aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/3rdparty/CMakeLists.txt2
-rw-r--r--src/libs/3rdparty/cplusplus/CMakeLists.txt46
-rw-r--r--src/libs/3rdparty/syntax-highlighting/.gitignore3
-rw-r--r--src/libs/3rdparty/syntax-highlighting/CMakeLists.txt173
-rw-r--r--src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde140
-rw-r--r--src/libs/3rdparty/syntax-highlighting/README.md17
-rw-r--r--src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h6
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml27
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml86
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml2
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml73
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml9
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml52
-rw-r--r--src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml9
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp4
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp88
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt1
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp77
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp83
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h12
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp54
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp45
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h9
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp40
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/repository.h8
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp8
-rw-r--r--src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp8
-rw-r--r--src/libs/3rdparty/variant/variant.hpp9
-rw-r--r--src/libs/CMakeLists.txt21
-rw-r--r--src/libs/aggregation/CMakeLists.txt6
-rw-r--r--src/libs/aggregation/examples/text/main.cpp2
-rw-r--r--src/libs/clangsupport/CMakeLists.txt137
-rw-r--r--src/libs/clangsupport/clangsupport-lib.pri8
-rw-r--r--src/libs/clangsupport/commandlinebuilder.h24
-rw-r--r--src/libs/clangsupport/connectionclient.cpp2
-rw-r--r--src/libs/clangsupport/connectionserver.h8
-rw-r--r--src/libs/clangsupport/environment.h (renamed from src/libs/clangsupport/ipcserverinterface.cpp)18
-rw-r--r--src/libs/clangsupport/executeinloop.h33
-rw-r--r--src/libs/clangsupport/generatedfiles.cpp28
-rw-r--r--src/libs/clangsupport/modifiedtimechecker.h215
-rw-r--r--src/libs/clangsupport/modifiedtimecheckerinterface.h (renamed from src/libs/clangsupport/projectpartpchproviderinterface.h)23
-rw-r--r--src/libs/clangsupport/pchmanagerclientproxy.h3
-rw-r--r--src/libs/clangsupport/pchpaths.h52
-rw-r--r--src/libs/clangsupport/precompiledheadersupdatedmessage.h31
-rw-r--r--src/libs/clangsupport/projectpartartefact.cpp2
-rw-r--r--src/libs/clangsupport/projectpartartefact.h4
-rw-r--r--src/libs/clangsupport/projectpartcontainer.h7
-rw-r--r--src/libs/clangsupport/projectpartid.h2
-rw-r--r--src/libs/clangsupport/projectpartpch.cpp3
-rw-r--r--src/libs/clangsupport/projectpartpch.h3
-rw-r--r--src/libs/clangsupport/projectpartsstorage.h35
-rw-r--r--src/libs/clangsupport/projectpartsstorageinterface.h1
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h2
-rw-r--r--src/libs/clangsupport/sourceentry.h152
-rw-r--r--src/libs/cplusplus/CMakeLists.txt44
-rw-r--r--src/libs/cplusplus/CppDocument.cpp17
-rw-r--r--src/libs/cplusplus/CppDocument.h28
-rw-r--r--src/libs/cplusplus/DependencyTable.cpp8
-rw-r--r--src/libs/cplusplus/DependencyTable.h6
-rw-r--r--src/libs/cplusplus/FindUsages.cpp2
-rw-r--r--src/libs/cplusplus/FindUsages.h4
-rw-r--r--src/libs/cplusplus/MatchingText.cpp29
-rw-r--r--src/libs/extensionsystem/CMakeLists.txt16
-rw-r--r--src/libs/extensionsystem/iplugin.cpp6
-rw-r--r--src/libs/extensionsystem/iplugin.h2
-rw-r--r--src/libs/extensionsystem/optionsparser.cpp12
-rw-r--r--src/libs/extensionsystem/pluginerroroverview.cpp2
-rw-r--r--src/libs/extensionsystem/pluginmanager.cpp71
-rw-r--r--src/libs/extensionsystem/pluginmanager.h12
-rw-r--r--src/libs/extensionsystem/pluginmanager_p.h28
-rw-r--r--src/libs/extensionsystem/pluginspec.cpp6
-rw-r--r--src/libs/extensionsystem/pluginspec_p.h4
-rw-r--r--src/libs/extensionsystem/pluginview.cpp24
-rw-r--r--src/libs/glsl/CMakeLists.txt19
-rw-r--r--src/libs/glsl/glslparser.h2
-rw-r--r--src/libs/languageserverprotocol/CMakeLists.txt23
-rw-r--r--src/libs/languageserverprotocol/basemessage.cpp16
-rw-r--r--src/libs/languageserverprotocol/basemessage.h3
-rw-r--r--src/libs/languageserverprotocol/clientcapabilities.cpp53
-rw-r--r--src/libs/languageserverprotocol/clientcapabilities.h31
-rw-r--r--src/libs/languageserverprotocol/icontent.h5
-rw-r--r--src/libs/languageserverprotocol/initializemessages.cpp31
-rw-r--r--src/libs/languageserverprotocol/jsonkeys.h1
-rw-r--r--src/libs/languageserverprotocol/jsonobject.cpp4
-rw-r--r--src/libs/languageserverprotocol/jsonrpcmessages.h1
-rw-r--r--src/libs/languageserverprotocol/languagefeatures.cpp55
-rw-r--r--src/libs/languageserverprotocol/languagefeatures.h45
-rw-r--r--src/libs/languageserverprotocol/lsptypes.cpp30
-rw-r--r--src/libs/languageserverprotocol/lsptypes.h34
-rw-r--r--src/libs/languageserverprotocol/lsputils.h2
-rw-r--r--src/libs/languageserverprotocol/servercapabilities.cpp2
-rw-r--r--src/libs/languageserverprotocol/servercapabilities.h4
-rw-r--r--src/libs/languageserverprotocol/textsynchronization.h2
-rw-r--r--src/libs/languageserverprotocol/workspace.cpp10
-rw-r--r--src/libs/languageserverprotocol/workspace.h11
-rw-r--r--src/libs/languageutils/CMakeLists.txt7
-rw-r--r--src/libs/libs.pro4
-rw-r--r--src/libs/modelinglib/CMakeLists.txt196
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp7
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h6
-rw-r--r--src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp16
-rw-r--r--src/libs/qmldebug/CMakeLists.txt18
-rw-r--r--src/libs/qmldebug/baseenginedebugclient.cpp2
-rw-r--r--src/libs/qmldebug/qmldebugcommandlinearguments.h14
-rw-r--r--src/libs/qmldebug/qmldebugconnection.cpp54
-rw-r--r--src/libs/qmldebug/qmldebugconnection.h9
-rw-r--r--src/libs/qmleditorwidgets/CMakeLists.txt22
-rw-r--r--src/libs/qmleditorwidgets/colorbox.cpp6
-rw-r--r--src/libs/qmleditorwidgets/contextpanetextwidget.cpp5
-rw-r--r--src/libs/qmleditorwidgets/customcolordialog.cpp12
-rw-r--r--src/libs/qmljs/CMakeLists.txt53
-rw-r--r--src/libs/qmljs/parser/qmljslexer.cpp67
-rw-r--r--src/libs/qmljs/parser/qmljslexer_p.h3
-rw-r--r--src/libs/qmljs/persistenttrie.cpp1
-rw-r--r--src/libs/qmljs/persistenttrie.h1
-rw-r--r--src/libs/qmljs/qmljs-lib.pri2
-rw-r--r--src/libs/qmljs/qmljs.qbs1
-rw-r--r--src/libs/qmljs/qmljsbundle.cpp5
-rw-r--r--src/libs/qmljs/qmljsbundle.h1
-rw-r--r--src/libs/qmljs/qmljscheck.cpp59
-rw-r--r--src/libs/qmljs/qmljsdialect.cpp7
-rw-r--r--src/libs/qmljs/qmljsdialect.h14
-rw-r--r--src/libs/qmljs/qmljsdocument.cpp8
-rw-r--r--src/libs/qmljs/qmljsdocument.h1
-rw-r--r--src/libs/qmljs/qmljsimportdependencies.cpp6
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp10
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h1
-rw-r--r--src/libs/qmljs/qmljslink.cpp5
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.cpp14
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.h6
-rw-r--r--src/libs/qmljs/qmljsreformatter.cpp76
-rw-r--r--src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp3
-rw-r--r--src/libs/qtcreatorcdbext/CMakeLists.txt46
-rw-r--r--src/libs/qtcreatorcdbext/common.h13
-rw-r--r--src/libs/qtcreatorcdbext/qtcreatorcdbext.pro2
-rw-r--r--src/libs/sqlite/CMakeLists.txt27
-rw-r--r--src/libs/sqlite/README.md13
-rw-r--r--src/libs/sqlite/sqlite-lib.pri6
-rw-r--r--src/libs/sqlite/sqlite-source.pri3
-rw-r--r--src/libs/sqlite/sqlitecolumn.cpp31
-rw-r--r--src/libs/sqlite/sqlitedatabase.h24
-rw-r--r--src/libs/sqlite/sqlitedatabasebackend.cpp21
-rw-r--r--src/libs/sqlite/sqlitedatabasebackend.h2
-rw-r--r--src/libs/sqlite/sqlitedatabaseinterface.h (renamed from src/libs/sqlite/sqlstatementbuilderexception.cpp)15
-rw-r--r--src/libs/ssh/CMakeLists.txt22
-rw-r--r--src/libs/ssh/sftpfilesystemmodel.cpp5
-rw-r--r--src/libs/ssh/sftpsession.cpp9
-rw-r--r--src/libs/ssh/sftptransfer.cpp2
-rw-r--r--src/libs/ssh/ssh.qrc2
-rw-r--r--src/libs/ssh/sshconnection.cpp8
-rw-r--r--src/libs/ssh/sshconnection.h2
-rw-r--r--src/libs/ssh/sshremoteprocess.cpp10
-rw-r--r--src/libs/ssh/sshremoteprocess.h6
-rw-r--r--src/libs/ssh/sshremoteprocessrunner.cpp11
-rw-r--r--src/libs/ssh/sshremoteprocessrunner.h8
-rw-r--r--src/libs/ssh/sshsettings.cpp48
-rw-r--r--src/libs/ssh/sshsettings.h18
-rw-r--r--src/libs/tracing/CMakeLists.txt35
-rw-r--r--src/libs/tracing/timelineabstractrenderer.h1
-rw-r--r--src/libs/tracing/timelinemodel_p.h4
-rw-r--r--src/libs/tracing/timelinerenderer.h1
-rw-r--r--src/libs/tracing/tracestashfile.h2
-rw-r--r--src/libs/utils/CMakeLists.txt204
-rw-r--r--src/libs/utils/algorithm.h409
-rw-r--r--src/libs/utils/basetreeview.cpp9
-rw-r--r--src/libs/utils/buildablehelperlibrary.cpp76
-rw-r--r--src/libs/utils/buildablehelperlibrary.h7
-rw-r--r--src/libs/utils/checkablemessagebox.cpp60
-rw-r--r--src/libs/utils/checkablemessagebox.h7
-rw-r--r--src/libs/utils/completingtextedit.cpp2
-rw-r--r--src/libs/utils/consoleprocess.h4
-rw-r--r--src/libs/utils/consoleprocess_unix.cpp12
-rw-r--r--src/libs/utils/consoleprocess_win.cpp4
-rw-r--r--src/libs/utils/cpplanguage_details.h3
-rw-r--r--src/libs/utils/delegates.cpp2
-rw-r--r--src/libs/utils/detailsbutton.cpp2
-rw-r--r--src/libs/utils/elidinglabel.cpp2
-rw-r--r--src/libs/utils/environment.cpp49
-rw-r--r--src/libs/utils/environment.h13
-rw-r--r--src/libs/utils/filecrumblabel.cpp10
-rw-r--r--src/libs/utils/filecrumblabel.h4
-rw-r--r--src/libs/utils/fileinprojectfinder.cpp193
-rw-r--r--src/libs/utils/fileinprojectfinder.h47
-rw-r--r--src/libs/utils/filesearch.cpp2
-rw-r--r--src/libs/utils/fileutils.cpp424
-rw-r--r--src/libs/utils/fileutils.h137
-rw-r--r--src/libs/utils/genericconstants.h (renamed from src/libs/sqlite/sqlitetable.cpp)11
-rw-r--r--src/libs/utils/highlightingitemdelegate.cpp3
-rw-r--r--src/libs/utils/images/dir.png (renamed from src/libs/ssh/images/dir.png)bin862 -> 862 bytes
-rw-r--r--src/libs/utils/images/pinned.pngbin0 -> 168 bytes
-rw-r--r--src/libs/utils/images/pinned@2x.pngbin0 -> 267 bytes
-rw-r--r--src/libs/utils/images/settings.pngbin0 -> 177 bytes
-rw-r--r--src/libs/utils/images/settings@2x.pngbin0 -> 316 bytes
-rw-r--r--src/libs/utils/images/sort_alphabetically.pngbin0 -> 139 bytes
-rw-r--r--src/libs/utils/images/sort_alphabetically@2x.pngbin0 -> 205 bytes
-rw-r--r--src/libs/utils/images/toggleprogressdetails.pngbin0 -> 167 bytes
-rw-r--r--src/libs/utils/images/toggleprogressdetails@2x.pngbin0 -> 216 bytes
-rw-r--r--src/libs/utils/images/unknownfile.png (renamed from src/libs/ssh/images/unknownfile.png)bin345 -> 345 bytes
-rw-r--r--src/libs/utils/listmodel.h183
-rw-r--r--src/libs/utils/macroexpander.cpp30
-rw-r--r--src/libs/utils/macroexpander.h3
-rw-r--r--src/libs/utils/mimetypes/mimeprovider.cpp4
-rw-r--r--src/libs/utils/newclasswidget.cpp2
-rw-r--r--src/libs/utils/outputformatter.cpp3
-rw-r--r--src/libs/utils/outputformatter.h3
-rw-r--r--src/libs/utils/pathchooser.cpp20
-rw-r--r--src/libs/utils/pathchooser.h14
-rw-r--r--src/libs/utils/persistentsettings.cpp6
-rw-r--r--src/libs/utils/persistentsettings.h8
-rw-r--r--src/libs/utils/projectintropage.cpp2
-rw-r--r--src/libs/utils/qrcparser.cpp (renamed from src/libs/qmljs/qmljsqrcparser.cpp)50
-rw-r--r--src/libs/utils/qrcparser.h (renamed from src/libs/qmljs/qmljsqrcparser.h)8
-rw-r--r--src/libs/utils/qtcprocess.cpp11
-rw-r--r--src/libs/utils/qtcprocess.h13
-rw-r--r--src/libs/utils/reloadpromptutils.cpp7
-rw-r--r--src/libs/utils/reloadpromptutils.h4
-rw-r--r--src/libs/utils/runextensions.h57
-rw-r--r--src/libs/utils/savedaction.cpp2
-rw-r--r--src/libs/utils/savefile.cpp2
-rw-r--r--src/libs/utils/settingsaccessor.cpp59
-rw-r--r--src/libs/utils/settingsaccessor.h46
-rw-r--r--src/libs/utils/settingsselector.cpp2
-rw-r--r--src/libs/utils/shellcommand.cpp16
-rw-r--r--src/libs/utils/shellcommand.h14
-rw-r--r--src/libs/utils/smallstringlayout.h7
-rw-r--r--src/libs/utils/stringutils.cpp2
-rw-r--r--src/libs/utils/stylehelper.cpp14
-rw-r--r--src/libs/utils/synchronousprocess.cpp3
-rw-r--r--src/libs/utils/textfieldcombobox.cpp2
-rw-r--r--src/libs/utils/touchbar/touchbar.pri1
-rw-r--r--src/libs/utils/touchbar/touchbar_mac.mm10
-rw-r--r--src/libs/utils/unixutils.cpp2
-rw-r--r--src/libs/utils/utils-lib.pri8
-rw-r--r--src/libs/utils/utils.qbs5
-rw-r--r--src/libs/utils/utils.qrc10
-rw-r--r--src/libs/utils/utilsicons.cpp19
-rw-r--r--src/libs/utils/utilsicons.h7
-rw-r--r--src/libs/utils/variant.h19
-rw-r--r--src/libs/utils/wizardpage.h36
240 files changed, 4631 insertions, 1520 deletions
diff --git a/src/libs/3rdparty/CMakeLists.txt b/src/libs/3rdparty/CMakeLists.txt
new file mode 100644
index 0000000000..7cf97ab87f
--- /dev/null
+++ b/src/libs/3rdparty/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(cplusplus)
+add_subdirectory(syntax-highlighting)
diff --git a/src/libs/3rdparty/cplusplus/CMakeLists.txt b/src/libs/3rdparty/cplusplus/CMakeLists.txt
new file mode 100644
index 0000000000..a33e96a197
--- /dev/null
+++ b/src/libs/3rdparty/cplusplus/CMakeLists.txt
@@ -0,0 +1,46 @@
+add_qtc_library(3rd_cplusplus OBJECT
+ PUBLIC_DEPENDS Qt5::Core Utils
+ DEFINES CPLUSPLUS_BUILD_LIB
+ INCLUDES "${CMAKE_SOURCE_DIR}/src/libs"
+ SOURCES
+ AST.cpp AST.h
+ ASTClone.cpp
+ ASTMatch0.cpp
+ ASTMatcher.cpp ASTMatcher.h
+ ASTPatternBuilder.h
+ ASTVisit.cpp
+ ASTVisitor.cpp ASTVisitor.h
+ ASTfwd.h
+ Bind.cpp Bind.h
+ CPlusPlus.h
+ CPlusPlusForwardDeclarations.h
+ Control.cpp Control.h
+ CoreTypes.cpp CoreTypes.h
+ DiagnosticClient.cpp DiagnosticClient.h
+ FullySpecifiedType.cpp FullySpecifiedType.h
+ Keywords.cpp
+ Lexer.cpp Lexer.h
+ LiteralTable.h
+ Literals.cpp Literals.h
+ Matcher.cpp Matcher.h
+ MemoryPool.cpp MemoryPool.h
+ Name.cpp Name.h
+ NameVisitor.cpp NameVisitor.h
+ Names.cpp Names.h
+ ObjectiveCAtKeywords.cpp
+ ObjectiveCTypeQualifiers.cpp ObjectiveCTypeQualifiers.h
+ Parser.cpp Parser.h
+ QtContextKeywords.cpp QtContextKeywords.h
+ SafeMatcher.cpp SafeMatcher.h
+ Scope.cpp Scope.h
+ Symbol.cpp Symbol.h
+ SymbolVisitor.h
+ Symbols.cpp Symbols.h
+ Templates.cpp Templates.h
+ Token.cpp Token.h
+ TranslationUnit.cpp TranslationUnit.h
+ Type.cpp Type.h
+ TypeVisitor.cpp TypeVisitor.h
+ cppassert.h
+ PROPERTIES POSITION_INDEPENDENT_CODE ON
+)
diff --git a/src/libs/3rdparty/syntax-highlighting/.gitignore b/src/libs/3rdparty/syntax-highlighting/.gitignore
index 02ba11c78a..52f10e28a5 100644
--- a/src/libs/3rdparty/syntax-highlighting/.gitignore
+++ b/src/libs/3rdparty/syntax-highlighting/.gitignore
@@ -7,3 +7,6 @@
CMakeLists.txt.user
callgrind.*
heaptrack.*
+/build*/
+*.unc-backup*
+
diff --git a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
index 49923fb26e..27cc408223 100644
--- a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt
@@ -1,134 +1,47 @@
-cmake_minimum_required(VERSION 3.0)
-
-set(KF5_VERSION "5.52.0")
-project(KSyntaxHighlighting VERSION ${KF5_VERSION})
-
-find_package(ECM 5.51.0 REQUIRED NO_MODULE)
-set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
-if(POLICY CMP0063)
- cmake_policy(SET CMP0063 NEW)
-endif()
-
-include(FeatureSummary)
-include(GenerateExportHeader)
-include(ECMSetupVersion)
-include(ECMGenerateHeaders)
-include(ECMGeneratePriFile)
-include(CMakePackageConfigHelpers)
-include(ECMPoQmTools)
-include(ECMQtDeclareLoggingCategory)
-include(KDEInstallDirs)
-include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
-include(KDECMakeSettings)
-include(ECMMarkNonGuiExecutable)
-include(ECMAddQch)
-
-
-ecm_setup_version(PROJECT
- VARIABLE_PREFIX SyntaxHighlighting
- VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h"
- PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake"
+add_qtc_library(KSyntaxHighlighting STATIC
+ PUBLIC_INCLUDES autogenerated/ autogenerated/src/lib src/lib
+ PUBLIC_DEFINES KSYNTAXHIGHLIGHTING_LIBRARY
+ DEPENDS Qt5::Network Qt5::Gui
+ SOURCES
+ autogenerated/src/lib/ksyntaxhighlighting_logging.cpp autogenerated/src/lib/ksyntaxhighlighting_logging.h
+ autogenerated/ksyntaxhighlighting_version.h
+
+ data/themes/theme-data.qrc
+
+ src/lib/abstracthighlighter.cpp src/lib/abstracthighlighter.h src/lib/abstracthighlighter_p.h
+ src/lib/context.cpp src/lib/context_p.h
+ src/lib/contextswitch.cpp src/lib/contextswitch_p.h
+ src/lib/definition.cpp src/lib/definition.h
+ src/lib/definitiondownloader.cpp src/lib/definitiondownloader.h
+ src/lib/definitionref_p.h
+ src/lib/definition_p.h
+ src/lib/foldingregion.cpp src/lib/foldingregion.h
+ src/lib/format.cpp src/lib/format.h src/lib/format_p.h
+ src/lib/htmlhighlighter.cpp src/lib/htmlhighlighter.h
+ src/lib/keywordlist.cpp src/lib/keywordlist_p.h
+ src/lib/ksyntaxhighlighting_export.h
+ src/lib/matchresult_p.h
+ src/lib/repository.cpp src/lib/repository.h src/lib/repository_p.h
+ src/lib/rule.cpp src/lib/rule_p.h
+ src/lib/state.cpp src/lib/state.h src/lib/state_p.h
+ src/lib/syntaxhighlighter.cpp src/lib/syntaxhighlighter.h
+ src/lib/textstyledata_p.h
+ src/lib/theme.cpp src/lib/theme.h
+ src/lib/themedata.cpp src/lib/themedata_p.h
+ src/lib/wildcardmatcher.cpp src/lib/wildcardmatcher_p.h
+ src/lib/xml_p.h
)
-#
-# Dependencies
-#
-set(REQUIRED_QT_VERSION 5.8.0)
-find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED COMPONENTS Core Network Test)
-option(KSYNTAXHIGHLIGHTING_USE_GUI "Build components depending on Qt5Gui" ON)
-if(KSYNTAXHIGHLIGHTING_USE_GUI)
- find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED COMPONENTS Gui)
-endif()
-find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE QUIET OPTIONAL_COMPONENTS Widgets XmlPatterns)
-set_package_properties(Qt5 PROPERTIES URL "http://qt-project.org/")
-set_package_properties(Qt5Widgets PROPERTIES PURPOSE "Example application.")
-set_package_properties(Qt5XmlPatterns PROPERTIES PURPOSE "Compile-time validation of syntax definition files.")
-
-find_package(Perl REQUIRED)
-set_package_properties(Perl PROPERTIES PURPOSE "Auto-generate PHP syntax definition files.")
-
-#
-# allow to install the "differently" licensed syntax xml files instead of putting them in a QRC and link them in
-#
-option(QRC_SYNTAX "Bundle the syntax definition files inside the library as resources" ON)
-add_feature_info(SYNTAX_RESOURCE ${QRC_SYNTAX} "Bundle the syntax definition files inside the library as resources")
-
-#
-# allow to turn of lookup for syntax files and themes via QStandardPaths
-#
-option(NO_STANDARD_PATHS "Skip lookup of syntax and theme definitions in QStandardPaths locations" OFF)
-add_feature_info(FEATURE_NO_STANDARD_PATHS ${NO_STANDARD_PATHS} "Skip lookup of syntax and theme definitions in QStandardPaths locations")
-
-#
-# API documentation
-#
-option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF)
-add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)")
-
-#
-# Translations
-#
-if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po")
- ecm_install_po_files_as_qm(po)
-endif()
-
-# tell the framework if it shall use the syntax files from the resource
-if (QRC_SYNTAX)
- add_definitions(-DHAS_SYNTAX_RESOURCE)
-endif()
-
-# skip standard paths?
-if (NO_STANDARD_PATHS)
- add_definitions(-DNO_STANDARD_PATHS)
-endif()
-
-#
-# Actually build the stuff
-#
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-add_subdirectory(data)
-add_subdirectory(src)
-if(TARGET Qt5::Gui)
- add_subdirectory(examples)
-endif()
-
-#
-# CMake package config file generation
-#
-set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5SyntaxHighlighting")
-
-if (BUILD_QCH)
- ecm_install_qch_export(
- TARGETS KF5SyntaxHighlighting_QCH
- FILE KF5SyntaxHighlightingQchTargets.cmake
- DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
- COMPONENT Devel
- )
- set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF5SyntaxHighlightingQchTargets.cmake\")")
-endif()
-
-configure_package_config_file(
- "${CMAKE_CURRENT_SOURCE_DIR}/KF5SyntaxHighlightingConfig.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake"
- INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+install(
+ DIRECTORY data/syntax
+ DESTINATION "${IDE_DATA_PATH}/generic-highlighter/"
)
-install(FILES
- "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake"
- "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake"
- DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
- COMPONENT Devel)
-
-if(TARGET KF5SyntaxHighlighting)
- install(EXPORT KF5SyntaxHighlightingTargets
- DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
- FILE KF5SyntaxHighlightingTargets.cmake
- NAMESPACE KF5::)
-endif()
-
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h"
- DESTINATION "${KDE_INSTALL_INCLUDEDIR_KF5}"
- COMPONENT Devel)
-install(FILES org_kde_ksyntaxhighlighting.categories DESTINATION ${KDE_INSTALL_CONFDIR})
-
-feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
+add_custom_target(copy_generic_highligher_to_builddir ALL VERBATIM)
+add_custom_command(TARGET copy_generic_highligher_to_builddir POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E copy_directory data/syntax
+ "${PROJECT_BINARY_DIR}/${IDE_DATA_PATH}/generic-highlighter/syntax"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ COMMENT Copy files into build directory
+ VERBATIM
+)
diff --git a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde
new file mode 100644
index 0000000000..4f88fcf84a
--- /dev/null
+++ b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt.kde
@@ -0,0 +1,140 @@
+cmake_minimum_required(VERSION 3.5)
+
+set(KF5_VERSION "5.59.0")
+project(KSyntaxHighlighting VERSION ${KF5_VERSION})
+
+find_package(ECM 5.59.0 REQUIRED NO_MODULE)
+set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
+if(POLICY CMP0063)
+ cmake_policy(SET CMP0063 NEW)
+endif()
+
+include(FeatureSummary)
+include(GenerateExportHeader)
+include(ECMSetupVersion)
+include(ECMGenerateHeaders)
+include(ECMGeneratePriFile)
+include(CMakePackageConfigHelpers)
+include(ECMPoQmTools)
+include(ECMQtDeclareLoggingCategory)
+include(KDEInstallDirs)
+include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE)
+include(KDECMakeSettings)
+include(ECMMarkNonGuiExecutable)
+include(ECMAddQch)
+include(ECMOptionalAddSubdirectory)
+
+
+ecm_setup_version(PROJECT
+ VARIABLE_PREFIX SyntaxHighlighting
+ VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h"
+ PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake"
+)
+
+#
+# Dependencies
+#
+set(REQUIRED_QT_VERSION 5.10.0)
+find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED COMPONENTS Core Network Test)
+option(KSYNTAXHIGHLIGHTING_USE_GUI "Build components depending on Qt5Gui" ON)
+if(KSYNTAXHIGHLIGHTING_USE_GUI)
+ find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED COMPONENTS Gui)
+endif()
+find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE QUIET OPTIONAL_COMPONENTS PrintSupport Widgets XmlPatterns)
+set_package_properties(Qt5 PROPERTIES URL "http://qt-project.org/")
+set_package_properties(Qt5Widgets PROPERTIES PURPOSE "Example application.")
+set_package_properties(Qt5PrintSupport PROPERTIES PURPOSE "Example application.")
+set_package_properties(Qt5XmlPatterns PROPERTIES PURPOSE "Compile-time validation of syntax definition files.")
+
+find_package(Perl REQUIRED)
+set_package_properties(Perl PROPERTIES PURPOSE "Auto-generate PHP syntax definition files.")
+
+#
+# allow to install the "differently" licensed syntax xml files instead of putting them in a QRC and link them in
+#
+option(QRC_SYNTAX "Bundle the syntax definition files inside the library as resources" ON)
+add_feature_info(SYNTAX_RESOURCE ${QRC_SYNTAX} "Bundle the syntax definition files inside the library as resources")
+
+#
+# allow to turn of lookup for syntax files and themes via QStandardPaths
+#
+option(NO_STANDARD_PATHS "Skip lookup of syntax and theme definitions in QStandardPaths locations" OFF)
+add_feature_info(FEATURE_NO_STANDARD_PATHS ${NO_STANDARD_PATHS} "Skip lookup of syntax and theme definitions in QStandardPaths locations")
+
+#
+# API documentation
+#
+option(BUILD_QCH "Build API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)" OFF)
+add_feature_info(QCH ${BUILD_QCH} "API documentation in QCH format (for e.g. Qt Assistant, Qt Creator & KDevelop)")
+
+#
+# Translations
+#
+if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po")
+ ecm_install_po_files_as_qm(po)
+endif()
+
+# tell the framework if it shall use the syntax files from the resource
+if (QRC_SYNTAX)
+ add_definitions(-DHAS_SYNTAX_RESOURCE)
+endif()
+
+# skip standard paths?
+if (NO_STANDARD_PATHS)
+ add_definitions(-DNO_STANDARD_PATHS)
+endif()
+add_definitions(-DQT_NO_FOREACH)
+
+#
+# Actually build the stuff
+#
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_subdirectory(data)
+add_subdirectory(src)
+if(TARGET Qt5::Gui)
+ add_subdirectory(examples)
+ if (BUILD_TESTING)
+ add_subdirectory(autotests)
+ endif()
+endif()
+
+#
+# CMake package config file generation
+#
+set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5SyntaxHighlighting")
+
+if (BUILD_QCH)
+ ecm_install_qch_export(
+ TARGETS KF5SyntaxHighlighting_QCH
+ FILE KF5SyntaxHighlightingQchTargets.cmake
+ DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+ COMPONENT Devel
+ )
+ set(PACKAGE_INCLUDE_QCHTARGETS "include(\"\${CMAKE_CURRENT_LIST_DIR}/KF5SyntaxHighlightingQchTargets.cmake\")")
+endif()
+
+configure_package_config_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/KF5SyntaxHighlightingConfig.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake"
+ INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+)
+
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/KF5SyntaxHighlightingConfigVersion.cmake"
+ DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+ COMPONENT Devel)
+
+if(TARGET KF5SyntaxHighlighting)
+ install(EXPORT KF5SyntaxHighlightingTargets
+ DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+ FILE KF5SyntaxHighlightingTargets.cmake
+ NAMESPACE KF5::)
+endif()
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ksyntaxhighlighting_version.h"
+ DESTINATION "${KDE_INSTALL_INCLUDEDIR_KF5}"
+ COMPONENT Devel)
+install(FILES org_kde_ksyntaxhighlighting.categories DESTINATION ${KDE_INSTALL_CONFDIR})
+
+feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
diff --git a/src/libs/3rdparty/syntax-highlighting/README.md b/src/libs/3rdparty/syntax-highlighting/README.md
index 1eedc0af7f..c1b82c63d1 100644
--- a/src/libs/3rdparty/syntax-highlighting/README.md
+++ b/src/libs/3rdparty/syntax-highlighting/README.md
@@ -30,3 +30,20 @@ out of scope:
* management of text buffers or documents
If you need any of this, check out [KTextEditor](https://api.kde.org/frameworks/ktexteditor/html/).
+
+## Adding unit tests for a syntax definition
+
+* add an input file into the autotests/input/ folder, lets call it test.<language-extension>
+
+* if the file extension is not sufficient to trigger the right syntax definition, you can add an
+ second file testname.<language-extension>.syntax that contains the syntax definition name
+ to enforce the use of the right extension
+
+* do "make && make test"
+
+* inspect the outputs found in your binary directory autotests/folding.out, autotests/html.output and autotests/output
+
+* if ok, run in the binary folder "./autotests/update-reference-data.sh" to copy the results to the right location
+
+* add the result references after the copying to the git
+
diff --git a/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h
index bd31a4d407..70795908d6 100644
--- a/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h
+++ b/src/libs/3rdparty/syntax-highlighting/autogenerated/ksyntaxhighlighting_version.h
@@ -3,10 +3,10 @@
#ifndef SyntaxHighlighting_VERSION_H
#define SyntaxHighlighting_VERSION_H
-#define SyntaxHighlighting_VERSION_STRING "5.52.0"
+#define SyntaxHighlighting_VERSION_STRING "5.59.0"
#define SyntaxHighlighting_VERSION_MAJOR 5
-#define SyntaxHighlighting_VERSION_MINOR 52
+#define SyntaxHighlighting_VERSION_MINOR 59
#define SyntaxHighlighting_VERSION_PATCH 0
-#define SyntaxHighlighting_VERSION ((5<<16)|(52<<8)|(0))
+#define SyntaxHighlighting_VERSION ((5<<16)|(59<<8)|(0))
#endif
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml
index 2a9088b46c..6d170e4eaa 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/cmake.xml
@@ -31,7 +31,7 @@
<language
name="CMake"
- version="11"
+ version="12"
kateversion="2.4"
section="Other"
extensions="CMakeLists.txt;*.cmake;*.cmake.in"
@@ -317,6 +317,7 @@
<item>PATTERN</item>
<item>PERMISSIONS</item>
<item>READ</item>
+ <item>READ_SYMLINK</item>
<item>REGEX</item>
<item>RELATIVE</item>
<item>RELATIVE_PATH</item>
@@ -335,6 +336,7 @@
<item>SHA3_512</item>
<item>SHA512</item>
<item>SHOW_PROGRESS</item>
+ <item>SIZE</item>
<item>STATUS</item>
<item>STRINGS</item>
<item>TIMEOUT</item>
@@ -484,8 +486,10 @@
<item>CACHE</item>
<item>DIRECTORY</item>
<item>EXT</item>
+ <item>LAST_EXT</item>
<item>NAME</item>
<item>NAME_WE</item>
+ <item>NAME_WLE</item>
<item>PATH</item>
<item>PROGRAM</item>
<item>PROGRAM_ARGS</item>
@@ -1054,6 +1058,7 @@
<item>COPY_FILE</item>
<item>COPY_FILE_ERROR</item>
<item>LINK_LIBRARIES</item>
+ <item>LINK_OPTIONS</item>
<item>OUTPUT_VARIABLE</item>
<item>RESULT_VAR</item>
<item>SOURCES</item>
@@ -1065,6 +1070,7 @@
<item>COMPILE_OUTPUT_VARIABLE</item>
<item>COMPILE_RESULT_VAR</item>
<item>LINK_LIBRARIES</item>
+ <item>LINK_OPTIONS</item>
<item>OUTPUT_VARIABLE</item>
<item>RUN_OUTPUT_VARIABLE</item>
<item>RUN_RESULT_VAR</item>
@@ -1209,6 +1215,7 @@
<item>CMAKE_ARCHIVE_OUTPUT_DIRECTORY</item>
<item>CMAKE_ARGC</item>
<item>CMAKE_ARGV0</item>
+ <item>CMAKE_AUTOGEN_ORIGIN_DEPENDS</item>
<item>CMAKE_AUTOGEN_PARALLEL</item>
<item>CMAKE_AUTOGEN_VERBOSE</item>
<item>CMAKE_AUTOMOC</item>
@@ -1223,6 +1230,7 @@
<item>CMAKE_BACKWARDS_COMPATIBILITY</item>
<item>CMAKE_BINARY_DIR</item>
<item>CMAKE_BUILD_RPATH</item>
+ <item>CMAKE_BUILD_RPATH_USE_ORIGIN</item>
<item>CMAKE_BUILD_TOOL</item>
<item>CMAKE_BUILD_TYPE</item>
<item>CMAKE_BUILD_WITH_INSTALL_NAME_DIR</item>
@@ -1297,6 +1305,7 @@
<item>CMAKE_FIND_PACKAGE_NAME</item>
<item>CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY</item>
<item>CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY</item>
+ <item>CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS</item>
<item>CMAKE_FIND_PACKAGE_SORT_DIRECTION</item>
<item>CMAKE_FIND_PACKAGE_SORT_ORDER</item>
<item>CMAKE_FIND_PACKAGE_WARN_NO_MODULE</item>
@@ -1316,6 +1325,10 @@
<item>CMAKE_GENERATOR_INSTANCE</item>
<item>CMAKE_GENERATOR_PLATFORM</item>
<item>CMAKE_GENERATOR_TOOLSET</item>
+ <item>CMAKE_GLOBAL_AUTOGEN_TARGET</item>
+ <item>CMAKE_GLOBAL_AUTOGEN_TARGET_NAME</item>
+ <item>CMAKE_GLOBAL_AUTORCC_TARGET</item>
+ <item>CMAKE_GLOBAL_AUTORCC_TARGET_NAME</item>
<item>CMAKE_GNUtoMS</item>
<item>CMAKE_HAS_ANSI_STRING_STREAM</item>
<item>CMAKE_HOME_DIRECTORY</item>
@@ -1412,6 +1425,7 @@
<item>CMAKE_MAJOR_VERSION</item>
<item>CMAKE_MAKE_PROGRAM</item>
<item>CMAKE_MATCH_COUNT</item>
+ <item>CMAKE_MAXIMUM_RECURSION_DEPTH</item>
<item>CMAKE_MFC_FLAG</item>
<item>CMAKE_MINIMUM_REQUIRED_VERSION</item>
<item>CMAKE_MINOR_VERSION</item>
@@ -1884,6 +1898,7 @@
<item>CTEST_SCP_COMMAND</item>
<item>CTEST_SITE</item>
<item>CTEST_SOURCE_DIRECTORY</item>
+ <item>CTEST_SUBMIT_URL</item>
<item>CTEST_SVN_COMMAND</item>
<item>CTEST_SVN_OPTIONS</item>
<item>CTEST_SVN_UPDATE_OPTIONS</item>
@@ -1964,6 +1979,8 @@
<item>PROJECT_VERSION_PATCH</item>
<item>PROJECT_VERSION_TWEAK</item>
<item>QTIFWDIR</item>
+ <item>SWIG_OUTFILE_DIR</item>
+ <item>SWIG_SOURCE_FILE_EXTENSIONS</item>
<item>THREADS_PREFER_PTHREAD_FLAG</item>
<item>UNIX</item>
<item>WIN32</item>
@@ -1982,6 +1999,7 @@
<item>AUTORCC_SOURCE_GROUP</item>
<item>CMAKE_CXX_KNOWN_FEATURES</item>
<item>CMAKE_C_KNOWN_FEATURES</item>
+ <item>CMAKE_ROLE</item>
<item>DEBUG_CONFIGURATIONS</item>
<item>DISABLED_FEATURES</item>
<item>ECLIPSE_EXTRA_NATURES</item>
@@ -2067,17 +2085,24 @@
<item>ARCHIVE_OUTPUT_DIRECTORY</item>
<item>ARCHIVE_OUTPUT_NAME</item>
<item>AUTOGEN_BUILD_DIR</item>
+ <item>AUTOGEN_ORIGIN_DEPENDS</item>
<item>AUTOGEN_TARGET_DEPENDS</item>
<item>AUTOMOC</item>
+ <item>AUTOMOC_COMPILER_PREDEFINES</item>
<item>AUTOMOC_DEPEND_FILTERS</item>
+ <item>AUTOMOC_EXECUTABLE</item>
+ <item>AUTOMOC_MACRO_NAMES</item>
<item>AUTOMOC_MOC_OPTIONS</item>
<item>AUTORCC</item>
+ <item>AUTORCC_EXECUTABLE</item>
<item>AUTORCC_OPTIONS</item>
<item>AUTOUIC</item>
+ <item>AUTOUIC_EXECUTABLE</item>
<item>AUTOUIC_OPTIONS</item>
<item>AUTOUIC_SEARCH_PATHS</item>
<item>BINARY_DIR</item>
<item>BUILD_RPATH</item>
+ <item>BUILD_RPATH_USE_ORIGIN</item>
<item>BUILD_WITH_INSTALL_NAME_DIR</item>
<item>BUILD_WITH_INSTALL_RPATH</item>
<item>BUNDLE</item>
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml
index 99b1d79c02..a6abda9204 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/doxygen.xml
@@ -4,7 +4,7 @@
<!ENTITY wordsep "([][,?;()]|\.$|\.?\s)"> <!-- things that end a TagWord -->
]>
<language name="Doxygen"
- version="5"
+ version="6"
kateversion="5.0"
section="Markup"
extensions="*.dox;*.doxygen"
@@ -463,7 +463,7 @@
<itemData name="Tags" defStyleNum="dsAnnotation" bold="1" />
<itemData name="Custom Tags" defStyleNum="dsAnnotation" />
<itemData name="Word" defStyleNum="dsCommentVar" bold="1" italic="0" />
- <itemData name="HTML Tag" defStyleNum="dsKeyword" color="#000000" bold="1" italic="0" />
+ <itemData name="HTML Tag" defStyleNum="dsKeyword" bold="1" italic="0" />
<itemData name="Entities" defStyleNum="dsOthers" color="#4086C0" bold="1" italic="1" />
<itemData name="Description" defStyleNum="dsDocumentation" />
<itemData name="Comment" defStyleNum="dsComment" />
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml
index 4f9eb962d7..107e1067da 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/html.xml
@@ -5,7 +5,7 @@
<!ENTITY attributeName "[A-Za-z_:*#\(\[][\)\]\w.:_-]*">
<!ENTITY entref "&amp;(#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
]>
-<language name="HTML" version="5" kateversion="3.4" section="Markup" extensions="*.htm;*.html;*.shtml;*.shtm" mimetype="text/html" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL" priority="10">
+<language name="HTML" version="7" kateversion="3.4" section="Markup" extensions="*.htm;*.html;*.shtml;*.shtm" mimetype="text/html" author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL" priority="10">
<highlighting>
<contexts>
@@ -163,16 +163,23 @@
</context>
<context name="JS" attribute="Other Text" lineEndContext="#stay">
- <Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" endRegion="script" />
+ <RegExpr attribute="Attribute" context="Script-Type" String="(\s+|^)type(?=\=|\s|$)" insensitive="true"/>
<DetectChar attribute="Element" context="JS content" char="&gt;" />
+ <IncludeRules context="DefaultJS" />
+ </context>
+ <context name="DefaultJS" attribute="Other Text" lineEndContext="#stay">
+ <Detect2Chars attribute="Element" context="#pop" char="/" char1="&gt;" endRegion="script" />
<IncludeRules context="FindAttributes" />
<RegExpr attribute="Error" context="#stay" String="\S" />
</context>
<context name="JS content" attribute="Other Text" lineEndContext="#stay">
+ <IncludeRules context="Default JS content"/>
+ <IncludeRules context="Normal##JavaScript" includeAttrib="true"/>
+ </context>
+ <context name="Default JS content" attribute="Other Text" lineEndContext="#stay">
<RegExpr attribute="Element" context="El Close 2" String="&lt;/script\b" insensitive="true" endRegion="script" />
<RegExpr attribute="Comment" context="JS comment close" String="//(?=.*&lt;/script\b)" insensitive="true" />
- <IncludeRules context="Normal##JavaScript" includeAttrib="true"/>
</context>
<context name="JS comment close" attribute="Comment" lineEndContext="#pop">
@@ -202,6 +209,79 @@
<IncludeRules context="FindEntityRefs" />
</context>
+ <!-- Read content from the "type" attribute to change the language to
+ highlight in the <script> tag. The default language is JavaScript. -->
+
+ <context name="Script-Type" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop">
+ <DetectSpaces />
+ <DetectChar attribute="Attribute" context="#pop!Script-Type Value" char="=" />
+ </context>
+ <context name="Script-Type Value" attribute="Other Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop!Value">
+ <DetectSpaces />
+ <!-- TypeScript -->
+ <StringDetect attribute="Value" context="#pop#pop!TypeScript" String="&quot;text/typescript&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!TypeScript" String="&apos;text/typescript&apos;"/>
+ <!-- JSX (JavaScript React) -->
+ <StringDetect attribute="Value" context="#pop#pop!JSX" String="&quot;text/jsx&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!JSX" String="&apos;text/jsx&apos;"/>
+ <StringDetect attribute="Value" context="#pop#pop!JSX" String="&quot;text/babel&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!JSX" String="&apos;text/babel&apos;"/>
+ <!-- MustacheJS / HandlebarsJS / RactiveJS -->
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&quot;x-tmpl-mustache&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&apos;x-tmpl-mustache&apos;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&quot;text/mustache&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&apos;text/mustache&apos;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&quot;text/x-mustache-template&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&apos;text/x-mustache-template&apos;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&quot;text/x-handlebars-template&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&apos;text/x-handlebars-template&apos;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&quot;text/ractive&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!MustacheJS" String="&apos;text/ractive&apos;"/>
+ <!-- HTML templates -->
+ <StringDetect attribute="Value" context="#pop#pop!Script HTML template" String="&quot;text/html&quot;"/>
+ <StringDetect attribute="Value" context="#pop#pop!Script HTML template" String="&apos;text/html&apos;"/>
+ </context>
+
+ <context name="JSX" attribute="Other Text" lineEndContext="#stay">
+ <DetectChar attribute="Element" context="JSX content" char="&gt;" />
+ <IncludeRules context="DefaultJS" />
+ </context>
+ <context name="JSX content" attribute="Other Text" lineEndContext="#stay">
+ <IncludeRules context="Default JS content"/>
+ <IncludeRules context="Normal##JavaScript React" includeAttrib="true"/>
+ </context>
+
+ <context name="TypeScript" attribute="Other Text" lineEndContext="#stay">
+ <DetectChar attribute="Element" context="TypeScript content" char="&gt;" />
+ <IncludeRules context="DefaultJS" />
+ </context>
+ <context name="TypeScript content" attribute="Other Text" lineEndContext="#stay">
+ <IncludeRules context="Default JS content"/>
+ <IncludeRules context="Normal##TypeScript" includeAttrib="true"/>
+ </context>
+
+ <context name="MustacheJS" attribute="Other Text" lineEndContext="#stay">
+ <DetectChar attribute="Element" context="MustacheJS content" char="&gt;" />
+ <IncludeRules context="DefaultJS" />
+ </context>
+ <context name="MustacheJS content" attribute="Other Text" lineEndContext="#stay">
+ <RegExpr attribute="Element" context="El Close 2" String="&lt;/script\b" insensitive="true" endRegion="script" />
+ <StringDetect attribute="Error" context="#stay" String="&lt;script&gt;" insensitive="true" />
+ <RegExpr attribute="Error" context="#stay" String="&lt;script\b" insensitive="true" />
+ <IncludeRules context="Base##Mustache/Handlebars (HTML)" includeAttrib="true"/>
+ </context>
+
+ <context name="Script HTML template" attribute="Other Text" lineEndContext="#stay">
+ <DetectChar attribute="Element" context="Script HTML template content" char="&gt;" />
+ <IncludeRules context="DefaultJS" />
+ </context>
+ <context name="Script HTML template content" attribute="Other Text" lineEndContext="#stay">
+ <RegExpr attribute="Element" context="El Close 2" String="&lt;/script\b" insensitive="true" endRegion="script" />
+ <StringDetect attribute="Error" context="#stay" String="&lt;script&gt;" insensitive="true" />
+ <RegExpr attribute="Error" context="#stay" String="&lt;script\b" insensitive="true" />
+ <IncludeRules context="FindHTML" />
+ </context>
+
</contexts>
<itemDatas>
<itemData name="Normal Text" defStyleNum="dsNormal" />
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml
index 465422f0b0..ce300fff47 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/ini.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
-<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc;*.conf" mimetype="" version="4" kateversion="2.4" author="Jan Janssen (medhefgo@web.de)" license="LGPL">
+<language name="INI Files" section="Configuration" extensions="*.ini;*.pls;*.kcfgc" mimetype="" version="5" kateversion="2.4" author="Jan Janssen (medhefgo@web.de)" license="LGPL">
<highlighting>
<list name="keywords">
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml
index 39ffaf77af..f88848729f 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/markdown.xml
@@ -35,7 +35,7 @@
<!ENTITY strikeoutregex "[~]{2}[^~].*[^~][~]{2}">
<!-- pandoc style -->
]>
-<language name="Markdown" version="3" kateversion="3.8" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
+<language name="Markdown" version="6" kateversion="5.0" section="Markup" extensions="*.md;*.mmd;*.markdown" priority="15" author="Darrin Yeager, Claes Holmerson" license="GPL,BSD">
<highlighting>
<contexts>
<context attribute="Normal Text" lineEndContext="#stay" name="Normal Text">
@@ -74,13 +74,57 @@
<context attribute="comment" lineEndContext="#stay" name="comment">
<RegExpr String="--&gt;" attribute="comment" context="#pop" endRegion="comment"/>
</context>
+ <context attribute="code" lineEndContext="#stay" name="bash-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##Bash" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="cmake-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##CMake" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="cpp-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##C++" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="css-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##CSS" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="email-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##Email" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="haskell-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##Haskell" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="html-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##HTML" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="json-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##JSON" includeAttrib="true"/>
+ </context>
<context attribute="code" lineEndContext="#stay" name="php-code">
<WordDetect attribute="code" context="#pop" String="```"/>
- <IncludeRules context="phpsource##PHP/PHP"/>
+ <IncludeRules context="phpsource##PHP/PHP" includeAttrib="true"/>
</context>
<context attribute="code" lineEndContext="#stay" name="python-code">
<WordDetect attribute="code" context="#pop" String="```"/>
- <IncludeRules context="##Python"/>
+ <IncludeRules context="##Python" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="qml-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##QML" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="rust-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##Rust" includeAttrib="true"/>
+ </context>
+ <context attribute="code" lineEndContext="#stay" name="xml-code">
+ <WordDetect attribute="code" context="#pop" String="```"/>
+ <IncludeRules context="##XML" includeAttrib="true"/>
</context>
<context attribute="code" lineEndContext="#stay" name="code">
<WordDetect attribute="code" context="#pop" String="```"/>
@@ -98,8 +142,19 @@
<RegExpr attribute="mailtolink" String="&mailtolinkregex;"/>
<RegExpr attribute="strikeout" minimal="true" String="&strikeoutregex;"/>
<RegExpr attribute="linebreak" minimal="true" String="&linebreakregex;"/>
+ <WordDetect attribute="code" context="bash-code" String="```bash"/>
+ <WordDetect attribute="code" context="cmake-code" String="```cmake"/>
+ <WordDetect attribute="code" context="cpp-code" String="```cpp"/>
+ <WordDetect attribute="code" context="css-code" String="```css"/>
+ <WordDetect attribute="code" context="email-code" String="```email"/>
+ <WordDetect attribute="code" context="haskell-code" String="```haskell"/>
+ <WordDetect attribute="code" context="html-code" String="```html"/>
+ <WordDetect attribute="code" context="json-code" String="```json"/>
<WordDetect attribute="code" context="php-code" String="```php"/>
<WordDetect attribute="code" context="python-code" String="```python"/>
+ <WordDetect attribute="code" context="qml-code" String="```qml"/>
+ <WordDetect attribute="code" context="rust-code" String="```rust"/>
+ <WordDetect attribute="code" context="xml-code" String="```xml"/>
<StringDetect attribute="code" context="code" String="```"/>
</context>
</contexts>
@@ -121,12 +176,12 @@
<itemData name="blockquote" defStyleNum="dsDataType"/>
<itemData name="bq-emphasis" defStyleNum="dsDataType" italic="true"/>
<itemData name="bq-strong" defStyleNum="dsDataType" bold="true"/>
- <itemData name="bullet" defStyleNum="dsFloat"/>
- <itemData name="bl-emphasis" defStyleNum="dsFloat" italic="true"/>
- <itemData name="bl-strong" defStyleNum="dsFloat" bold="true"/>
- <itemData name="numlist" defStyleNum="dsFloat"/>
- <itemData name="nl-emphasis" defStyleNum="dsFloat" italic="true"/>
- <itemData name="nl-strong" defStyleNum="dsFloat" bold="true"/>
+ <itemData name="bullet" defStyleNum="dsString"/>
+ <itemData name="bl-emphasis" defStyleNum="dsString" italic="true"/>
+ <itemData name="bl-strong" defStyleNum="dsString" bold="true"/>
+ <itemData name="numlist" defStyleNum="dsString"/>
+ <itemData name="nl-emphasis" defStyleNum="dsString" italic="true"/>
+ <itemData name="nl-strong" defStyleNum="dsString" bold="true"/>
<itemData name="comment" defStyleNum="dsComment"/>
<itemData name="code" defStyleNum="dsBaseN"/>
<itemData name="reflink" defStyleNum="dsOthers" underline="true"/>
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml
index cd3d3ce65c..0d1931649c 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/perl.xml
@@ -39,7 +39,7 @@
Enhance tr/// and y/// support.
-->
-<language name="Perl" version="7" kateversion="2.4" section="Scripts" extensions="*.pl;*.PL;*.pm;*.pl6;*.PL6;*.p6;*.pm6;" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2">
+<language name="Perl" version="8" kateversion="2.4" section="Scripts" extensions="*.pl;*.PL;*.pm;*.pl6;*.PL6;*.p6;*.pm6;" mimetype="application/x-perl;text/x-perl" priority="5" author="Anders Lund (anders@alweb.dk)" license="LGPLv2">
<highlighting>
<list name="keywords">
<item>if</item>
@@ -383,8 +383,11 @@
<RegExpr attribute="Operator" context="find_pattern" String="\b(?:m|qr)(?=\s*[^\w\s\]})])" />
- <RegExpr attribute="Normal Text" context="#stay" String="[\w_]+\s*/" />
- <RegExpr attribute="Normal Text" context="#stay" String="[&lt;&gt;&quot;':]/" />
+ <RegExpr attribute="Normal Text" context="#stay" String="[\w_]+\s*//?\=?" />
+ <RegExpr attribute="Normal Text" context="#stay" String="[&lt;&gt;&quot;':]//?\=?" />
+ <!-- Avoid conflicts between operators / and // -->
+ <StringDetect attribute="Normal Text" context="#stay" String="//=" />
+ <Detect2Chars attribute="Normal Text" context="#stay" char="/" char1="/" />
<DetectChar attribute="Operator" context="pattern_slash" char="/" beginRegion="Pattern" />
<RegExpr attribute="Operator" context="#stay" String="-[rwxoRWXOeszfdlpSbctugkTBMAC]\b" />
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml
index 754dfdc5fe..a451e1442f 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/ruby.xml
@@ -31,7 +31,7 @@
<!-- Hold the "language" opening tag on a single line, as mentioned in "language.dtd". -->
<language name="Ruby" section="Scripts"
- version="9" kateversion="3.3"
+ version="10" kateversion="3.3"
extensions="*.rb;*.rjs;*.rxml;*.xml.erb;*.js.erb;*.rake;Rakefile;Gemfile;*.gemspec;Vagrantfile"
mimetype="application/x-ruby"
style="ruby" indenter="ruby"
@@ -179,11 +179,11 @@
<item>warn</item>
</list>
- <list name="mixin-methods">
- <item>extend</item>
- <item>include</item>
- <item>prepend</item>
- </list>
+ <list name="mixin-methods">
+ <item>extend</item>
+ <item>include</item>
+ <item>prepend</item>
+ </list>
<contexts>
<context name="Normal" attribute="Normal Text" lineEndContext="#stay">
@@ -204,7 +204,7 @@
<RegExpr attribute="Keyword" String="\;\s*(while|until)\b(?!.*\bdo\b)" context="#stay" beginRegion="def block"/>
<RegExpr attribute="Keyword" String="(if|unless)\b" context="#stay" beginRegion="def block" firstNonSpace="true"/>
<RegExpr attribute="Keyword" String="\;\s*(if|unless)\b" context="#stay" beginRegion="def block"/>
- <WordDetect attribute="Keyword" String="class" context="#stay" beginRegion="def block"/>
+ <WordDetect attribute="Keyword" String="class" context="no_heredoc" beginRegion="def block"/>
<WordDetect attribute="Keyword" String="module" context="#stay" beginRegion="def block"/>
<WordDetect attribute="Keyword" String="begin" context="#stay" beginRegion="def block"/>
<RegExpr attribute="Keyword" String="\bfor\b(?!.*\bdo\b)" context="#stay" beginRegion="def block"/>
@@ -231,7 +231,7 @@
<keyword attribute="Pseudo variable" String="pseudo-variables" context="check_div_1"/>
<keyword attribute="Default globals" String="default-globals" context="check_div_2"/>
<keyword attribute="Kernel methods" String="kernel-methods" context="check_div_2"/>
- <keyword attribute="Module mixin methods" String="mixin-methods" context="check_div_2"/>
+ <keyword attribute="Module mixin methods" String="mixin-methods" context="check_div_2"/>
<!-- (global) vars starting with $
Match them before $_.
@@ -263,8 +263,8 @@
push operator '<<' than requiring to put space between the operator
and the string.
-->
- <RegExpr attribute="Operator" context="find_indented_heredoc" String="\s*&lt;&lt;-(?=\w+|[&quot;'])" beginRegion="HereDocument" />
- <RegExpr attribute="Operator" context="find_heredoc" String="\s*&lt;&lt;(?=\w+|[&quot;'])" beginRegion="HereDocument" />
+ <RegExpr attribute="Operator" context="find_indented_heredoc" String="\s*&lt;&lt;[-~](?=\w+|[&quot;'`])" beginRegion="HereDocument" />
+ <RegExpr attribute="Operator" context="find_heredoc" String="\s*&lt;&lt;(?=\w+|[&quot;'`])" beginRegion="HereDocument" />
<DetectChar attribute="Operator" char="." context="#stay"/>
<Detect2Chars attribute="Operator" char="&amp;" char1="&amp;" context="#stay"/>
@@ -280,8 +280,10 @@
<RegExpr attribute="Symbol" String=":(@{1,2}|\$)?[a-zA-Z_][a-zA-Z0-9_]*[=?!]?" context="check_div_1"/>
<RegExpr attribute="Symbol" String=":\[\]=?" context="check_div_1"/>
- <RegExpr attribute="Symbol" String="(@{1,2}|\$)?[a-zA-Z_][a-zA-Z0-9_]*[=?!]?: " context="check_div_1"/>
- <RegExpr attribute="Symbol" String="\[\]=?: " context="check_div_1"/>
+ <!-- Do not send to "check_div_1" context!:
+ after detecting these rules (": ") there can be a regular expression (see bug: #361875) -->
+ <RegExpr attribute="Symbol" String="(@{1,2}|\$)?[a-zA-Z_][a-zA-Z0-9_]*[=?!]?: " context="#stay"/>
+ <RegExpr attribute="Symbol" String="\[\]=?: " context="#stay"/>
<DetectChar attribute="String" char="&quot;" context="Quoted String"/>
<DetectChar attribute="Raw String" char="'" context="Apostrophed String"/>
@@ -436,13 +438,17 @@
The contexts below support both normal and indented heredocs
-->
<!-- here we markup the heredoc markers -->
- <context name="find_heredoc" attribute="Normal Text" lineEndContext="#pop" >
+ <context name="find_heredoc" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<RegExpr attribute="Keyword" context="apostrophed_normal_heredoc" String="'(\w+)'" />
- <RegExpr attribute="Keyword" context="normal_heredoc" String="&quot;?(\w+)&quot;?" />
+ <RegExpr attribute="Keyword" context="normal_heredoc" String="(\w+)" />
+ <RegExpr attribute="Keyword" context="normal_heredoc" String="&quot;(\w+)&quot;" />
+ <RegExpr attribute="Keyword" context="normal_heredoc" String="`(\w+)`" />
</context>
- <context name="find_indented_heredoc" attribute="Normal Text" lineEndContext="#pop" >
+ <context name="find_indented_heredoc" attribute="Normal Text" lineEndContext="#pop" fallthrough="true" fallthroughContext="#pop">
<RegExpr attribute="Keyword" context="apostrophed_indented_heredoc" String="'(\w+)'" />
- <RegExpr attribute="Keyword" context="indented_heredoc" String="&quot;?(\w+)&quot;?" />
+ <RegExpr attribute="Keyword" context="indented_heredoc" String="(\w+)" />
+ <RegExpr attribute="Keyword" context="indented_heredoc" String="&quot;(\w+)&quot;" />
+ <RegExpr attribute="Keyword" context="indented_heredoc" String="`(\w+)`" />
</context>
<!-- these are the real heredoc contexts -->
<context name="indented_heredoc" attribute="Here Document" lineEndContext="#stay" dynamic="true">
@@ -467,6 +473,16 @@
<Detect2Chars attribute="Substitution" char="#" char1="{" context="Subst"/>
</context>
+ <!-- avoid highlighting heredoc markers, for example, in singleton class definition (see bug: #358273) -->
+ <context name="no_heredoc" attribute="Normal Text" lineEndContext="#stay" fallthrough="true" fallthroughContext="#pop">
+ <DetectSpaces />
+ <Detect2Chars attribute="Operator" char="&lt;" char1="&lt;" context="#pop"/>
+ <!-- comments -->
+ <RegExpr attribute="Comment" String="#\s*BEGIN.*$" context="#stay" beginRegion="marker" column="0"/>
+ <RegExpr attribute="Comment" String="#\s*END.*$" context="#stay" endRegion="marker" column="0"/>
+ <DetectChar attribute="Comment" char="#" context="General Comment"/>
+ </context>
+
<!-- General delimited input support
The contexts below handle the various gdl formats
-->
@@ -892,7 +908,7 @@
<itemData name="Constant" defStyleNum="dsDataType"/>
<itemData name="Constant Value" defStyleNum="dsDataType" color="#bb1188"/>
<itemData name="Kernel methods" defStyleNum="dsNormal" color="#000080" selColor="#ffffff"/> <!-- #CC0E86 -->
- <itemData name="Module mixin methods" defStyleNum="dsNormal" color="#000080" selColor="#ffffff"/> <!-- #CC0E86 -->
+ <itemData name="Module mixin methods" defStyleNum="dsNormal" color="#000080" selColor="#ffffff"/> <!-- #CC0E86 -->
<itemData name="Member" defStyleNum="dsNormal"/>
<itemData name="Instance Variable" defStyleNum="dsOthers"/>
<itemData name="Class Variable" defStyleNum="dsOthers"/>
@@ -913,3 +929,5 @@
<keywords casesensitive="1" weakDeliminator="!?"/>
</general>
</language>
+
+<!-- kate: replace-tabs off; -->
diff --git a/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml b/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml
index 6936c7a2de..06d6492ff1 100644
--- a/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml
+++ b/src/libs/3rdparty/syntax-highlighting/data/syntax/yacc.xml
@@ -32,7 +32,7 @@ This code is released under the LGPL as part of kdelibs/kate.
========================================================================
-->
-<language name="Yacc/Bison" version="4" kateversion="2.4" section="Sources" extensions="*.y;*.yy;*.ypp;*.y++" mimetype="text/x-yacc;text/x-bison" priority="5" author="Jan Villat (jan.villat@net2000.ch)" license="LGPL">
+<language name="Yacc/Bison" version="5" kateversion="5.0" section="Sources" extensions="*.y;*.yy;*.ypp;*.y++" mimetype="text/x-yacc;text/x-bison" priority="5" author="Jan Villat (jan.villat@net2000.ch)" license="LGPL">
<highlighting>
<contexts>
@@ -200,9 +200,12 @@ This code is released under the LGPL as part of kdelibs/kate.
</context>
<context name="CommentStar" attribute="Comment" lineEndContext="#stay">
<Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" />
+ <IncludeRules context="##Alerts" />
+ <IncludeRules context="##Modelines" />
</context>
- <context name="CommentSlash" attribute="Comment" lineEndContext="#stay">
- <RegExpr attribute="Comment" context="#pop" String="[^\\]$" />
+ <context name="CommentSlash" attribute="Comment" lineEndContext="#pop">
+ <IncludeRules context="##Alerts" />
+ <IncludeRules context="##Modelines" />
</context>
<context name="StringOrChar" attribute="Normal Text" lineEndContext="#stay">
diff --git a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
index 80a15d2589..8334dd32e9 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/cli/kate-syntax-highlighter.cpp
@@ -92,14 +92,14 @@ int main(int argc, char **argv)
Repository repo;
if (parser.isSet(listDefs)) {
- foreach (const auto &def, repo.definitions()) {
+ for (const auto &def : repo.definitions()) {
std::cout << qPrintable(def.name()) << std::endl;
}
return 0;
}
if (parser.isSet(listThemes)) {
- foreach (const auto &theme, repo.themes())
+ for (const auto &theme : repo.themes())
std::cout << qPrintable(theme.name()) << std::endl;
return 0;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
index 489fbec160..3534cfde90 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/indexer/katehighlightingindexer.cpp
@@ -194,6 +194,82 @@ bool checkLookAhead(const QString &hlFilename, QXmlStreamReader &xml)
}
/**
+ * Helper class to search for non-existing keyword include.
+ */
+class KeywordIncludeChecker
+{
+public:
+ void processElement(const QString &hlFilename, const QString &hlName, QXmlStreamReader &xml)
+ {
+ if (xml.name() == QLatin1String("list")) {
+ auto &keywords = m_keywordMap[hlName];
+ keywords.filename = hlFilename;
+ auto name = xml.attributes().value(QLatin1String("name")).toString();
+ m_currentIncludes = &keywords.includes[name];
+ }
+ else if (xml.name() == QLatin1String("include")) {
+ if (!m_currentIncludes) {
+ qWarning() << hlFilename << "line" << xml.lineNumber() << "<include> tag ouside <list>";
+ m_success = false;
+ } else {
+ m_currentIncludes->push_back({xml.lineNumber(), xml.readElementText()});
+ }
+ }
+ }
+
+ bool check() const
+ {
+ bool success = m_success;
+ for (auto &keywords : m_keywordMap) {
+ QMapIterator<QString, QVector<Keywords::Include>> includes(keywords.includes);
+ while (includes.hasNext()) {
+ includes.next();
+ for (auto &include : includes.value()) {
+ bool containsKeywordName = true;
+ int const idx = include.name.indexOf(QStringLiteral("##"));
+ if (idx == -1) {
+ auto &keywordName = includes.key();
+ containsKeywordName = keywords.includes.contains(keywordName);
+ }
+ else {
+ auto defName = include.name.mid(idx + 2);
+ auto listName = include.name.left(idx);
+ auto it = m_keywordMap.find(defName);
+ if (it == m_keywordMap.end()) {
+ qWarning() << keywords.filename << "line" << include.line << "unknown definition in" << include.name;
+ success = false;
+ } else {
+ containsKeywordName = it->includes.contains(listName);
+ }
+ }
+
+ if (!containsKeywordName) {
+ qWarning() << keywords.filename << "line" << include.line << "unknown keyword name in" << include.name;
+ success = false;
+ }
+ }
+ }
+ }
+ return success;
+ }
+
+private:
+ struct Keywords
+ {
+ QString filename;
+ struct Include
+ {
+ qint64 line;
+ QString name;
+ };
+ QMap<QString, QVector<Include>> includes;
+ };
+ QHash<QString, Keywords> m_keywordMap;
+ QVector<Keywords::Include> *m_currentIncludes = nullptr;
+ bool m_success = true;
+};
+
+/**
* Helper class to search for non-existing or unreferenced keyword lists.
*/
class KeywordChecker
@@ -296,6 +372,7 @@ public:
const auto unusedNames = language.existingContextNames - language.usedContextNames;
if (!unusedNames.isEmpty()) {
qWarning() << language.hlFilename << "Unused contexts:" << unusedNames;
+ success = false;
}
}
@@ -457,9 +534,10 @@ int main(int argc, char *argv[])
// index all given highlightings
ContextChecker contextChecker;
+ KeywordIncludeChecker keywordIncludeChecker;
QVariantMap hls;
int anyError = 0;
- foreach (const QString &hlFilename, hlFilenames) {
+ for (const QString &hlFilename : qAsConst(hlFilenames)) {
QFile hlFile(hlFilename);
if (!hlFile.open(QIODevice::ReadOnly)) {
qWarning ("Failed to open %s", qPrintable(hlFilename));
@@ -493,7 +571,7 @@ int main(int argc, char *argv[])
QVariantMap hl;
// transfer text attributes
- Q_FOREACH (const QString &attribute, textAttributes) {
+ for (const QString &attribute : qAsConst(textAttributes)) {
hl[attribute] = xml.attributes().value(attribute).toString();
}
@@ -528,6 +606,9 @@ int main(int argc, char *argv[])
// search for used/existing contexts if applicable
contextChecker.processElement(hlFilename, hlName, xml);
+ // search for existing keyword includes
+ keywordIncludeChecker.processElement(hlFilename, hlName, xml);
+
// search for used/existing attributes if applicable
attributeChecker.processElement(xml);
@@ -571,6 +652,9 @@ int main(int argc, char *argv[])
if (!contextChecker.check())
anyError = 7;
+ if (!keywordIncludeChecker.check())
+ anyError = 7;
+
// bail out if any problem was seen
if (anyError)
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
index bf729fca71..95bf4c349e 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/CMakeLists.txt
@@ -40,6 +40,7 @@ ecm_generate_headers(SyntaxHighlighting_HEADERS
HEADER_NAMES
AbstractHighlighter
Definition
+ DefinitionDownloader
FoldingRegion
Format
Repository
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
index f69944debd..c4ef86a771 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/abstracthighlighter.cpp
@@ -53,7 +53,7 @@ void AbstractHighlighterPrivate::ensureDefinitionLoaded()
defData = DefinitionData::get(m_definition);
}
- if (Q_UNLIKELY(!defData->repo && !defData->name.isEmpty()))
+ if (Q_UNLIKELY(!defData->repo && !defData->fileName.isEmpty()))
qCCritical(Log) << "Repository got deleted while a highlighter is still active!";
if (m_definition.isValid())
@@ -118,13 +118,13 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state
// verify definition, deal with no highlighting being enabled
d->ensureDefinitionLoaded();
- if (!d->m_definition.isValid()) {
+ const auto defData = DefinitionData::get(d->m_definition);
+ if (!d->m_definition.isValid() || !defData->isLoaded()) {
applyFormat(0, text.size(), Format());
return State();
}
// verify/initialize state
- auto defData = DefinitionData::get(d->m_definition);
auto newState = state;
auto stateData = StateData::get(newState);
const DefinitionRef currentDefRef(d->m_definition);
@@ -139,9 +139,37 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state
// process empty lines
if (text.isEmpty()) {
- while (!stateData->topContext()->lineEmptyContext().isStay()) {
- if (!d->switchContext(stateData, stateData->topContext()->lineEmptyContext(), QStringList()))
+ /**
+ * handle line empty context switches
+ * guard against endless loops
+ * see https://phabricator.kde.org/D18509
+ */
+ int endlessLoopingCounter = 0;
+ while (!stateData->topContext()->lineEmptyContext().isStay() || (stateData->topContext()->lineEmptyContext().isStay() && !stateData->topContext()->lineEndContext().isStay())) {
+ /**
+ * line empty context switches
+ */
+ if (!stateData->topContext()->lineEmptyContext().isStay()) {
+ if (!d->switchContext(stateData, stateData->topContext()->lineEmptyContext(), QStringList())) {
+ /**
+ * end when trying to #pop the main context
+ */
+ break;
+ }
+ /**
+ * line end context switches only when lineEmptyContext is #stay. This avoids
+ * skipping empty lines after a line continuation character (see bug 405903)
+ */
+ } else if (!stateData->topContext()->lineEndContext().isStay() &&
+ !d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
break;
+
+ // guard against endless loops
+ ++endlessLoopingCounter;
+ if (endlessLoopingCounter > 1024) {
+ qCDebug(Log) << "Endless switch context transitions for line empty context, aborting highlighting of line.";
+ break;
+ }
}
auto context = stateData->topContext();
applyFormat(0, 0, context->attributeFormat());
@@ -238,11 +266,18 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state
if (newOffset <= offset)
continue;
- // apply folding
- if (rule->endRegion().isValid())
- applyFolding(offset, newOffset - offset, rule->endRegion());
+ /**
+ * apply folding.
+ * special cases:
+ * - rule with endRegion + beginRegion: in endRegion, the length is 0
+ * - rule with lookAhead: length is 0
+ */
+ if (rule->endRegion().isValid() && rule->beginRegion().isValid())
+ applyFolding(offset, 0, rule->endRegion());
+ else if (rule->endRegion().isValid())
+ applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->endRegion());
if (rule->beginRegion().isValid())
- applyFolding(offset, newOffset - offset, rule->beginRegion());
+ applyFolding(offset, rule->isLookAhead() ? 0 : newOffset - offset, rule->beginRegion());
if (rule->isLookAhead()) {
Q_ASSERT(!rule->context().isStay());
@@ -293,12 +328,30 @@ State AbstractHighlighter::highlightLine(const QString& text, const State &state
} while (offset < text.size());
+ /**
+ * apply format for remaining text, if any
+ */
if (beginOffset < offset)
applyFormat(beginOffset, text.size() - beginOffset, *currentFormat);
- while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) {
- if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
- break;
+ /**
+ * handle line end context switches
+ * guard against endless loops
+ * see https://phabricator.kde.org/D18509
+ */
+ {
+ int endlessLoopingCounter = 0;
+ while (!stateData->topContext()->lineEndContext().isStay() && !lineContinuation) {
+ if (!d->switchContext(stateData, stateData->topContext()->lineEndContext(), QStringList()))
+ break;
+
+ // guard against endless loops
+ ++endlessLoopingCounter;
+ if (endlessLoopingCounter > 1024) {
+ qCDebug(Log) << "Endless switch context transitions for line end context, aborting highlighting of line.";
+ break;
+ }
+ }
}
return newState;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
index c03d23dc48..ae95a6b235 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition.cpp
@@ -31,6 +31,7 @@
#include "context_p.h"
#include "format.h"
#include "format_p.h"
+#include "repository.h"
#include "repository_p.h"
#include "rule_p.h"
#include "ksyntaxhighlighting_logging.h"
@@ -222,13 +223,13 @@ QStringList Definition::foldingIgnoreList() const
QStringList Definition::keywordLists() const
{
- d->load();
+ d->load(DefinitionData::OnlyKeywords(true));
return d->keywordLists.keys();
}
QStringList Definition::keywordList(const QString& name) const
{
- d->load();
+ d->load(DefinitionData::OnlyKeywords(true));
const auto list = d->keywordList(name);
return list ? list->keywords() : QStringList();
}
@@ -323,18 +324,18 @@ Context* DefinitionData::initialContext() const
return contexts.first();
}
-Context* DefinitionData::contextByName(const QString& name) const
+Context* DefinitionData::contextByName(const QString& wantedName) const
{
- foreach (auto context, contexts) {
- if (context->name() == name)
+ for (const auto context : contexts) {
+ if (context->name() == wantedName)
return context;
}
return nullptr;
}
-KeywordList *DefinitionData::keywordList(const QString& name)
+KeywordList *DefinitionData::keywordList(const QString& wantedName)
{
- auto it = keywordLists.find(name);
+ auto it = keywordLists.find(wantedName);
return (it == keywordLists.end()) ? nullptr : &it.value();
}
@@ -343,9 +344,9 @@ bool DefinitionData::isWordDelimiter(QChar c) const
return std::binary_search(wordDelimiters.constBegin(), wordDelimiters.constEnd(), c);
}
-Format DefinitionData::formatByName(const QString& name) const
+Format DefinitionData::formatByName(const QString& wantedName) const
{
- const auto it = formats.constFind(name);
+ const auto it = formats.constFind(wantedName);
if (it != formats.constEnd())
return it.value();
@@ -357,7 +358,7 @@ bool DefinitionData::isLoaded() const
return !contexts.isEmpty();
}
-bool DefinitionData::load()
+bool DefinitionData::load(OnlyKeywords onlyKeywords)
{
if (fileName.isEmpty())
return false;
@@ -365,6 +366,9 @@ bool DefinitionData::load()
if (isLoaded())
return true;
+ if (bool(onlyKeywords) && keywordIsLoaded)
+ return true;
+
QFile file(fileName);
if (!file.open(QFile::ReadOnly))
return false;
@@ -375,17 +379,22 @@ bool DefinitionData::load()
if (token != QXmlStreamReader::StartElement)
continue;
- if (reader.name() == QLatin1String("highlighting"))
- loadHighlighting(reader);
+ if (reader.name() == QLatin1String("highlighting")) {
+ loadHighlighting(reader, onlyKeywords);
+ if (bool(onlyKeywords)) {
+ return true;
+ }
+ }
else if (reader.name() == QLatin1String("general"))
loadGeneral(reader);
}
- for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it)
- (*it).setCaseSensitivity(caseSensitive);
+ for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
+ it->setCaseSensitivity(caseSensitive);
+ }
- foreach (auto context, contexts) {
+ for (const auto context : qAsConst(contexts)) {
context->resolveContexts();
context->resolveIncludes();
context->resolveAttributeFormat();
@@ -454,10 +463,10 @@ bool DefinitionData::loadMetaData(const QString &file, const QJsonObject &obj)
fileName = file;
const auto exts = obj.value(QLatin1String("extensions")).toString();
- foreach (const auto &ext, exts.split(QLatin1Char(';'), QString::SkipEmptyParts))
+ for (const auto &ext : exts.split(QLatin1Char(';'), QString::SkipEmptyParts))
extensions.push_back(ext);
const auto mts = obj.value(QLatin1String("mimetype")).toString();
- foreach (const auto &mt, mts.split(QLatin1Char(';'), QString::SkipEmptyParts))
+ for (const auto &mt : mts.split(QLatin1Char(';'), QString::SkipEmptyParts))
mimetypes.push_back(mt);
return true;
@@ -482,29 +491,42 @@ bool DefinitionData::loadLanguage(QXmlStreamReader &reader)
author = reader.attributes().value(QStringLiteral("author")).toString();
license = reader.attributes().value(QStringLiteral("license")).toString();
const auto exts = reader.attributes().value(QStringLiteral("extensions")).toString();
- foreach (const auto &ext, exts.split(QLatin1Char(';'), QString::SkipEmptyParts))
+ for (const auto &ext : exts.split(QLatin1Char(';'), QString::SkipEmptyParts))
extensions.push_back(ext);
const auto mts = reader.attributes().value(QStringLiteral("mimetype")).toString();
- foreach (const auto &mt, mts.split(QLatin1Char(';'), QString::SkipEmptyParts))
+ for (const auto &mt : mts.split(QLatin1Char(';'), QString::SkipEmptyParts))
mimetypes.push_back(mt);
if (reader.attributes().hasAttribute(QStringLiteral("casesensitive")))
caseSensitive = Xml::attrToBool(reader.attributes().value(QStringLiteral("casesensitive"))) ? Qt::CaseSensitive : Qt::CaseInsensitive;
return true;
}
-void DefinitionData::loadHighlighting(QXmlStreamReader& reader)
+void DefinitionData::loadHighlighting(QXmlStreamReader& reader, OnlyKeywords onlyKeywords)
{
Q_ASSERT(reader.name() == QLatin1String("highlighting"));
Q_ASSERT(reader.tokenType() == QXmlStreamReader::StartElement);
+ // skip highlighting
+ reader.readNext();
+
while (!reader.atEnd()) {
switch (reader.tokenType()) {
case QXmlStreamReader::StartElement:
if (reader.name() == QLatin1String("list")) {
- KeywordList keywords;
- keywords.load(reader);
- keywordLists.insert(keywords.name(), keywords);
+ if (!keywordIsLoaded) {
+ KeywordList keywords;
+ keywords.load(reader);
+ keywordLists.insert(keywords.name(), keywords);
+ }
+ else {
+ reader.skipCurrentElement();
+ reader.readNext(); // Skip </list>
+ }
+ } else if (bool(onlyKeywords)) {
+ resolveIncludeKeywords();
+ return;
} else if (reader.name() == QLatin1String("contexts")) {
+ resolveIncludeKeywords();
loadContexts(reader);
reader.readNext();
} else if (reader.name() == QLatin1String("itemDatas")) {
@@ -522,6 +544,19 @@ void DefinitionData::loadHighlighting(QXmlStreamReader& reader)
}
}
+void DefinitionData::resolveIncludeKeywords()
+{
+ if (keywordIsLoaded) {
+ return;
+ }
+
+ keywordIsLoaded = true;
+
+ for (auto it = keywordLists.begin(); it != keywordLists.end(); ++it) {
+ it->resolveIncludeKeywords(*this);
+ }
+}
+
void DefinitionData::loadContexts(QXmlStreamReader& reader)
{
Q_ASSERT(reader.name() == QLatin1String("contexts"));
@@ -598,7 +633,7 @@ void DefinitionData::loadGeneral(QXmlStreamReader& reader)
std::sort(wordDelimiters.begin(), wordDelimiters.end());
auto it = std::unique(wordDelimiters.begin(), wordDelimiters.end());
wordDelimiters.truncate(std::distance(wordDelimiters.begin(), it));
- foreach (const auto c, reader.attributes().value(QLatin1String("weakDeliminator")))
+ for (const auto c : reader.attributes().value(QLatin1String("weakDeliminator")))
wordDelimiters.remove(c);
// adaptWordWrapDelimiters, and sort
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h
index ab95a9552c..9bbf59691c 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/definition_p.h
@@ -46,6 +46,9 @@ public:
DefinitionData();
~DefinitionData();
+ DefinitionData(const DefinitionData &) = delete;
+ DefinitionData &operator=(const DefinitionData &) = delete;
+
static DefinitionData* get(const Definition &def);
bool isLoaded() const;
@@ -54,9 +57,11 @@ public:
void clear();
- bool load();
+ enum class OnlyKeywords : bool;
+
+ bool load(OnlyKeywords onlyKeywords = OnlyKeywords(false));
bool loadLanguage(QXmlStreamReader &reader);
- void loadHighlighting(QXmlStreamReader &reader);
+ void loadHighlighting(QXmlStreamReader &reader, OnlyKeywords onlyKeywords);
void loadContexts(QXmlStreamReader &reader);
void loadItemData(QXmlStreamReader &reader);
void loadGeneral(QXmlStreamReader &reader);
@@ -65,6 +70,8 @@ public:
void loadSpellchecking(QXmlStreamReader &reader);
bool checkKateVersion(const QStringRef &verStr);
+ void resolveIncludeKeywords();
+
KeywordList *keywordList(const QString &name);
bool isWordDelimiter(QChar c) const;
@@ -83,6 +90,7 @@ public:
QHash<QString, Format> formats;
QString wordDelimiters;
QString wordWrapDelimiters;
+ bool keywordIsLoaded = false;
bool hasFoldingRegions = false;
bool indentationBasedFolding = false;
QStringList foldingIgnoreList;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
index 397da6d700..d1808cafef 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/format.cpp
@@ -213,52 +213,52 @@ void FormatPrivate::load(QXmlStreamReader& reader)
name = reader.attributes().value(QStringLiteral("name")).toString();
defaultStyle = stringToDefaultFormat(reader.attributes().value(QStringLiteral("defStyleNum")));
- QStringRef ref = reader.attributes().value(QStringLiteral("color"));
- if (!ref.isEmpty()) {
- style.textColor = QColor(ref.toString()).rgba();
+ QStringRef attribute = reader.attributes().value(QStringLiteral("color"));
+ if (!attribute.isEmpty()) {
+ style.textColor = QColor(attribute.toString()).rgba();
}
- ref = reader.attributes().value(QStringLiteral("selColor"));
- if (!ref.isEmpty()) {
- style.selectedTextColor = QColor(ref.toString()).rgba();
+ attribute = reader.attributes().value(QStringLiteral("selColor"));
+ if (!attribute.isEmpty()) {
+ style.selectedTextColor = QColor(attribute.toString()).rgba();
}
- ref = reader.attributes().value(QStringLiteral("backgroundColor"));
- if (!ref.isEmpty()) {
- style.backgroundColor = QColor(ref.toString()).rgba();
+ attribute = reader.attributes().value(QStringLiteral("backgroundColor"));
+ if (!attribute.isEmpty()) {
+ style.backgroundColor = QColor(attribute.toString()).rgba();
}
- ref = reader.attributes().value(QStringLiteral("selBackgroundColor"));
- if (!ref.isEmpty()) {
- style.selectedBackgroundColor = QColor(ref.toString()).rgba();
+ attribute = reader.attributes().value(QStringLiteral("selBackgroundColor"));
+ if (!attribute.isEmpty()) {
+ style.selectedBackgroundColor = QColor(attribute.toString()).rgba();
}
- ref = reader.attributes().value(QStringLiteral("italic"));
- if (!ref.isEmpty()) {
+ attribute = reader.attributes().value(QStringLiteral("italic"));
+ if (!attribute.isEmpty()) {
style.hasItalic = true;
- style.italic = Xml::attrToBool(ref);
+ style.italic = Xml::attrToBool(attribute);
}
- ref = reader.attributes().value(QStringLiteral("bold"));
- if (!ref.isEmpty()) {
+ attribute = reader.attributes().value(QStringLiteral("bold"));
+ if (!attribute.isEmpty()) {
style.hasBold = true;
- style.bold = Xml::attrToBool(ref);
+ style.bold = Xml::attrToBool(attribute);
}
- ref = reader.attributes().value(QStringLiteral("underline"));
- if (!ref.isEmpty()) {
+ attribute = reader.attributes().value(QStringLiteral("underline"));
+ if (!attribute.isEmpty()) {
style.hasUnderline = true;
- style.underline = Xml::attrToBool(ref);
+ style.underline = Xml::attrToBool(attribute);
}
- ref = reader.attributes().value(QStringLiteral("strikeOut"));
- if (!ref.isEmpty()) {
+ attribute = reader.attributes().value(QStringLiteral("strikeOut"));
+ if (!attribute.isEmpty()) {
style.hasStrikeThrough = true;
- style.strikeThrough = Xml::attrToBool(ref);
+ style.strikeThrough = Xml::attrToBool(attribute);
}
- ref = reader.attributes().value(QStringLiteral("spellChecking"));
- if (!ref.isEmpty()) {
- spellCheck = Xml::attrToBool(ref);
+ attribute = reader.attributes().value(QStringLiteral("spellChecking"));
+ if (!attribute.isEmpty()) {
+ spellCheck = Xml::attrToBool(attribute);
}
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
index fe5f77586a..f042baac27 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist.cpp
@@ -22,6 +22,9 @@
*/
#include "keywordlist_p.h"
+#include "repository.h"
+#include "definition_p.h"
+#include "ksyntaxhighlighting_logging.h"
#include <QDebug>
#include <QXmlStreamReader>
@@ -58,6 +61,11 @@ void KeywordList::load(QXmlStreamReader& reader)
reader.readNextStartElement();
break;
}
+ else if (reader.name() == QLatin1String("include")) {
+ m_includes.append(reader.readElementText().trimmed());
+ reader.readNextStartElement();
+ break;
+ }
reader.readNext();
break;
case QXmlStreamReader::EndElement:
@@ -102,3 +110,40 @@ void KeywordList::initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive
*/
std::sort(vectorToSort.begin(), vectorToSort.end(), [caseSensitive] (const QStringRef &a, const QStringRef &b) { return a.compare(b, caseSensitive) < 0; });
}
+
+void KeywordList::resolveIncludeKeywords(DefinitionData &def)
+{
+ while (!m_includes.isEmpty()) {
+ const auto kw_include = std::move(m_includes.back());
+ m_includes.pop_back();
+
+ const auto idx = kw_include.indexOf(QLatin1String("##"));
+ KeywordList *keywords = nullptr;
+
+ if (idx >= 0) {
+ auto listName = kw_include.left(idx);
+ auto defName = kw_include.mid(idx + 2);
+ auto includeDef = def.repo->definitionForName(defName);
+ if (includeDef.isValid()) {
+ auto defData = DefinitionData::get(includeDef);
+ defData->load(DefinitionData::OnlyKeywords(true));
+ keywords = defData->keywordList(listName);
+ }
+ else {
+ qCWarning(Log) << "Unable to resolve external include keyword for definition" << defName << "in" << def.name;
+ }
+ } else {
+ keywords = def.keywordList(kw_include);
+ }
+
+ if (keywords) {
+ if (this != keywords) {
+ keywords->resolveIncludeKeywords(def);
+ }
+ m_keywords += keywords->m_keywords;
+ }
+ else {
+ qCWarning(Log) << "Unresolved include keyword" << kw_include << "in" << def.name;
+ }
+ }
+}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h
index 8c41aabe0c..25d0022dbe 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/keywordlist_p.h
@@ -36,6 +36,9 @@ QT_END_NAMESPACE
namespace KSyntaxHighlighting {
+class Repository;
+class DefinitionData;
+
class KeywordList
{
public:
@@ -69,6 +72,7 @@ public:
void load(QXmlStreamReader &reader);
void setCaseSensitivity(Qt::CaseSensitivity caseSensitive);
void initLookupForCaseSensitivity(Qt::CaseSensitivity caseSensitive);
+ void resolveIncludeKeywords(DefinitionData &def);
private:
/**
@@ -82,6 +86,11 @@ private:
QStringList m_keywords;
/**
+ * raw list of include keywords, as seen in XML (but trimmed)
+ */
+ QStringList m_includes;
+
+ /**
* default case-sensitivity setting
*/
Qt::CaseSensitivity m_caseSensitive = Qt::CaseSensitive;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
index 922225a7e1..aaba9616dc 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.cpp
@@ -69,7 +69,7 @@ Repository::~Repository()
{
// reset repo so we can detect in still alive definition instances
// that the repo was deleted
- foreach (const auto &def, d->m_sortedDefs)
+ for (const auto &def : qAsConst(d->m_sortedDefs))
DefinitionData::get(def)->repo = nullptr;
}
@@ -78,21 +78,16 @@ Definition Repository::definitionForName(const QString& defName) const
return d->m_defs.value(defName);
}
-static Definition bestCandidate(QVector<Definition> &&candidates)
+static void sortDefinitions(QVector<Definition> &definitions)
{
- if (candidates.isEmpty())
- return Definition();
-
- std::partial_sort(candidates.begin(), candidates.begin() + 1, candidates.end(), [](const Definition &lhs, const Definition &rhs) {
+ std::stable_sort(definitions.begin(), definitions.end(), [](const Definition &lhs, const Definition &rhs) {
return lhs.priority() > rhs.priority();
});
-
- return candidates.at(0);
}
Definition Repository::definitionForFileName(const QString& fileName) const
{
- return bestCandidate(definitionsForFileName(fileName));
+ return definitionsForFileName(fileName).value(0);
}
QVector<Definition> Repository::definitionsForFileName(const QString &fileName) const
@@ -101,9 +96,8 @@ QVector<Definition> Repository::definitionsForFileName(const QString &fileName)
const auto name = fi.fileName();
QVector<Definition> candidates;
- for (auto it = d->m_defs.constBegin(); it != d->m_defs.constEnd(); ++it) {
- auto def = it.value();
- foreach (const auto &pattern, def.extensions()) {
+ for (const Definition &def : qAsConst(d->m_sortedDefs)) {
+ for (const auto &pattern : def.extensions()) {
if (WildcardMatcher::exactMatch(name, pattern)) {
candidates.push_back(def);
break;
@@ -111,26 +105,28 @@ QVector<Definition> Repository::definitionsForFileName(const QString &fileName)
}
}
+ sortDefinitions(candidates);
return candidates;
}
Definition Repository::definitionForMimeType(const QString& mimeType) const
{
- return bestCandidate(definitionsForMimeType(mimeType));
+ return definitionsForMimeType(mimeType).value(0);
}
QVector<Definition> Repository::definitionsForMimeType(const QString &mimeType) const
{
QVector<Definition> candidates;
- for (auto it = d->m_defs.constBegin(); it != d->m_defs.constEnd(); ++it) {
- auto def = it.value();
- foreach (const auto &matchType, def.mimeTypes()) {
+ for (const Definition &def : qAsConst(d->m_sortedDefs)) {
+ for (const auto &matchType : def.mimeTypes()) {
if (mimeType == matchType) {
candidates.push_back(def);
break;
}
}
}
+
+ sortDefinitions(candidates);
return candidates;
}
@@ -169,11 +165,11 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
- foreach (const auto &dir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/syntax"), QStandardPaths::LocateDirectory))
+ for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/syntax"), QStandardPaths::LocateDirectory))
loadSyntaxFolder(repo, dir);
// backward compatibility with Kate
- foreach (const auto &dir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory))
+ for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("katepart5/syntax"), QStandardPaths::LocateDirectory))
loadSyntaxFolder(repo, dir);
#endif
@@ -181,7 +177,7 @@ void RepositoryPrivate::load(Repository *repo)
loadSyntaxFolder(repo, QStringLiteral(":/org.kde.syntax-highlighting/syntax"));
// user given extra paths
- foreach (const auto &path, m_customSearchPaths)
+ for (const auto &path : qAsConst(m_customSearchPaths))
loadSyntaxFolder(repo, path + QStringLiteral("/syntax"));
m_sortedDefs.reserve(m_defs.size());
@@ -198,7 +194,7 @@ void RepositoryPrivate::load(Repository *repo)
// do lookup in standard paths, if not disabled
#ifndef NO_STANDARD_PATHS
- foreach (const auto &dir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/themes"), QStandardPaths::LocateDirectory))
+ for (const auto &dir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("org.kde.syntax-highlighting/themes"), QStandardPaths::LocateDirectory))
loadThemeFolder(dir);
#endif
@@ -206,7 +202,7 @@ void RepositoryPrivate::load(Repository *repo)
loadThemeFolder(QStringLiteral(":/org.kde.syntax-highlighting/themes"));
// user given extra paths
- foreach (const auto &path, m_customSearchPaths)
+ for (const auto &path : qAsConst(m_customSearchPaths))
loadThemeFolder(path + QStringLiteral("/themes"));
}
@@ -307,7 +303,7 @@ quint16 RepositoryPrivate::nextFormatId()
void Repository::reload()
{
qCDebug(Log) << "Reloading syntax definitions!";
- foreach (const auto &def, d->m_sortedDefs)
+ for (const auto &def : qAsConst(d->m_sortedDefs))
DefinitionData::get(def)->clear();
d->m_defs.clear();
d->m_sortedDefs.clear();
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
index e4e9bed69f..2bc66965cf 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/repository.h
@@ -167,9 +167,11 @@ public:
Definition definitionForFileName(const QString &fileName) const;
/**
- * Returns all Definition%s for the file named @p fileName.
+ * Returns all Definition%s for the file named @p fileName sorted by priority.
* The match is performed based on the \e extensions and @e mimetype of
* the definition files.
+ *
+ * @since 5.56
*/
QVector<Definition> definitionsForFileName(const QString &fileName) const;
@@ -184,7 +186,9 @@ public:
Definition definitionForMimeType(const QString &mimeType) const;
/**
- * Returns all Definition%s to the type named @p mimeType
+ * Returns all Definition%s to the type named @p mimeType sorted by priority
+ *
+ * @since 5.56
*/
QVector<Definition> definitionsForMimeType(const QString &mimeType) const;
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
index c48753bf0c..d9cf5eb211 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/rule.cpp
@@ -59,7 +59,8 @@ static int matchEscapedChar(const QString &text, int offset)
if (controlChars.contains(c))
return offset + 2;
- if (c == QLatin1Char('x')) { // hex encoded character
+ // hex encoded character
+ if (c == QLatin1Char('x')) {
auto newOffset = offset + 2;
for (int i = 0; i < 2 && newOffset + i < text.size(); ++i, ++newOffset) {
if (!isHexChar(text.at(newOffset)))
@@ -70,14 +71,13 @@ static int matchEscapedChar(const QString &text, int offset)
return newOffset;
}
- if (isOctalChar(c)) { // octal encoding
+ // octal encoding, simple \0 is OK, too, unlike simple \x above
+ if (isOctalChar(c)) {
auto newOffset = offset + 2;
for (int i = 0; i < 2 && newOffset + i < text.size(); ++i, ++newOffset) {
if (!isOctalChar(text.at(newOffset)))
break;
}
- if (newOffset == offset + 2)
- return offset;
return newOffset;
}
diff --git a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
index 2bb61a7ae6..4987dc95f0 100644
--- a/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
+++ b/src/libs/3rdparty/syntax-highlighting/src/lib/syntaxhighlighter.cpp
@@ -156,15 +156,15 @@ void SyntaxHighlighter::highlightBlock(const QString& text)
void SyntaxHighlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format& format)
{
- if (format.isDefaultTextStyle(theme()) || length == 0)
+ if (length == 0)
return;
QTextCharFormat tf;
- if (format.hasTextColor(theme()))
- tf.setForeground(format.textColor(theme()));
+ // always set the foreground color to avoid palette issues
+ tf.setForeground(format.textColor(theme()));
+
if (format.hasBackgroundColor(theme()))
tf.setBackground(format.backgroundColor(theme()));
-
if (format.isBold(theme()))
tf.setFontWeight(QFont::Bold);
if (format.isItalic(theme()))
diff --git a/src/libs/3rdparty/variant/variant.hpp b/src/libs/3rdparty/variant/variant.hpp
index 29d7feb29f..dca26986c9 100644
--- a/src/libs/3rdparty/variant/variant.hpp
+++ b/src/libs/3rdparty/variant/variant.hpp
@@ -8,6 +8,11 @@
#ifndef MPARK_VARIANT_HPP
#define MPARK_VARIANT_HPP
+#if defined(__GNUC__) && __GNUC__ >= 9
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-copy"
+#endif
+
/*
variant synopsis
@@ -2453,4 +2458,8 @@ namespace std {
} // namespace std
+#if defined(__GNUC__) && __GNUC__ >= 9
+#pragma GCC diagnostic pop
+#endif
+
#endif // MPARK_VARIANT_HPP
diff --git a/src/libs/CMakeLists.txt b/src/libs/CMakeLists.txt
new file mode 100644
index 0000000000..52cc1d35a9
--- /dev/null
+++ b/src/libs/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_subdirectory(3rdparty)
+
+add_subdirectory(aggregation)
+add_subdirectory(extensionsystem)
+add_subdirectory(utils)
+add_subdirectory(languageutils)
+add_subdirectory(cplusplus)
+add_subdirectory(modelinglib)
+add_subdirectory(qmljs)
+add_subdirectory(qmldebug)
+add_subdirectory(qmleditorwidgets)
+add_subdirectory(glsl)
+add_subdirectory(languageserverprotocol)
+add_subdirectory(ssh)
+add_subdirectory(sqlite)
+add_subdirectory(clangsupport)
+add_subdirectory(tracing)
+
+if (WIN32)
+ add_subdirectory(qtcreatorcdbext)
+endif()
diff --git a/src/libs/aggregation/CMakeLists.txt b/src/libs/aggregation/CMakeLists.txt
new file mode 100644
index 0000000000..6871c9ab35
--- /dev/null
+++ b/src/libs/aggregation/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_qtc_library(Aggregation
+ DEPENDS Qt5::Core
+ SOURCES
+ aggregate.cpp aggregate.h
+ aggregation_global.h
+)
diff --git a/src/libs/aggregation/examples/text/main.cpp b/src/libs/aggregation/examples/text/main.cpp
index c205ccb838..043196ab78 100644
--- a/src/libs/aggregation/examples/text/main.cpp
+++ b/src/libs/aggregation/examples/text/main.cpp
@@ -31,7 +31,7 @@ MyMain::MyMain(QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags)
{
ui.setupUi(this);
- connect(ui.comboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ connect(ui.comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &MyMain::select);
}
diff --git a/src/libs/clangsupport/CMakeLists.txt b/src/libs/clangsupport/CMakeLists.txt
new file mode 100644
index 0000000000..84cdbaf8b9
--- /dev/null
+++ b/src/libs/clangsupport/CMakeLists.txt
@@ -0,0 +1,137 @@
+add_qtc_library(ClangSupport
+ PUBLIC_DEPENDS Utils Sqlite Qt5::Core Qt5::Network
+ PUBLIC_INCLUDES "${CMAKE_CURRENT_LIST_DIR}"
+ PUBLIC_DEFINES
+ CLANG_VERSION="${CLANG_VERSION}"
+ CLANG_RESOURCE_DIR="${CLANG_RESOURCE_DIR}"
+ CLANG_BINDIR="${CLANG_BIN_DIR}"
+ DEFINES CLANGSUPPORT_BUILD_LIB
+ SOURCES
+ alivemessage.cpp alivemessage.h
+ annotationsmessage.cpp annotationsmessage.h
+ baseserverproxy.cpp baseserverproxy.h
+ cancelmessage.cpp cancelmessage.h
+ changedfilepathcompressor.h
+ clangcodemodelclientinterface.cpp clangcodemodelclientinterface.h
+ clangcodemodelclientmessages.h
+ clangcodemodelclientproxy.cpp clangcodemodelclientproxy.h
+ clangcodemodelconnectionclient.cpp clangcodemodelconnectionclient.h
+ clangcodemodelserverinterface.cpp clangcodemodelserverinterface.h
+ clangcodemodelservermessages.h
+ clangcodemodelserverproxy.cpp clangcodemodelserverproxy.h
+ clangpathwatcher.h
+ clangpathwatcherinterface.h
+ clangpathwatchernotifier.h
+ clangrefactoringclientmessages.h
+ clangrefactoringmessages.h
+ clangrefactoringservermessages.h
+ clangsupport_global.h
+ clangsupportdebugutils.cpp clangsupportdebugutils.h
+ clangsupportexceptions.h
+ codecompletion.cpp codecompletion.h
+ codecompletionchunk.cpp codecompletionchunk.h
+ commandlinebuilder.h
+ compilermacro.h
+ completionsmessage.cpp completionsmessage.h
+ connectionclient.cpp connectionclient.h
+ connectionserver.cpp connectionserver.h
+ diagnosticcontainer.cpp diagnosticcontainer.h
+ documentschangedmessage.cpp documentschangedmessage.h
+ documentsclosedmessage.cpp documentsclosedmessage.h
+ documentsopenedmessage.cpp documentsopenedmessage.h
+ documentvisibilitychangedmessage.cpp documentvisibilitychangedmessage.h
+ dynamicastmatcherdiagnosticcontainer.cpp dynamicastmatcherdiagnosticcontainer.h
+ dynamicastmatcherdiagnosticcontextcontainer.cpp dynamicastmatcherdiagnosticcontextcontainer.h
+ dynamicastmatcherdiagnosticmessagecontainer.cpp dynamicastmatcherdiagnosticmessagecontainer.h
+ dynamicmatcherdiagnostics.h
+ echomessage.cpp echomessage.h
+ endmessage.cpp endmessage.h
+ environment.h
+ executeinloop.h
+ filecontainer.cpp filecontainer.h
+ filecontainerv2.cpp filecontainerv2.h
+ filepath.cpp filepath.h
+ filepathcache.h
+ filepathcaching.cpp filepathcaching.h
+ filepathcachingfwd.h
+ filepathcachinginterface.h
+ filepathexceptions.h
+ filepathid.cpp filepathid.h
+ filepathstorage.h
+ filepathstoragesources.h
+ filepathstoragesqlitestatementfactory.h
+ filepathview.h
+ fixitcontainer.cpp fixitcontainer.h
+ followsymbolmessage.cpp followsymbolmessage.h
+ generatedfiles.cpp generatedfiles.h
+ generatedfilesinterface.h
+ idpaths.h
+ includesearchpath.h
+ ipcclientinterface.h
+ ipcclientprovider.h
+ ipcinterface.h
+ ipcserverinterface.h
+ lineprefixer.cpp lineprefixer.h
+ messageenvelop.cpp messageenvelop.h
+ modifiedtimechecker.h
+ modifiedtimecheckerinterface.h
+ nativefilepath.h
+ pchmanagerclientinterface.cpp pchmanagerclientinterface.h
+ pchmanagerclientproxy.cpp pchmanagerclientproxy.h
+ pchmanagerserverinterface.cpp pchmanagerserverinterface.h
+ pchmanagerserverproxy.cpp pchmanagerserverproxy.h
+ pchpaths.h
+ precompiledheadersupdatedmessage.cpp precompiledheadersupdatedmessage.h
+ processcreator.cpp processcreator.h
+ processexception.cpp processexception.h
+ processhandle.h
+ processstartedevent.cpp processstartedevent.h
+ progresscounter.h
+ progressmessage.h
+ projectmanagementserverinterface.h
+ projectpartartefact.cpp projectpartartefact.h
+ projectpartcontainer.cpp projectpartcontainer.h
+ projectpartid.h
+ projectpartpch.cpp projectpartpch.h
+ projectpartsstorage.h
+ projectpartsstorageinterface.h
+ readmessageblock.cpp readmessageblock.h
+ refactoringclientinterface.cpp refactoringclientinterface.h
+ refactoringclientproxy.cpp refactoringclientproxy.h
+ refactoringdatabaseinitializer.h
+ refactoringserverinterface.cpp refactoringserverinterface.h
+ refactoringserverproxy.cpp refactoringserverproxy.h
+ referencesmessage.cpp referencesmessage.h
+ removegeneratedfilesmessage.cpp removegeneratedfilesmessage.h
+ removeprojectpartsmessage.h
+ requestannotationsmessage.cpp requestannotationsmessage.h
+ requestcompletionsmessage.cpp requestcompletionsmessage.h
+ requestfollowsymbolmessage.cpp requestfollowsymbolmessage.h
+ requestreferencesmessage.cpp requestreferencesmessage.h
+ requestsourcelocationforrenamingmessage.cpp requestsourcelocationforrenamingmessage.h
+ requestsourcerangesanddiagnosticsforquerymessage.cpp requestsourcerangesanddiagnosticsforquerymessage.h
+ requestsourcerangesforquerymessage.cpp requestsourcerangesforquerymessage.h
+ requesttooltipmessage.cpp requesttooltipmessage.h
+ sourceentry.h
+ sourcelocationcontainer.cpp sourcelocationcontainer.h
+ sourcelocationcontainerv2.cpp sourcelocationcontainerv2.h
+ sourcelocationscontainer.cpp sourcelocationscontainer.h
+ sourcelocationsforrenamingmessage.cpp sourcelocationsforrenamingmessage.h
+ sourcerangecontainer.cpp sourcerangecontainer.h
+ sourcerangecontainerv2.cpp sourcerangecontainerv2.h
+ sourcerangesanddiagnosticsforquerymessage.cpp sourcerangesanddiagnosticsforquerymessage.h
+ sourcerangescontainer.cpp sourcerangescontainer.h
+ sourcerangesforquerymessage.cpp sourcerangesforquerymessage.h
+ sourcerangewithtextcontainer.cpp sourcerangewithtextcontainer.h
+ stringcache.h
+ stringcachealgorithms.h
+ stringcachefwd.h
+ tokeninfocontainer.cpp tokeninfocontainer.h
+ tooltipinfo.cpp tooltipinfo.h
+ tooltipmessage.cpp tooltipmessage.h
+ unsavedfilesremovedmessage.cpp unsavedfilesremovedmessage.h
+ unsavedfilesupdatedmessage.cpp unsavedfilesupdatedmessage.h
+ updategeneratedfilesmessage.cpp updategeneratedfilesmessage.h
+ updateprojectpartsmessage.cpp updateprojectpartsmessage.h
+ writemessageblock.cpp writemessageblock.h
+)
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index 0668382803..df537f5848 100644
--- a/src/libs/clangsupport/clangsupport-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -110,6 +110,7 @@ HEADERS += \
$$PWD/clangsupportexceptions.h \
$$PWD/completionsmessage.h \
$$PWD/executeinloop.h \
+ $$PWD/pchpaths.h \
$$PWD/projectpartid.h \
$$PWD/projectpartsstorage.h \
$$PWD/projectpartsstorageinterface.h \
@@ -203,7 +204,6 @@ HEADERS += \
$$PWD/nativefilepath.h \
$$PWD/filepathview.h \
$$PWD/compilermacro.h \
- $$PWD/projectpartpchproviderinterface.h \
$$PWD/updategeneratedfilesmessage.h \
$$PWD/removegeneratedfilesmessage.h \
$$PWD/generatedfiles.h \
@@ -213,6 +213,10 @@ HEADERS += \
$$PWD/includesearchpath.h \
$$PWD/commandlinebuilder.h \
$$PWD/projectpartartefact.h \
- $$PWD/projectpartcontainer.h
+ $$PWD/projectpartcontainer.h \
+ $$PWD/sourceentry.h \
+ $$PWD/modifiedtimecheckerinterface.h \
+ $$PWD/environment.h \
+ $$PWD/modifiedtimechecker.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangsupport/commandlinebuilder.h b/src/libs/clangsupport/commandlinebuilder.h
index 9de1da68d3..dedcf1c518 100644
--- a/src/libs/clangsupport/commandlinebuilder.h
+++ b/src/libs/clangsupport/commandlinebuilder.h
@@ -33,6 +33,9 @@
#include <utils/smallstringvector.h>
#include <utils/cpplanguage_details.h>
+#include <QCoreApplication>
+#include <QDir>
+
namespace ClangBackEnd {
enum class InputFileType : unsigned char { Header, Source };
@@ -46,7 +49,8 @@ public:
InputFileType sourceType = InputFileType::Header,
FilePathView sourcePath = {},
FilePathView outputPath = {},
- FilePathView includePchPath = {})
+ FilePathView includePchPath = {},
+ NativeFilePathView preIncludeSearchPath = {})
{
commandLine.reserve(1024);
@@ -58,6 +62,7 @@ public:
addLanguageVersion(projectInfo);
addNoStdIncAndNoStdLibInc(projectInfo.language);
addCompilerMacros(projectInfo.compilerMacros);
+ addPreIncludeSearchPath(preIncludeSearchPath);
addProjectIncludeSearchPaths(
sortedIncludeSearchPaths(projectInfo.projectIncludeSearchPaths));
addSystemAndBuiltInIncludeSearchPaths(
@@ -97,9 +102,12 @@ public:
if (projectInfo.languageExtension && Utils::LanguageExtension::ObjectiveC)
return sourceType == InputFileType::Header ? "objective-c++-header"
: "objective-c++";
+ return sourceType == InputFileType::Header ? "c++-header" : "c++";
+ case Utils::Language::None:
+ return "none";
}
- return sourceType == InputFileType::Header ? "c++-header" : "c++";
+ return "none";
}
void addLanguage(const ProjectInfo &projectInfo, InputFileType sourceType)
@@ -131,6 +139,8 @@ public:
return "-std=c++17";
case Utils::LanguageVersion::CXX2a:
return "-std=c++2a";
+ case Utils::LanguageVersion::None:
+ return "";
}
return "-std=c++2a";
@@ -159,6 +169,8 @@ public:
return "-std=gnu++17";
case Utils::LanguageVersion::CXX2a:
return "-std=gnu++2a";
+ case Utils::LanguageVersion::None:
+ return "";
}
return "-std=gnu++2a";
@@ -209,6 +221,14 @@ public:
commandLine.emplace_back(Utils::SmallString{"-D", macro.key, "=", macro.value});
}
+ void addPreIncludeSearchPath(NativeFilePathView preIncludeSearchPath)
+ {
+ if (!preIncludeSearchPath.empty()) {
+ commandLine.emplace_back("-isystem");
+ commandLine.emplace_back(preIncludeSearchPath);
+ }
+ }
+
IncludeSearchPaths sortedIncludeSearchPaths(const IncludeSearchPaths &unsortedPaths)
{
IncludeSearchPaths paths = unsortedPaths;
diff --git a/src/libs/clangsupport/connectionclient.cpp b/src/libs/clangsupport/connectionclient.cpp
index bdbedab5c0..b3025baeea 100644
--- a/src/libs/clangsupport/connectionclient.cpp
+++ b/src/libs/clangsupport/connectionclient.cpp
@@ -325,7 +325,7 @@ void ConnectionClient::connectStandardOutputAndError(QProcess *process) const
void ConnectionClient::connectLocalSocketError() const
{
connect(m_localSocket,
- static_cast<void (QLocalSocket::*)(QLocalSocket::LocalSocketError)>(&QLocalSocket::error),
+ QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error),
this,
&ConnectionClient::printLocalSocketError);
}
diff --git a/src/libs/clangsupport/connectionserver.h b/src/libs/clangsupport/connectionserver.h
index 8f13e631c5..b60083c4f8 100644
--- a/src/libs/clangsupport/connectionserver.h
+++ b/src/libs/clangsupport/connectionserver.h
@@ -72,11 +72,17 @@ public:
}
+ void ensureAliveMessageIsSent()
+ {
+ if (m_aliveTimer.remainingTime() == 0)
+ sendAliveMessage();
+ }
+
private:
void connectToLocalServer(const QString &connectionName)
{
QObject::connect(&m_localSocket,
- static_cast<void (QLocalSocket::*)(QLocalSocket::LocalSocketError)>(&QLocalSocket::error),
+ QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error),
[&] (QLocalSocket::LocalSocketError) {
qWarning() << "ConnectionServer error:" << m_localSocket.errorString() << connectionName;
});
diff --git a/src/libs/clangsupport/ipcserverinterface.cpp b/src/libs/clangsupport/environment.h
index fbc92de52e..ffa4d907cc 100644
--- a/src/libs/clangsupport/ipcserverinterface.cpp
+++ b/src/libs/clangsupport/environment.h
@@ -23,9 +23,25 @@
**
****************************************************************************/
-#include "ipcserverinterface.h"
+#pragma once
+
+#include <nativefilepath.h>
namespace ClangBackEnd {
+class Environment
+{
+public:
+ Environment() = default;
+ Environment(const Environment &) = delete;
+ Environment &operator=(const Environment &) = delete;
+
+ virtual Utils::PathString pchBuildDirectory() const = 0;
+ virtual uint hardwareConcurrency() const = 0;
+ virtual NativeFilePathView preIncludeSearchPath() const = 0;
+
+protected:
+ ~Environment() = default;
+};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/executeinloop.h b/src/libs/clangsupport/executeinloop.h
index 9c3eddeb4d..3642c3ccd3 100644
--- a/src/libs/clangsupport/executeinloop.h
+++ b/src/libs/clangsupport/executeinloop.h
@@ -29,38 +29,6 @@
#include <QCoreApplication>
#include <QThread>
-#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
-template<typename CallableType>
-class CallableEvent : public QEvent
-{
-public:
- using Callable = std::decay_t<CallableType>;
- CallableEvent(Callable &&callable)
- : QEvent(QEvent::None)
- , callable(std::move(callable))
- {}
- CallableEvent(const Callable &callable)
- : QEvent(QEvent::None)
- , callable(callable)
- {}
-
- ~CallableEvent() { callable(); }
-
-public:
- Callable callable;
-};
-
-template<typename Callable>
-void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance())
-{
- if (QThread *thread = qobject_cast<QThread *>(object))
- object = QAbstractEventDispatcher::instance(thread);
-
- QCoreApplication::postEvent(object,
- new CallableEvent<Callable>(std::forward<Callable>(callable)),
- Qt::HighEventPriority);
-}
-#else
template<typename Callable>
void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance())
{
@@ -69,4 +37,3 @@ void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::inst
QMetaObject::invokeMethod(object, std::forward<Callable>(callable));
}
-#endif
diff --git a/src/libs/clangsupport/generatedfiles.cpp b/src/libs/clangsupport/generatedfiles.cpp
index f4863baba5..644137886b 100644
--- a/src/libs/clangsupport/generatedfiles.cpp
+++ b/src/libs/clangsupport/generatedfiles.cpp
@@ -25,6 +25,8 @@
#include "generatedfiles.h"
+#include <utils/algorithm.h>
+
namespace ClangBackEnd {
void GeneratedFiles::update(V2::FileContainers &&fileContainers)
@@ -32,16 +34,16 @@ void GeneratedFiles::update(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;
};
- std::set_union(std::make_move_iterator(fileContainers.begin()),
- std::make_move_iterator(fileContainers.end()),
- std::make_move_iterator(m_fileContainers.begin()),
- std::make_move_iterator(m_fileContainers.end()),
- std::back_inserter(unionFileContainers),
- compare);
+ Utils::set_union(std::make_move_iterator(fileContainers.begin()),
+ std::make_move_iterator(fileContainers.end()),
+ std::make_move_iterator(m_fileContainers.begin()),
+ std::make_move_iterator(m_fileContainers.end()),
+ std::back_inserter(unionFileContainers),
+ compare);
m_fileContainers = std::move(unionFileContainers);
}
@@ -55,12 +57,12 @@ void GeneratedFiles::update(const V2::FileContainers &fileContainers)
return first.filePath < second.filePath;
};
- std::set_union(fileContainers.begin(),
- fileContainers.end(),
- std::make_move_iterator(m_fileContainers.begin()),
- std::make_move_iterator(m_fileContainers.end()),
- std::back_inserter(unionFileContainers),
- compare);
+ Utils::set_union(fileContainers.begin(),
+ fileContainers.end(),
+ std::make_move_iterator(m_fileContainers.begin()),
+ std::make_move_iterator(m_fileContainers.end()),
+ std::back_inserter(unionFileContainers),
+ compare);
m_fileContainers = std::move(unionFileContainers);
}
diff --git a/src/libs/clangsupport/modifiedtimechecker.h b/src/libs/clangsupport/modifiedtimechecker.h
new file mode 100644
index 0000000000..c9b62c4673
--- /dev/null
+++ b/src/libs/clangsupport/modifiedtimechecker.h
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "filepathcachinginterface.h"
+#include "modifiedtimecheckerinterface.h"
+
+#include <algorithm>
+#include <iterator>
+
+namespace ClangBackEnd {
+template<typename SourceEntries = ::ClangBackEnd::SourceEntries>
+class ModifiedTimeChecker final : public ModifiedTimeCheckerInterface<SourceEntries>
+{
+ using SourceEntry = typename SourceEntries::value_type;
+
+public:
+ using GetModifiedTime = std::function<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>;
+ ModifiedTimeChecker(GetModifiedTime &getModifiedTime, FilePathCachingInterface &filePathCache)
+ : m_getModifiedTime(getModifiedTime)
+ , m_filePathCache(filePathCache)
+ {}
+
+ bool isUpToDate(const SourceEntries &sourceEntries) const
+ {
+ if (sourceEntries.empty())
+ return false;
+
+ updateCurrentSourceTimeStamps(sourceEntries);
+
+ return compareEntries(sourceEntries);
+ }
+
+ void pathsChanged(const FilePathIds &filePathIds)
+ {
+ using SourceTimeStampReferences = std::vector<std::reference_wrapper<SourceTimeStamp>>;
+
+ SourceTimeStampReferences timeStampsToUpdate;
+ timeStampsToUpdate.reserve(filePathIds.size());
+
+ std::set_intersection(m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end(),
+ filePathIds.begin(),
+ filePathIds.end(),
+ std::back_inserter(timeStampsToUpdate));
+
+ for (SourceTimeStamp &sourceTimeStamp : timeStampsToUpdate) {
+ sourceTimeStamp.timeStamp = m_getModifiedTime(
+ m_filePathCache.filePath(sourceTimeStamp.sourceId));
+ }
+ }
+
+private:
+ bool compareEntries(const SourceEntries &sourceEntries) const
+ {
+ class CompareSourceId
+ {
+ public:
+ bool operator()(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+ };
+
+ SourceTimeStamps currentSourceTimeStamp;
+ currentSourceTimeStamp.reserve(sourceEntries.size());
+ std::set_intersection(m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end(),
+ sourceEntries.begin(),
+ sourceEntries.end(),
+ std::back_inserter(currentSourceTimeStamp),
+ CompareSourceId{});
+
+ class CompareTime
+ {
+ public:
+ bool operator()(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.timeStamp <= second.timeStamp;
+ }
+
+ bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second)
+ {
+ return first.timeStamp <= second.timeStamp;
+ }
+
+ bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second)
+ {
+ return first.timeStamp <= second.timeStamp;
+ }
+
+ bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second)
+ {
+ return first.timeStamp <= second.timeStamp;
+ }
+ };
+
+ return std::lexicographical_compare(currentSourceTimeStamp.begin(),
+ currentSourceTimeStamp.end(),
+ sourceEntries.begin(),
+ sourceEntries.end(),
+ CompareTime{});
+ }
+
+ void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const
+ {
+ SourceTimeStamps sourceTimeStamps = newSourceTimeStamps(sourceEntries);
+
+ for (SourceTimeStamp &newSourceTimeStamp : sourceTimeStamps) {
+ newSourceTimeStamp.timeStamp = m_getModifiedTime(
+ m_filePathCache.filePath(newSourceTimeStamp.sourceId));
+ }
+
+ auto split = sourceTimeStamps.insert(sourceTimeStamps.end(),
+ m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end());
+ std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end());
+
+ m_currentSourceTimeStamps = sourceTimeStamps;
+ }
+
+ SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const
+ {
+ SourceEntries newSourceEntries;
+ newSourceEntries.reserve(sourceEntries.size());
+
+ class CompareSourceId
+ {
+ public:
+ bool operator()(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+ };
+
+ std::set_difference(sourceEntries.begin(),
+ sourceEntries.end(),
+ m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end(),
+ std::back_inserter(newSourceEntries),
+ CompareSourceId{});
+
+ SourceTimeStamps newTimeStamps;
+ newTimeStamps.reserve(newSourceEntries.size());
+
+ std::transform(newSourceEntries.begin(),
+ newSourceEntries.end(),
+ std::back_inserter(newTimeStamps),
+ [](SourceEntry entry) {
+ return SourceTimeStamp{entry.sourceId, {}};
+ });
+
+ return newTimeStamps;
+ }
+
+private:
+ mutable SourceTimeStamps m_currentSourceTimeStamps;
+ GetModifiedTime &m_getModifiedTime;
+ FilePathCachingInterface &m_filePathCache;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartpchproviderinterface.h b/src/libs/clangsupport/modifiedtimecheckerinterface.h
index 282e541cfd..a0e79b0701 100644
--- a/src/libs/clangsupport/projectpartpchproviderinterface.h
+++ b/src/libs/clangsupport/modifiedtimecheckerinterface.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -25,26 +25,23 @@
#pragma once
-#include "projectpartpch.h"
-
-#include <utils/optional.h>
+#include "sourceentry.h"
namespace ClangBackEnd {
-class ProjectPartPchProviderInterface
+template<typename SourceEntries = ::ClangBackEnd::SourceEntries>
+class ModifiedTimeCheckerInterface
{
public:
- ProjectPartPchProviderInterface() = default;
- ProjectPartPchProviderInterface(const ProjectPartPchProviderInterface &) = delete;
- ProjectPartPchProviderInterface &operator=(const ProjectPartPchProviderInterface &) = delete;
-
- virtual Utils::optional<ClangBackEnd::ProjectPartPch> projectPartPch(
- ClangBackEnd::ProjectPartId projectPartId) const = 0;
- virtual const ClangBackEnd::ProjectPartPchs &projectPartPchs() const = 0;
+ ModifiedTimeCheckerInterface() = default;
+ ModifiedTimeCheckerInterface(const ModifiedTimeCheckerInterface &) = delete;
+ ModifiedTimeCheckerInterface &operator=(const ModifiedTimeCheckerInterface &) = delete;
+ virtual bool isUpToDate(const SourceEntries &sourceEntries) const = 0;
protected:
- ~ProjectPartPchProviderInterface() = default;
+ ~ModifiedTimeCheckerInterface() = default;
};
} // namespace ClangBackEnd
+
diff --git a/src/libs/clangsupport/pchmanagerclientproxy.h b/src/libs/clangsupport/pchmanagerclientproxy.h
index 516b2e3a86..6dec4ecfca 100644
--- a/src/libs/clangsupport/pchmanagerclientproxy.h
+++ b/src/libs/clangsupport/pchmanagerclientproxy.h
@@ -42,9 +42,6 @@ public:
PchManagerClientProxy(const PchManagerClientProxy&) = delete;
const PchManagerClientProxy &operator=(const PchManagerClientProxy&) = delete;
- PchManagerClientProxy(PchManagerClientProxy &&other) = default;
- PchManagerClientProxy &operator=(PchManagerClientProxy &&other) = default;
-
void readMessages();
void alive() override;
diff --git a/src/libs/clangsupport/pchpaths.h b/src/libs/clangsupport/pchpaths.h
new file mode 100644
index 0000000000..048ec9da8d
--- /dev/null
+++ b/src/libs/clangsupport/pchpaths.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 "filepath.h"
+
+namespace ClangBackEnd {
+
+class PchPaths
+{
+public:
+ PchPaths() = default;
+ PchPaths(Utils::SmallStringView projectPchPath, Utils::SmallStringView systemPchPath)
+ : projectPchPath(FilePathView{projectPchPath})
+ , systemPchPath(FilePathView{systemPchPath})
+ {}
+
+ friend bool operator==(const PchPaths &first, const PchPaths &second)
+ {
+ return first.projectPchPath == second.projectPchPath
+ && first.systemPchPath == second.systemPchPath;
+ }
+
+public:
+ FilePath projectPchPath;
+ FilePath systemPchPath;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/precompiledheadersupdatedmessage.h b/src/libs/clangsupport/precompiledheadersupdatedmessage.h
index 5a21b995df..5bd24dcd49 100644
--- a/src/libs/clangsupport/precompiledheadersupdatedmessage.h
+++ b/src/libs/clangsupport/precompiledheadersupdatedmessage.h
@@ -25,7 +25,10 @@
#pragma once
-#include "projectpartpch.h"
+#include "clangsupport_global.h"
+#include "projectpartid.h"
+
+#include <utils/smallstringio.h>
namespace ClangBackEnd {
@@ -33,25 +36,26 @@ class PrecompiledHeadersUpdatedMessage
{
public:
PrecompiledHeadersUpdatedMessage() = default;
- PrecompiledHeadersUpdatedMessage(std::vector<ProjectPartPch> &&projectPartPchs)
- : projectPartPchs(std::move(projectPartPchs))
- {}
-
- ProjectPartPchs takeProjectPartPchs() const
+ PrecompiledHeadersUpdatedMessage(ProjectPartId projectPartId)
{
- return std::move(projectPartPchs);
+ projectPartIds.push_back(projectPartId);
}
+ PrecompiledHeadersUpdatedMessage(ProjectPartIds &&projectPartIds)
+ : projectPartIds(std::move(projectPartIds))
+ {}
+
+ ProjectPartIds takeProjectPartIds() const { return std::move(projectPartIds); }
friend QDataStream &operator<<(QDataStream &out, const PrecompiledHeadersUpdatedMessage &message)
{
- out << message.projectPartPchs;
+ out << message.projectPartIds;
return out;
}
friend QDataStream &operator>>(QDataStream &in, PrecompiledHeadersUpdatedMessage &message)
{
- in >> message.projectPartPchs;
+ in >> message.projectPartIds;
return in;
}
@@ -59,16 +63,13 @@ public:
friend bool operator==(const PrecompiledHeadersUpdatedMessage &first,
const PrecompiledHeadersUpdatedMessage &second)
{
- return first.projectPartPchs == second.projectPartPchs;
+ return first.projectPartIds == second.projectPartIds;
}
- PrecompiledHeadersUpdatedMessage clone() const
- {
- return PrecompiledHeadersUpdatedMessage(Utils::clone(projectPartPchs));
- }
+ PrecompiledHeadersUpdatedMessage clone() const { return *this; }
public:
- std::vector<ProjectPartPch> projectPartPchs;
+ ProjectPartIds projectPartIds;
};
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const PrecompiledHeadersUpdatedMessage &message);
diff --git a/src/libs/clangsupport/projectpartartefact.cpp b/src/libs/clangsupport/projectpartartefact.cpp
index 7623f38796..56551693e1 100644
--- a/src/libs/clangsupport/projectpartartefact.cpp
+++ b/src/libs/clangsupport/projectpartartefact.cpp
@@ -33,8 +33,6 @@
namespace ClangBackEnd {
-
-
Utils::SmallStringVector ProjectPartArtefact::toStringVector(Utils::SmallStringView jsonText)
{
if (jsonText.isEmpty())
diff --git a/src/libs/clangsupport/projectpartartefact.h b/src/libs/clangsupport/projectpartartefact.h
index ac8c44a891..0d9bcf5c39 100644
--- a/src/libs/clangsupport/projectpartartefact.h
+++ b/src/libs/clangsupport/projectpartartefact.h
@@ -113,8 +113,8 @@ public:
CompilerMacros compilerMacros;
IncludeSearchPaths systemIncludeSearchPaths;
IncludeSearchPaths projectIncludeSearchPaths;
- Utils::Language language = Utils::Language::Cxx;
- Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98;
+ Utils::Language language = Utils::Language::None;
+ Utils::LanguageVersion languageVersion = Utils::LanguageVersion::None;
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None;
};
diff --git a/src/libs/clangsupport/projectpartcontainer.h b/src/libs/clangsupport/projectpartcontainer.h
index f1c64bd237..b2133dcaa2 100644
--- a/src/libs/clangsupport/projectpartcontainer.h
+++ b/src/libs/clangsupport/projectpartcontainer.h
@@ -147,7 +147,8 @@ public:
first.sourcePathIds,
first.language,
first.languageVersion,
- first.languageExtension)
+ first.languageExtension,
+ first.hasPrecompiledHeader)
< std::tie(second.projectPartId,
second.toolChainArguments,
second.compilerMacros,
@@ -157,7 +158,8 @@ public:
second.sourcePathIds,
second.language,
second.languageVersion,
- second.languageExtension);
+ second.languageExtension,
+ second.hasPrecompiledHeader);
}
ProjectPartContainer clone() const
@@ -169,6 +171,7 @@ public:
FilePathIds headerPathIds;
FilePathIds sourcePathIds;
bool updateIsDeferred = false;
+ bool hasPrecompiledHeader = true;
};
using ProjectPartContainerReference = std::reference_wrapper<ProjectPartContainer>;
diff --git a/src/libs/clangsupport/projectpartid.h b/src/libs/clangsupport/projectpartid.h
index c372682baf..fc5f659605 100644
--- a/src/libs/clangsupport/projectpartid.h
+++ b/src/libs/clangsupport/projectpartid.h
@@ -54,7 +54,7 @@ public:
return first.projectPathId < second.projectPathId;
}
- friend QDataStream &operator<<(QDataStream &out, const ProjectPartId &projectPathId)
+ friend QDataStream &operator<<(QDataStream &out, ProjectPartId projectPathId)
{
out << projectPathId.projectPathId;
diff --git a/src/libs/clangsupport/projectpartpch.cpp b/src/libs/clangsupport/projectpartpch.cpp
index aac672441c..9c870ac572 100644
--- a/src/libs/clangsupport/projectpartpch.cpp
+++ b/src/libs/clangsupport/projectpartpch.cpp
@@ -29,8 +29,7 @@ namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const ProjectPartPch &projectPartPch)
{
- debug.nospace() << "FileContainer(" << projectPartPch.projectPartId.projectPathId << ", "
- << projectPartPch.pchPath << ")";
+ debug.nospace() << "FileContainer(" << projectPartPch.projectPartId.projectPathId << ")";
return debug;
}
diff --git a/src/libs/clangsupport/projectpartpch.h b/src/libs/clangsupport/projectpartpch.h
index c471b46b16..213247ae42 100644
--- a/src/libs/clangsupport/projectpartpch.h
+++ b/src/libs/clangsupport/projectpartpch.h
@@ -74,8 +74,7 @@ public:
friend bool operator==(const ProjectPartPch &first,
const ProjectPartPch &second)
{
- return first.projectPartId == second.projectPartId
- && first.pchPath == second.pchPath;
+ return first.projectPartId == second.projectPartId && first.pchPath == second.pchPath;
}
ProjectPartPch clone() const
diff --git a/src/libs/clangsupport/projectpartsstorage.h b/src/libs/clangsupport/projectpartsstorage.h
index c91291bca2..e71bb0d51e 100644
--- a/src/libs/clangsupport/projectpartsstorage.h
+++ b/src/libs/clangsupport/projectpartsstorage.h
@@ -74,6 +74,14 @@ public:
.template values<FilePathId>(1024, projectPartId.projectPathId);
}
+ bool hasPrecompiledHeader(ProjectPartId projectPartId) const
+ {
+ auto value = fetchProjectPrecompiledHeaderPathStatement.template value<Utils::SmallString>(
+ projectPartId.projectPathId);
+
+ return value && value->hasContent();
+ }
+
ProjectPartContainers fetchProjectParts(const ProjectPartIds &projectPartIds) const override
{
try {
@@ -88,6 +96,7 @@ public:
if (value) {
value->headerPathIds = fetchHeaders(projectPartId);
value->sourcePathIds = fetchSources(projectPartId);
+ value->hasPrecompiledHeader = hasPrecompiledHeader(projectPartId);
projectParts.push_back(*std::move(value));
}
}
@@ -125,7 +134,7 @@ public:
}
}
- Utils::PathString fetchProjectPartName(ProjectPartId projectPartId) const
+ Utils::PathString fetchProjectPartName(ProjectPartId projectPartId) const override
{
try {
Sqlite::DeferredTransaction transaction{database};
@@ -236,6 +245,22 @@ public:
return statement.template value<ProjectPartArtefact, 8>(projectPartId.projectPathId);
}
+ void resetIndexingTimeStamps(const ProjectPartContainers &projectsParts) override
+ {
+ try {
+ Sqlite::ImmediateTransaction transaction{database};
+
+ for (const ProjectPartContainer &projectPart : projectsParts) {
+ for (FilePathId sourcePathId : projectPart.sourcePathIds)
+ resetDependentIndexingTimeStampsStatement.write(sourcePathId.filePathId);
+ }
+
+ transaction.commit();
+ } catch (const Sqlite::StatementIsBusy &) {
+ resetIndexingTimeStamps(projectsParts);
+ }
+ }
+
Sqlite::TransactionInterface &transactionBackend() override { return database; }
static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
@@ -332,5 +357,13 @@ public:
"SELECT sourceId FROM projectPartsHeaders WHERE projectPartId = ?", 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)",
+ database};
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartsstorageinterface.h b/src/libs/clangsupport/projectpartsstorageinterface.h
index 1127f70b1f..2d0675e657 100644
--- a/src/libs/clangsupport/projectpartsstorageinterface.h
+++ b/src/libs/clangsupport/projectpartsstorageinterface.h
@@ -63,6 +63,7 @@ public:
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const = 0;
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
ProjectPartId projectPartId) const = 0;
+ virtual void resetIndexingTimeStamps(const ProjectPartContainers &projectsParts) = 0;
virtual Sqlite::TransactionInterface &transactionBackend() = 0;
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
index efca925413..a7058d3204 100644
--- a/src/libs/clangsupport/refactoringdatabaseinitializer.h
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -177,6 +177,7 @@ public:
Sqlite::Contraint::PrimaryKey);
table.addColumn("size", Sqlite::ColumnType::Integer);
table.addColumn("lastModified", Sqlite::ColumnType::Integer);
+ table.addColumn("indexingTimeStamp", Sqlite::ColumnType::Integer);
table.initialize(database);
}
@@ -188,6 +189,7 @@ public:
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
const Sqlite::Column &dependencySourceIdColumn = table.addColumn("dependencySourceId", Sqlite::ColumnType::Integer);
table.addIndex({sourceIdColumn, dependencySourceIdColumn});
+ table.addIndex({dependencySourceIdColumn, sourceIdColumn});
table.initialize(database);
}
diff --git a/src/libs/clangsupport/sourceentry.h b/src/libs/clangsupport/sourceentry.h
new file mode 100644
index 0000000000..c593f1fcd3
--- /dev/null
+++ b/src/libs/clangsupport/sourceentry.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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 <filepathid.h>
+
+#include <vector>
+
+namespace ClangBackEnd {
+
+enum class SourceType : unsigned char {
+ TopProjectInclude,
+ TopSystemInclude,
+ UserInclude,
+ ProjectInclude,
+ SystemInclude,
+ Source
+};
+
+enum class HasMissingIncludes : unsigned char { No, Yes };
+
+class TimeStamp
+{
+ using int64 = long long;
+public:
+ TimeStamp() = default;
+ TimeStamp(int64 value)
+ : value(value)
+ {}
+
+ operator int64() const
+ {
+ return value;
+ }
+
+ int64 value = -1;
+};
+
+class SourceTimeStamp
+{
+ using int64 = long long;
+public:
+ SourceTimeStamp(int sourceId, int64 lastModified)
+ : timeStamp(lastModified)
+ , sourceId(sourceId)
+ {}
+
+ SourceTimeStamp(FilePathId sourceId, TimeStamp lastModified)
+ : timeStamp(lastModified)
+ , sourceId(sourceId)
+ {}
+
+ friend bool operator<(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ friend bool operator<(SourceTimeStamp first, FilePathId second)
+ {
+ return first.sourceId < second;
+ }
+
+ friend bool operator<(FilePathId first, SourceTimeStamp second)
+ {
+ return first < second.sourceId;
+ }
+
+ friend bool operator==(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.sourceId == second.sourceId && first.timeStamp == second.timeStamp;
+ }
+
+ friend bool operator!=(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return !(first == second);
+ }
+
+public:
+ TimeStamp timeStamp;
+ FilePathId sourceId;
+};
+
+using SourceTimeStamps = std::vector<SourceTimeStamp>;
+
+class SourceEntry
+{
+ using int64 = long long;
+
+public:
+ SourceEntry(int sourceId, int64 timeStamp, int sourceType, int hasMissingIncludes)
+ : timeStamp(timeStamp)
+ , sourceId(sourceId)
+ , sourceType(static_cast<SourceType>(sourceType))
+ , hasMissingIncludes(static_cast<HasMissingIncludes>(hasMissingIncludes))
+ {}
+
+ SourceEntry(FilePathId sourceId,
+ SourceType sourceType,
+ TimeStamp timeStamp,
+ HasMissingIncludes hasMissingIncludes = HasMissingIncludes::No)
+ : timeStamp(timeStamp)
+ , sourceId(sourceId)
+ , sourceType(sourceType)
+ , hasMissingIncludes(hasMissingIncludes)
+ {}
+
+ friend bool operator<(SourceEntry first, SourceEntry second) {
+ return first.sourceId < second.sourceId;
+ }
+
+ friend bool operator==(SourceEntry first, SourceEntry second)
+ {
+ return first.sourceId == second.sourceId && first.sourceType == second.sourceType
+ && first.timeStamp == second.timeStamp;
+ }
+
+ friend bool operator!=(SourceEntry first, SourceEntry second) { return !(first == second); }
+
+public:
+ TimeStamp timeStamp;
+ FilePathId sourceId;
+ SourceType sourceType = SourceType::UserInclude;
+ HasMissingIncludes hasMissingIncludes = HasMissingIncludes::No;
+};
+
+using SourceEntries = std::vector<SourceEntry>;
+using SourceEntryReference = std::reference_wrapper<SourceEntry>;
+using SourceEntryReferences = std::vector<SourceEntryReference>;
+} // namespace ClangBackEnd
diff --git a/src/libs/cplusplus/CMakeLists.txt b/src/libs/cplusplus/CMakeLists.txt
new file mode 100644
index 0000000000..593d809394
--- /dev/null
+++ b/src/libs/cplusplus/CMakeLists.txt
@@ -0,0 +1,44 @@
+# TODO: Support static build, currently being done with CPLUSPLUS_BUILD_STATIC_LIB
+# -- if really needed that is.
+# TODO: Make Qt5::Gui optional -- if really needed that is.
+
+add_qtc_library(CPlusPlus
+ DEPENDS Utils
+ DEFINES CPLUSPLUS_BUILD_LIB
+ PUBLIC_DEPENDS 3rd_cplusplus Qt5::Concurrent Qt5::Gui
+ PUBLIC_INCLUDES "${CMAKE_SOURCE_DIR}/src/libs/3rdparty"
+ SOURCES
+ ASTParent.cpp ASTParent.h
+ ASTPath.cpp ASTPath.h
+ AlreadyConsideredClassContainer.h
+ BackwardsScanner.cpp BackwardsScanner.h
+ CppDocument.cpp CppDocument.h
+ CppRewriter.cpp CppRewriter.h
+ DependencyTable.cpp DependencyTable.h
+ DeprecatedGenTemplateInstance.cpp DeprecatedGenTemplateInstance.h
+ ExpressionUnderCursor.cpp ExpressionUnderCursor.h
+ FastPreprocessor.cpp FastPreprocessor.h
+ FindUsages.cpp FindUsages.h
+ Icons.cpp Icons.h
+ LookupContext.cpp LookupContext.h
+ LookupItem.cpp LookupItem.h
+ Macro.cpp Macro.h
+ MatchingText.cpp MatchingText.h
+ NamePrettyPrinter.cpp NamePrettyPrinter.h
+ Overview.cpp Overview.h
+ PPToken.cpp PPToken.h
+ PreprocessorClient.cpp PreprocessorClient.h
+ PreprocessorEnvironment.cpp PreprocessorEnvironment.h
+ ResolveExpression.cpp ResolveExpression.h
+ SimpleLexer.cpp SimpleLexer.h
+ SnapshotSymbolVisitor.cpp SnapshotSymbolVisitor.h
+ SymbolNameVisitor.cpp SymbolNameVisitor.h
+ TypeOfExpression.cpp TypeOfExpression.h
+ TypePrettyPrinter.cpp TypePrettyPrinter.h
+ cppmodelmanagerbase.cpp cppmodelmanagerbase.h
+ findcdbbreakpoint.cpp findcdbbreakpoint.h
+ pp-cctype.h pp-engine.cpp
+ pp-engine.h pp-scanner.cpp
+ pp-scanner.h
+ pp.h
+)
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index d892948468..73cc06f26a 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -228,8 +228,7 @@ public:
if (fileName != doc->fileName())
return;
- QString message;
- message.vsprintf(format, ap);
+ const QString message = QString::vasprintf(format, ap);
#ifndef DO_NOT_DUMP_ALL_PARSER_ERRORS
{
@@ -756,17 +755,17 @@ bool Snapshot::isEmpty() const
return _documents.isEmpty();
}
-Snapshot::const_iterator Snapshot::find(const Utils::FileName &fileName) const
+Snapshot::const_iterator Snapshot::find(const Utils::FilePath &fileName) const
{
return _documents.find(fileName);
}
-void Snapshot::remove(const Utils::FileName &fileName)
+void Snapshot::remove(const Utils::FilePath &fileName)
{
_documents.remove(fileName);
}
-bool Snapshot::contains(const Utils::FileName &fileName) const
+bool Snapshot::contains(const Utils::FilePath &fileName) const
{
return _documents.contains(fileName);
}
@@ -774,7 +773,7 @@ bool Snapshot::contains(const Utils::FileName &fileName) const
void Snapshot::insert(Document::Ptr doc)
{
if (doc) {
- _documents.insert(Utils::FileName::fromString(doc->fileName()), doc);
+ _documents.insert(Utils::FilePath::fromString(doc->fileName()), doc);
m_deps.files.clear(); // Will trigger re-build when accessed.
}
}
@@ -794,7 +793,7 @@ static QList<Macro> macrosDefinedUntilLine(const QList<Macro> &macros, int line)
}
Document::Ptr Snapshot::preprocessedDocument(const QByteArray &source,
- const Utils::FileName &fileName,
+ const Utils::FilePath &fileName,
int withDefinedMacrosFromDocumentUntilLine) const
{
Document::Ptr newDoc = Document::create(fileName.toString());
@@ -858,7 +857,7 @@ QList<Snapshot::IncludeLocation> Snapshot::includeLocationsOfDocument(const QStr
return result;
}
-Utils::FileNameList Snapshot::filesDependingOn(const Utils::FileName &fileName) const
+Utils::FilePathList Snapshot::filesDependingOn(const Utils::FilePath &fileName) const
{
updateDependencyTable();
return m_deps.filesDependingOn(fileName);
@@ -887,7 +886,7 @@ void Snapshot::allIncludesForDocument_helper(const QString &fileName, QSet<QStri
}
}
-Document::Ptr Snapshot::document(const Utils::FileName &fileName) const
+Document::Ptr Snapshot::document(const Utils::FilePath &fileName) const
{
return _documents.value(fileName);
}
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index 006f17aba6..74205f1625 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -389,7 +389,7 @@ private:
class CPLUSPLUS_EXPORT Snapshot
{
- typedef QHash<Utils::FileName, Document::Ptr> Base;
+ typedef QHash<Utils::FilePath, Document::Ptr> Base;
public:
Snapshot();
@@ -403,36 +403,36 @@ public:
bool isEmpty() const;
void insert(Document::Ptr doc); // ### remove
- void remove(const Utils::FileName &fileName); // ### remove
+ void remove(const Utils::FilePath &fileName); // ### remove
void remove(const QString &fileName)
- { remove(Utils::FileName::fromString(fileName)); }
+ { remove(Utils::FilePath::fromString(fileName)); }
const_iterator begin() const { return _documents.begin(); }
const_iterator end() const { return _documents.end(); }
- bool contains(const Utils::FileName &fileName) const;
+ bool contains(const Utils::FilePath &fileName) const;
bool contains(const QString &fileName) const
- { return contains(Utils::FileName::fromString(fileName)); }
+ { return contains(Utils::FilePath::fromString(fileName)); }
- Document::Ptr document(const Utils::FileName &fileName) const;
+ Document::Ptr document(const Utils::FilePath &fileName) const;
Document::Ptr document(const QString &fileName) const
- { return document(Utils::FileName::fromString(fileName)); }
+ { return document(Utils::FilePath::fromString(fileName)); }
- const_iterator find(const Utils::FileName &fileName) const;
+ const_iterator find(const Utils::FilePath &fileName) const;
const_iterator find(const QString &fileName) const
- { return find(Utils::FileName::fromString(fileName)); }
+ { return find(Utils::FilePath::fromString(fileName)); }
Snapshot simplified(Document::Ptr doc) const;
Document::Ptr preprocessedDocument(const QByteArray &source,
- const Utils::FileName &fileName,
+ const Utils::FilePath &fileName,
int withDefinedMacrosFromDocumentUntilLine = -1) const;
Document::Ptr preprocessedDocument(const QByteArray &source,
const QString &fileName,
int withDefinedMacrosFromDocumentUntilLine = -1) const
{
return preprocessedDocument(source,
- Utils::FileName::fromString(fileName),
+ Utils::FilePath::fromString(fileName),
withDefinedMacrosFromDocumentUntilLine);
}
@@ -442,9 +442,9 @@ public:
QSet<QString> allIncludesForDocument(const QString &fileName) const;
QList<IncludeLocation> includeLocationsOfDocument(const QString &fileName) const;
- Utils::FileNameList filesDependingOn(const Utils::FileName &fileName) const;
- Utils::FileNameList filesDependingOn(const QString &fileName) const
- { return filesDependingOn(Utils::FileName::fromString(fileName)); }
+ Utils::FilePathList filesDependingOn(const Utils::FilePath &fileName) const;
+ Utils::FilePathList filesDependingOn(const QString &fileName) const
+ { return filesDependingOn(Utils::FilePath::fromString(fileName)); }
void updateDependencyTable() const;
bool operator==(const Snapshot &other) const;
diff --git a/src/libs/cplusplus/DependencyTable.cpp b/src/libs/cplusplus/DependencyTable.cpp
index f9c17c0b61..8ddc9801d0 100644
--- a/src/libs/cplusplus/DependencyTable.cpp
+++ b/src/libs/cplusplus/DependencyTable.cpp
@@ -29,9 +29,9 @@
using namespace CPlusPlus;
-Utils::FileNameList DependencyTable::filesDependingOn(const Utils::FileName &fileName) const
+Utils::FilePathList DependencyTable::filesDependingOn(const Utils::FilePath &fileName) const
{
- Utils::FileNameList deps;
+ Utils::FilePathList deps;
int index = fileIndex.value(fileName, -1);
if (index == -1)
@@ -66,14 +66,14 @@ void DependencyTable::build(const Snapshot &snapshot)
}
for (int i = 0; i < files.size(); ++i) {
- const Utils::FileName &fileName = files.at(i);
+ const Utils::FilePath &fileName = files.at(i);
if (Document::Ptr doc = snapshot.document(fileName)) {
QBitArray bitmap(files.size());
QList<int> directIncludes;
const QStringList documentIncludes = doc->includedFiles();
foreach (const QString &includedFile, documentIncludes) {
- int index = fileIndex.value(Utils::FileName::fromString(includedFile));
+ int index = fileIndex.value(Utils::FilePath::fromString(includedFile));
if (index == -1)
continue;
diff --git a/src/libs/cplusplus/DependencyTable.h b/src/libs/cplusplus/DependencyTable.h
index 508ae297c5..3e888c59db 100644
--- a/src/libs/cplusplus/DependencyTable.h
+++ b/src/libs/cplusplus/DependencyTable.h
@@ -44,10 +44,10 @@ class CPLUSPLUS_EXPORT DependencyTable
private:
friend class Snapshot;
void build(const Snapshot &snapshot);
- Utils::FileNameList filesDependingOn(const Utils::FileName &fileName) const;
+ Utils::FilePathList filesDependingOn(const Utils::FilePath &fileName) const;
- QVector<Utils::FileName> files;
- QHash<Utils::FileName, int> fileIndex;
+ QVector<Utils::FilePath> files;
+ QHash<Utils::FilePath, int> fileIndex;
QHash<int, QList<int> > includes;
QVector<QBitArray> includeMap;
};
diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index 173a6e2a5e..638fba451b 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -170,7 +170,7 @@ void FindUsages::reportResult(unsigned tokenIndex)
const int len = tk.utf16chars();
- const Usage u(Utils::FileName::fromString(_doc->fileName()), lineText, line, col, len);
+ const Usage u(Utils::FilePath::fromString(_doc->fileName()), lineText, line, col, len);
_usages.append(u);
_references.append(tokenIndex);
}
diff --git a/src/libs/cplusplus/FindUsages.h b/src/libs/cplusplus/FindUsages.h
index deed69276a..2b6880a55c 100644
--- a/src/libs/cplusplus/FindUsages.h
+++ b/src/libs/cplusplus/FindUsages.h
@@ -40,11 +40,11 @@ class CPLUSPLUS_EXPORT Usage
{
public:
Usage() = default;
- Usage(const Utils::FileName &path, const QString &lineText, int line, int col, int len)
+ Usage(const Utils::FilePath &path, const QString &lineText, int line, int col, int len)
: path(path), lineText(lineText), line(line), col(col), len(len) {}
public:
- Utils::FileName path;
+ Utils::FilePath path;
QString lineText;
int line = 0;
int col = 0;
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index c22d3fe89c..59440813a7 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -358,6 +358,32 @@ static bool isAfterRecordLikeDefinition(const BackwardsScanner &tokens, int inde
return false;
}
+static bool isControlFlowKeywordRequiringParentheses(const Token &token)
+{
+ return token.is(T_IF)
+ || token.is(T_WHILE)
+ || token.is(T_FOR)
+ || token.is(T_SWITCH)
+ || token.is(T_CATCH);
+}
+
+static bool isAfterControlFlow(const BackwardsScanner &tokens, int index)
+{
+ const Token &token = tokens[index];
+ if (token.is(T_DO) || token.is(T_ELSE) || token.is(T_TRY))
+ return true;
+
+ if (token.is(T_RPAREN)) {
+ const int startIndex = index + 1;
+ const int matchingBraceIndex = tokens.startOfMatchingBrace(startIndex);
+ if (matchingBraceIndex == startIndex)
+ return false; // No matching paren found.
+ return isControlFlowKeywordRequiringParentheses(tokens[matchingBraceIndex - 1]);
+ }
+
+ return false;
+}
+
static bool allowAutoClosingBrace(const QTextCursor &cursor,
MatchingText::IsNextBlockDeeperIndented isNextIndented)
{
@@ -370,6 +396,9 @@ static bool allowAutoClosingBrace(const QTextCursor &cursor,
if (tokens[index].isStringLiteral())
return false;
+ if (isAfterControlFlow(tokens, index))
+ return false;
+
if (isAfterNamespaceDefinition(tokens, index))
return false;
diff --git a/src/libs/extensionsystem/CMakeLists.txt b/src/libs/extensionsystem/CMakeLists.txt
new file mode 100644
index 0000000000..864c57c1ae
--- /dev/null
+++ b/src/libs/extensionsystem/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_qtc_library(ExtensionSystem
+ DEPENDS Aggregation Utils Qt5::Core Qt5::Widgets
+ PUBLIC_DEPENDS Qt5::Core
+ SOURCES
+ extensionsystem_global.h
+ invoker.cpp invoker.h
+ iplugin.cpp iplugin.h iplugin_p.h
+ optionsparser.cpp optionsparser.h
+ plugindetailsview.cpp plugindetailsview.h plugindetailsview.ui
+ pluginerroroverview.cpp pluginerroroverview.h pluginerroroverview.ui
+ pluginerrorview.cpp pluginerrorview.h pluginerrorview.ui
+ pluginmanager.cpp pluginmanager.h pluginmanager_p.h
+ pluginspec.cpp pluginspec.h pluginspec_p.h
+ pluginview.cpp pluginview.h
+ SKIP_AUTOMOC pluginmanager.cpp
+)
diff --git a/src/libs/extensionsystem/iplugin.cpp b/src/libs/extensionsystem/iplugin.cpp
index 76704be823..90b4e86672 100644
--- a/src/libs/extensionsystem/iplugin.cpp
+++ b/src/libs/extensionsystem/iplugin.cpp
@@ -193,7 +193,7 @@ IPlugin::~IPlugin()
}
/*!
- \fn QList<QObject *> IPlugin::createTestObjects() const
+ \fn QVector<QObject *> IPlugin::createTestObjects() const
Returns objects that are meant to be passed on to QTest::qExec().
@@ -201,9 +201,9 @@ IPlugin::~IPlugin()
The ownership of returned objects is transferred to caller.
*/
-QList<QObject *> IPlugin::createTestObjects() const
+QVector<QObject *> IPlugin::createTestObjects() const
{
- return QList<QObject *>();
+ return {};
}
/*!
diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h
index 4b14ecd92b..9b7489ce0f 100644
--- a/src/libs/extensionsystem/iplugin.h
+++ b/src/libs/extensionsystem/iplugin.h
@@ -60,7 +60,7 @@ public:
virtual QObject *remoteCommand(const QStringList & /* options */,
const QString & /* workingDirectory */,
const QStringList & /* arguments */) { return nullptr; }
- virtual QList<QObject *> createTestObjects() const;
+ virtual QVector<QObject *> createTestObjects() const;
PluginSpec *pluginSpec() const;
diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp
index c3daed5daa..22c45df31f 100644
--- a/src/libs/extensionsystem/optionsparser.cpp
+++ b/src/libs/extensionsystem/optionsparser.cpp
@@ -115,10 +115,10 @@ bool OptionsParser::checkForTestOptions()
if (m_currentArg == QLatin1String(TEST_OPTION)) {
if (nextToken(RequiredToken)) {
if (m_currentArg == QLatin1String("all")) {
- m_pmPrivate->testSpecs =
- Utils::transform(m_pmPrivate->loadQueue(), [](PluginSpec *spec) {
- return PluginManagerPrivate::TestSpec(spec);
- });
+ m_pmPrivate->testSpecs
+ = Utils::transform<std::vector>(m_pmPrivate->loadQueue(), [](PluginSpec *spec) {
+ return PluginManagerPrivate::TestSpec(spec);
+ });
} else {
QStringList args = m_currentArg.split(QLatin1Char(','));
const QString pluginName = args.takeFirst();
@@ -129,7 +129,7 @@ bool OptionsParser::checkForTestOptions()
"The plugin \"%1\" is specified twice for testing.").arg(pluginName);
m_hasError = true;
} else {
- m_pmPrivate->testSpecs.append(PluginManagerPrivate::TestSpec(spec, args));
+ m_pmPrivate->testSpecs.emplace_back(spec, args);
}
} else {
if (m_errorString)
@@ -265,7 +265,7 @@ bool OptionsParser::checkForUnknownOption()
void OptionsParser::forceDisableAllPluginsExceptTestedAndForceEnabled()
{
- for (const PluginManagerPrivate::TestSpec &testSpec : qAsConst(m_pmPrivate->testSpecs))
+ for (const PluginManagerPrivate::TestSpec &testSpec : m_pmPrivate->testSpecs)
testSpec.pluginSpec->d->setForceEnabled(true);
for (PluginSpec *spec : qAsConst(m_pmPrivate->pluginSpecs)) {
if (!spec->isForceEnabled() && !spec->isRequired())
diff --git a/src/libs/extensionsystem/pluginerroroverview.cpp b/src/libs/extensionsystem/pluginerroroverview.cpp
index 828bd013f4..74e7ac73b0 100644
--- a/src/libs/extensionsystem/pluginerroroverview.cpp
+++ b/src/libs/extensionsystem/pluginerroroverview.cpp
@@ -45,7 +45,7 @@ PluginErrorOverview::PluginErrorOverview(QWidget *parent) :
// only show errors on startup if plugin is enabled.
if (spec->hasError() && spec->isEffectivelyEnabled()) {
QListWidgetItem *item = new QListWidgetItem(spec->name());
- item->setData(Qt::UserRole, qVariantFromValue(spec));
+ item->setData(Qt::UserRole, QVariant::fromValue(spec));
m_ui->pluginList->addItem(item);
}
}
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index 956f6f01eb..6fbda8e4ec 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -319,7 +319,7 @@ void PluginManager::removeObject(QObject *obj)
\sa PluginManager::getObject()
*/
-QList<QObject *> PluginManager::allObjects()
+QVector<QObject *> PluginManager::allObjects()
{
return d->allObjects;
}
@@ -376,10 +376,11 @@ QSet<PluginSpec *> PluginManager::pluginsRequiredByPlugin(PluginSpec *spec)
{
QSet<PluginSpec *> recursiveDependencies;
recursiveDependencies.insert(spec);
- QList<PluginSpec *> queue;
- queue.append(spec);
- while (!queue.isEmpty()) {
- PluginSpec *checkSpec = queue.takeFirst();
+ std::queue<PluginSpec *> queue;
+ queue.push(spec);
+ while (!queue.empty()) {
+ PluginSpec *checkSpec = queue.front();
+ queue.pop();
QHashIterator<PluginDependency, PluginSpec *> depIt(checkSpec->dependencySpecs());
while (depIt.hasNext()) {
depIt.next();
@@ -388,7 +389,7 @@ QSet<PluginSpec *> PluginManager::pluginsRequiredByPlugin(PluginSpec *spec)
PluginSpec *depSpec = depIt.value();
if (!recursiveDependencies.contains(depSpec)) {
recursiveDependencies.insert(depSpec);
- queue.append(depSpec);
+ queue.push(depSpec);
}
}
}
@@ -536,12 +537,12 @@ QStringList PluginManager::arguments()
\sa setPluginPaths()
*/
-const QList<PluginSpec *> PluginManager::plugins()
+const QVector<PluginSpec *> PluginManager::plugins()
{
return d->pluginSpecs;
}
-QHash<QString, QList<PluginSpec *> > PluginManager::pluginCollections()
+QHash<QString, QVector<PluginSpec *>> PluginManager::pluginCollections()
{
return d->pluginCategories;
}
@@ -752,7 +753,7 @@ void PluginManager::formatPluginVersions(QTextStream &str)
*/
bool PluginManager::testRunRequested()
{
- return !d->testSpecs.isEmpty();
+ return !d->testSpecs.empty();
}
/*!
@@ -769,7 +770,7 @@ void PluginManager::profilingReport(const char *what, const PluginSpec *spec)
/*!
Returns a list of plugins in load order.
*/
-QList<PluginSpec *> PluginManager::loadQueue()
+QVector<PluginSpec *> PluginManager::loadQueue()
{
return d->loadQueue();
}
@@ -818,15 +819,16 @@ PluginSpecPrivate *PluginManagerPrivate::privateSpec(PluginSpec *spec)
void PluginManagerPrivate::nextDelayedInitialize()
{
- while (!delayedInitializeQueue.isEmpty()) {
- PluginSpec *spec = delayedInitializeQueue.takeFirst();
+ while (!delayedInitializeQueue.empty()) {
+ PluginSpec *spec = delayedInitializeQueue.front();
+ delayedInitializeQueue.pop();
profilingReport(">delayedInitialize", spec);
bool delay = spec->d->delayedInitialize();
profilingReport("<delayedInitialize", spec);
if (delay)
break; // do next delayedInitialize after a delay
}
- if (delayedInitializeQueue.isEmpty()) {
+ if (delayedInitializeQueue.empty()) {
m_isInitializationDone = true;
delete delayedInitializeTimer;
delayedInitializeTimer = nullptr;
@@ -903,7 +905,7 @@ void PluginManagerPrivate::stopAll()
delete delayedInitializeTimer;
delayedInitializeTimer = nullptr;
}
- QList<PluginSpec *> queue = loadQueue();
+ QVector<PluginSpec *> queue = loadQueue();
foreach (PluginSpec *spec, queue) {
loadPlugin(spec, PluginSpec::Stopped);
}
@@ -926,8 +928,10 @@ using TestPlanIterator = QMapIterator<QObject *, QStringList>;
static bool isTestFunction(const QMetaMethod &metaMethod)
{
- static const QList<QByteArray> blackList = QList<QByteArray>()
- << "initTestCase()" << "cleanupTestCase()" << "init()" << "cleanup()";
+ static const QVector<QByteArray> blackList = {"initTestCase()",
+ "cleanupTestCase()",
+ "init()",
+ "cleanup()"};
if (metaMethod.methodType() != QMetaMethod::Slot)
return false;
@@ -991,7 +995,7 @@ static QStringList matchingTestFunctions(const QStringList &testFunctions,
return matchingFunctions;
}
-static QObject *objectWithClassName(const QList<QObject *> &objects, const QString &className)
+static QObject *objectWithClassName(const QVector<QObject *> &objects, const QString &className)
{
return Utils::findOr(objects, nullptr, [className] (QObject *object) -> bool {
QString candidate = QString::fromUtf8(object->metaObject()->className());
@@ -1034,7 +1038,7 @@ static int executeTestPlan(const TestPlan &testPlan)
/// Resulting plan consists of all test functions of the plugin object and
/// all test functions of all test objects of the plugin.
-static TestPlan generateCompleteTestPlan(IPlugin *plugin, const QList<QObject *> &testObjects)
+static TestPlan generateCompleteTestPlan(IPlugin *plugin, const QVector<QObject *> &testObjects)
{
TestPlan testPlan;
@@ -1054,7 +1058,8 @@ static TestPlan generateCompleteTestPlan(IPlugin *plugin, const QList<QObject *>
///
/// Since multiple match texts can match the same function, a test function might
/// be included multiple times for a test object.
-static TestPlan generateCustomTestPlan(IPlugin *plugin, const QList<QObject *> &testObjects,
+static TestPlan generateCustomTestPlan(IPlugin *plugin,
+ const QVector<QObject *> &testObjects,
const QStringList &matchTexts)
{
TestPlan testPlan;
@@ -1062,7 +1067,7 @@ static TestPlan generateCustomTestPlan(IPlugin *plugin, const QList<QObject *> &
const QStringList testFunctionsOfPluginObject = testFunctions(plugin->metaObject());
QStringList matchedTestFunctionsOfPluginObject;
QStringList remainingMatchTexts = matchTexts;
- QList<QObject *> remainingTestObjectsOfPlugin = testObjects;
+ QVector<QObject *> remainingTestObjectsOfPlugin = testObjects;
while (!remainingMatchTexts.isEmpty()) {
const QString matchText = remainingMatchTexts.takeFirst();
@@ -1127,11 +1132,12 @@ void PluginManagerPrivate::startTests()
if (!plugin)
continue; // plugin not loaded
- const QList<QObject *> testObjects = plugin->createTestObjects();
+ const QVector<QObject *> testObjects = plugin->createTestObjects();
ExecuteOnDestruction deleteTestObjects([&]() { qDeleteAll(testObjects); });
Q_UNUSED(deleteTestObjects)
- const bool hasDuplicateTestObjects = testObjects.size() != testObjects.toSet().size();
+ const bool hasDuplicateTestObjects = testObjects.size()
+ != Utils::filteredUnique(testObjects).size();
QTC_ASSERT(!hasDuplicateTestObjects, continue);
QTC_ASSERT(!testObjects.contains(plugin), continue);
@@ -1205,7 +1211,7 @@ void PluginManagerPrivate::removeObject(QObject *obj)
*/
void PluginManagerPrivate::loadPlugins()
{
- QList<PluginSpec *> queue = loadQueue();
+ QVector<PluginSpec *> queue = loadQueue();
Utils::setMimeStartupPhase(MimeStartupPhase::PluginsLoading);
foreach (PluginSpec *spec, queue) {
loadPlugin(spec, PluginSpec::Loaded);
@@ -1218,7 +1224,7 @@ void PluginManagerPrivate::loadPlugins()
Utils::reverseForeach(queue, [this](PluginSpec *spec) {
loadPlugin(spec, PluginSpec::Running);
if (spec->state() == PluginSpec::Running) {
- delayedInitializeQueue.append(spec);
+ delayedInitializeQueue.push(spec);
} else {
// Plugin initialization failed, so cleanup after it
spec->d->kill();
@@ -1261,7 +1267,7 @@ void PluginManagerPrivate::asyncShutdownFinished()
{
auto *plugin = qobject_cast<IPlugin *>(sender());
Q_ASSERT(plugin);
- asynchronousPlugins.removeAll(plugin->pluginSpec());
+ asynchronousPlugins.remove(plugin->pluginSpec());
if (asynchronousPlugins.isEmpty())
shutdownEventLoop->exit();
}
@@ -1269,11 +1275,11 @@ void PluginManagerPrivate::asyncShutdownFinished()
/*!
\internal
*/
-QList<PluginSpec *> PluginManagerPrivate::loadQueue()
+QVector<PluginSpec *> PluginManagerPrivate::loadQueue()
{
- QList<PluginSpec *> queue;
+ QVector<PluginSpec *> queue;
foreach (PluginSpec *spec, pluginSpecs) {
- QList<PluginSpec *> circularityCheckQueue;
+ QVector<PluginSpec *> circularityCheckQueue;
loadQueue(spec, queue, circularityCheckQueue);
}
return queue;
@@ -1282,8 +1288,9 @@ QList<PluginSpec *> PluginManagerPrivate::loadQueue()
/*!
\internal
*/
-bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queue,
- QList<PluginSpec *> &circularityCheckQueue)
+bool PluginManagerPrivate::loadQueue(PluginSpec *spec,
+ QVector<PluginSpec *> &queue,
+ QVector<PluginSpec *> &circularityCheckQueue)
{
if (queue.contains(spec))
return true;
@@ -1433,7 +1440,7 @@ void PluginManagerPrivate::readPluginPaths()
pluginCategories.clear();
// default
- pluginCategories.insert(QString(), QList<PluginSpec *>());
+ pluginCategories.insert(QString(), QVector<PluginSpec *>());
foreach (const QString &pluginFile, pluginFiles(pluginPaths)) {
auto *spec = new PluginSpec;
@@ -1477,7 +1484,7 @@ void PluginManagerPrivate::enableDependenciesIndirectly()
foreach (PluginSpec *spec, pluginSpecs)
spec->d->enabledIndirectly = false;
// cannot use reverse loadQueue here, because test dependencies can introduce circles
- QList<PluginSpec *> queue = Utils::filtered(pluginSpecs, &PluginSpec::isEffectivelyEnabled);
+ QVector<PluginSpec *> queue = Utils::filtered(pluginSpecs, &PluginSpec::isEffectivelyEnabled);
while (!queue.isEmpty()) {
PluginSpec *spec = queue.takeFirst();
queue += spec->d->enableDependenciesIndirectly(containsTestSpec(spec));
diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h
index 411a5205b4..c926d07f4a 100644
--- a/src/libs/extensionsystem/pluginmanager.h
+++ b/src/libs/extensionsystem/pluginmanager.h
@@ -55,14 +55,14 @@ public:
// Object pool operations
static void addObject(QObject *obj);
static void removeObject(QObject *obj);
- static QList<QObject *> allObjects();
+ static QVector<QObject *> allObjects();
static QReadWriteLock *listLock();
// This is useful for soft dependencies using pure interfaces.
template <typename T> static T *getObject()
{
QReadLocker lock(listLock());
- QList<QObject *> all = allObjects();
+ QVector<QObject *> all = allObjects();
foreach (QObject *obj, all) {
if (T *result = qobject_cast<T *>(obj))
return result;
@@ -72,7 +72,7 @@ public:
template <typename T, typename Predicate> static T *getObject(Predicate predicate)
{
QReadLocker lock(listLock());
- QList<QObject *> all = allObjects();
+ QVector<QObject *> all = allObjects();
foreach (QObject *obj, all) {
if (T *result = qobject_cast<T *>(obj))
if (predicate(result))
@@ -84,14 +84,14 @@ public:
static QObject *getObjectByName(const QString &name);
// Plugin operations
- static QList<PluginSpec *> loadQueue();
+ static QVector<PluginSpec *> loadQueue();
static void loadPlugins();
static QStringList pluginPaths();
static void setPluginPaths(const QStringList &paths);
static QString pluginIID();
static void setPluginIID(const QString &iid);
- static const QList<PluginSpec *> plugins();
- static QHash<QString, QList<PluginSpec *>> pluginCollections();
+ static const QVector<PluginSpec *> plugins();
+ static QHash<QString, QVector<PluginSpec *>> pluginCollections();
static bool hasError();
static QSet<PluginSpec *> pluginsRequiringPlugin(PluginSpec *spec);
static QSet<PluginSpec *> pluginsRequiredByPlugin(PluginSpec *spec);
diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h
index b21a3f7ce4..d67ce28c11 100644
--- a/src/libs/extensionsystem/pluginmanager_p.h
+++ b/src/libs/extensionsystem/pluginmanager_p.h
@@ -35,6 +35,8 @@
#include <QScopedPointer>
#include <QReadWriteLock>
+#include <queue>
+
QT_BEGIN_NAMESPACE
class QTime;
class QTimer;
@@ -65,13 +67,13 @@ public:
void loadPlugins();
void shutdown();
void setPluginPaths(const QStringList &paths);
- QList<PluginSpec *> loadQueue();
+ QVector<ExtensionSystem::PluginSpec *> loadQueue();
void loadPlugin(PluginSpec *spec, PluginSpec::State destState);
void resolveDependencies();
void enableDependenciesIndirectly();
void initProfiling();
void profilingSummary() const;
- void profilingReport(const char *what, const PluginSpec *spec = 0);
+ void profilingReport(const char *what, const PluginSpec *spec = nullptr);
void setSettings(QSettings *settings);
void setGlobalSettings(QSettings *settings);
void readSettings();
@@ -80,8 +82,10 @@ public:
class TestSpec {
public:
TestSpec(PluginSpec *pluginSpec, const QStringList &testFunctionsOrObjects = QStringList())
- : pluginSpec(pluginSpec), testFunctionsOrObjects(testFunctionsOrObjects) {}
- PluginSpec *pluginSpec;
+ : pluginSpec(pluginSpec)
+ , testFunctionsOrObjects(testFunctionsOrObjects)
+ {}
+ PluginSpec *pluginSpec = nullptr;
QStringList testFunctionsOrObjects;
};
@@ -95,21 +99,21 @@ public:
testSpecs = Utils::filtered(testSpecs, [pluginSpec](const TestSpec &s) { return s.pluginSpec != pluginSpec; });
}
- QHash<QString, QList<PluginSpec *>> pluginCategories;
- QList<PluginSpec *> pluginSpecs;
- QList<TestSpec> testSpecs;
+ QHash<QString, QVector<PluginSpec *>> pluginCategories;
+ QVector<PluginSpec *> pluginSpecs;
+ std::vector<TestSpec> testSpecs;
QStringList pluginPaths;
QString pluginIID;
- QList<QObject *> allObjects; // ### make this a QList<QPointer<QObject> > > ?
+ QVector<QObject *> allObjects; // ### make this a QVector<QPointer<QObject> > > ?
QStringList defaultDisabledPlugins; // Plugins/Ignored from install settings
QStringList defaultEnabledPlugins; // Plugins/ForceEnabled from install settings
QStringList disabledPlugins;
QStringList forceEnabledPlugins;
// delayed initialization
QTimer *delayedInitializeTimer = nullptr;
- QList<PluginSpec *> delayedInitializeQueue;
+ std::queue<PluginSpec *> delayedInitializeQueue;
// ansynchronous shutdown
- QList<PluginSpec *> asynchronousPlugins; // plugins that have requested async shutdown
+ QSet<PluginSpec *> asynchronousPlugins; // plugins that have requested async shutdown
QEventLoop *shutdownEventLoop = nullptr; // used for async shutdown
QStringList arguments;
@@ -140,8 +144,8 @@ private:
void readPluginPaths();
bool loadQueue(PluginSpec *spec,
- QList<PluginSpec *> &queue,
- QList<PluginSpec *> &circularityCheckQueue);
+ QVector<ExtensionSystem::PluginSpec *> &queue,
+ QVector<ExtensionSystem::PluginSpec *> &circularityCheckQueue);
void stopAll();
void deleteAll();
diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp
index ef9ac19ea2..b8d0643982 100644
--- a/src/libs/extensionsystem/pluginspec.cpp
+++ b/src/libs/extensionsystem/pluginspec.cpp
@@ -885,7 +885,7 @@ int PluginSpecPrivate::versionCompare(const QString &version1, const QString &ve
/*!
\internal
*/
-bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
+bool PluginSpecPrivate::resolveDependencies(const QVector<PluginSpec *> &specs)
{
if (hasError)
return false;
@@ -924,11 +924,11 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
}
// returns the plugins that it actually indirectly enabled
-QList<PluginSpec *> PluginSpecPrivate::enableDependenciesIndirectly(bool enableTestDependencies)
+QVector<PluginSpec *> PluginSpecPrivate::enableDependenciesIndirectly(bool enableTestDependencies)
{
if (!q->isEffectivelyEnabled()) // plugin not enabled, nothing to do
return {};
- QList<PluginSpec *> enabled;
+ QVector<PluginSpec *> enabled;
QHashIterator<PluginDependency, PluginSpec *> it(dependencySpecs);
while (it.hasNext()) {
it.next();
diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h
index 9d37ed9923..fc6c0c2ff2 100644
--- a/src/libs/extensionsystem/pluginspec_p.h
+++ b/src/libs/extensionsystem/pluginspec_p.h
@@ -52,7 +52,7 @@ public:
bool read(const QString &fileName);
bool provides(const QString &pluginName, const QString &version) const;
- bool resolveDependencies(const QList<PluginSpec *> &specs);
+ bool resolveDependencies(const QVector<PluginSpec *> &specs);
bool loadLibrary();
bool initializePlugin();
bool initializeExtensions();
@@ -103,7 +103,7 @@ public:
static bool isValidVersion(const QString &version);
static int versionCompare(const QString &version1, const QString &version2);
- QList<PluginSpec *> enableDependenciesIndirectly(bool enableTestDependencies = false);
+ QVector<PluginSpec *> enableDependenciesIndirectly(bool enableTestDependencies = false);
bool readMetaData(const QJsonObject &pluginMetaData);
diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp
index 39a39643cb..bb5d6b98ed 100644
--- a/src/libs/extensionsystem/pluginview.cpp
+++ b/src/libs/extensionsystem/pluginview.cpp
@@ -212,8 +212,10 @@ public:
class CollectionItem : public TreeItem
{
public:
- CollectionItem(const QString &name, QList<PluginSpec *> plugins, PluginView *view)
- : m_name(name), m_plugins(plugins), m_view(view)
+ CollectionItem(const QString &name, QVector<PluginSpec *> plugins, PluginView *view)
+ : m_name(name)
+ , m_plugins(plugins)
+ , m_view(view)
{
foreach (PluginSpec *spec, plugins)
appendChild(new PluginItem(spec, view));
@@ -254,9 +256,11 @@ public:
bool setData(int column, const QVariant &data, int role) override
{
if (column == LoadedColumn && role == Qt::CheckStateRole) {
- const QList<PluginSpec *> affectedPlugins =
- Utils::filtered(m_plugins, [](PluginSpec *spec) { return !spec->isRequired(); });
- if (m_view->setPluginsEnabled(affectedPlugins.toSet(), data.toBool())) {
+ const QVector<PluginSpec *> affectedPlugins
+ = Utils::filtered(m_plugins, [](PluginSpec *spec) { return !spec->isRequired(); });
+ if (m_view->setPluginsEnabled(Utils::transform<QSet>(affectedPlugins,
+ [](PluginSpec *s) { return s; }),
+ data.toBool())) {
update();
return true;
}
@@ -274,7 +278,7 @@ public:
public:
QString m_name;
- QList<PluginSpec *> m_plugins;
+ QVector<PluginSpec *> m_plugins;
PluginView *m_view; // Not owned.
};
@@ -408,13 +412,13 @@ void PluginView::updatePlugins()
// Model.
m_model->clear();
-
- QList<CollectionItem *> collections;
- const QHash<QString, QList<PluginSpec *>> pluginCollections = PluginManager::pluginCollections();
+ const QHash<QString, QVector<PluginSpec *>> pluginCollections
+ = PluginManager::pluginCollections();
+ std::vector<CollectionItem *> collections;
const auto end = pluginCollections.cend();
for (auto it = pluginCollections.cbegin(); it != end; ++it) {
const QString name = it.key().isEmpty() ? tr("Utilities") : it.key();
- collections.append(new CollectionItem(name, it.value(), this));
+ collections.push_back(new CollectionItem(name, it.value(), this));
}
Utils::sort(collections, &CollectionItem::m_name);
diff --git a/src/libs/glsl/CMakeLists.txt b/src/libs/glsl/CMakeLists.txt
new file mode 100644
index 0000000000..e5fcb3692b
--- /dev/null
+++ b/src/libs/glsl/CMakeLists.txt
@@ -0,0 +1,19 @@
+add_qtc_library(GLSL
+ DEPENDS Qt5::Core
+ SOURCES
+ glsl.h
+ glslast.cpp glslast.h
+ glslastdump.cpp glslastdump.h
+ glslastvisitor.cpp glslastvisitor.h
+ glslengine.cpp glslengine.h
+ glslkeywords.cpp
+ glsllexer.cpp glsllexer.h
+ glslmemorypool.cpp glslmemorypool.h
+ glslparser.cpp glslparser.h
+ glslparsertable.cpp glslparsertable_p.h
+ glslsemantic.cpp glslsemantic.h
+ glslsymbol.cpp glslsymbol.h
+ glslsymbols.cpp glslsymbols.h
+ glsltype.cpp glsltype.h
+ glsltypes.cpp glsltypes.h
+)
diff --git a/src/libs/glsl/glslparser.h b/src/libs/glsl/glslparser.h
index f0ccf82cb9..5e148c298b 100644
--- a/src/libs/glsl/glslparser.h
+++ b/src/libs/glsl/glslparser.h
@@ -26,6 +26,8 @@
**
****************************************************************************/
+#pragma once
+
#include "glslparsertable_p.h"
#include "glsllexer.h"
#include "glslast.h"
diff --git a/src/libs/languageserverprotocol/CMakeLists.txt b/src/libs/languageserverprotocol/CMakeLists.txt
new file mode 100644
index 0000000000..9ad446817f
--- /dev/null
+++ b/src/libs/languageserverprotocol/CMakeLists.txt
@@ -0,0 +1,23 @@
+add_qtc_library(LanguageServerProtocol
+ DEPENDS Utils
+ SOURCES
+ basemessage.cpp basemessage.h
+ client.cpp client.h
+ clientcapabilities.cpp clientcapabilities.h
+ completion.cpp completion.h
+ diagnostics.cpp diagnostics.h
+ icontent.h
+ initializemessages.cpp initializemessages.h
+ jsonkeys.h
+ jsonobject.cpp jsonobject.h
+ jsonrpcmessages.cpp jsonrpcmessages.h
+ languagefeatures.cpp languagefeatures.h
+ languageserverprotocol_global.h
+ lsptypes.cpp lsptypes.h
+ lsputils.cpp lsputils.h
+ messages.cpp messages.h
+ servercapabilities.cpp servercapabilities.h
+ shutdownmessages.cpp shutdownmessages.h
+ textsynchronization.cpp textsynchronization.h
+ workspace.cpp workspace.h
+)
diff --git a/src/libs/languageserverprotocol/basemessage.cpp b/src/libs/languageserverprotocol/basemessage.cpp
index 1ee17e3eee..950976549e 100644
--- a/src/libs/languageserverprotocol/basemessage.cpp
+++ b/src/libs/languageserverprotocol/basemessage.cpp
@@ -37,6 +37,8 @@
namespace LanguageServerProtocol {
+Q_LOGGING_CATEGORY(parseLog, "qtc.languageserverprotocol.parse", QtWarningMsg)
+
BaseMessage::BaseMessage()
: mimeType(JsonRpcMessageHandler::jsonRpcMimeType())
{ }
@@ -68,8 +70,7 @@ bool BaseMessage::operator==(const BaseMessage &other) const
return true;
}
-static QPair<QByteArray, QByteArray> splitHeaderFieldLine(
- const QByteArray &headerFieldLine, QString &parseError)
+static QPair<QByteArray, QByteArray> splitHeaderFieldLine(const QByteArray &headerFieldLine)
{
static const int fieldSeparatorLength = int(std::strlen(headerFieldSeparator));
int assignmentIndex = headerFieldLine.indexOf(headerFieldSeparator);
@@ -77,8 +78,7 @@ static QPair<QByteArray, QByteArray> splitHeaderFieldLine(
return {headerFieldLine.mid(0, assignmentIndex),
headerFieldLine.mid(assignmentIndex + fieldSeparatorLength)};
}
- parseError = BaseMessage::tr("Unexpected header line \"%1\".")
- .arg(QLatin1String(headerFieldLine));
+ qCWarning(parseLog) << "Unexpected header line:" << QLatin1String(headerFieldLine);
return {};
}
@@ -134,8 +134,7 @@ void BaseMessage::parse(QBuffer *data, QString &parseError, BaseMessage &message
message.content = data->read(message.contentLength);
return;
}
- const QPair<QByteArray, QByteArray> nameAndValue =
- splitHeaderFieldLine(headerFieldLine, parseError);
+ const QPair<QByteArray, QByteArray> nameAndValue = splitHeaderFieldLine(headerFieldLine);
const QByteArray &headerFieldName = nameAndValue.first.trimmed();
const QByteArray &headerFieldValue = nameAndValue.second.trimmed();
@@ -146,9 +145,8 @@ void BaseMessage::parse(QBuffer *data, QString &parseError, BaseMessage &message
} else if (headerFieldName == contentTypeFieldName) {
parseContentType(message, headerFieldValue, parseError);
} else {
- parseError = tr("Unexpected header field \"%1\" in \"%2\".")
- .arg(QLatin1String(headerFieldName),
- QLatin1String(headerFieldLine));
+ qCWarning(parseLog) << "Unexpected header field" << QLatin1String(headerFieldName)
+ << "in" << QLatin1String(headerFieldLine);
}
}
diff --git a/src/libs/languageserverprotocol/basemessage.h b/src/libs/languageserverprotocol/basemessage.h
index ba8238291a..b2835aa7d7 100644
--- a/src/libs/languageserverprotocol/basemessage.h
+++ b/src/libs/languageserverprotocol/basemessage.h
@@ -31,6 +31,7 @@
#include <QByteArray>
#include <QCoreApplication>
+#include <QLoggingCategory>
QT_BEGIN_NAMESPACE
class QBuffer;
@@ -39,6 +40,8 @@ QT_END_NAMESPACE
namespace LanguageServerProtocol {
+LANGUAGESERVERPROTOCOL_EXPORT Q_DECLARE_LOGGING_CATEGORY(parseLog)
+
class LANGUAGESERVERPROTOCOL_EXPORT BaseMessage
{
Q_DECLARE_TR_FUNCTIONS(BaseMessage)
diff --git a/src/libs/languageserverprotocol/clientcapabilities.cpp b/src/libs/languageserverprotocol/clientcapabilities.cpp
index 0200250444..f73c4ee04c 100644
--- a/src/libs/languageserverprotocol/clientcapabilities.cpp
+++ b/src/libs/languageserverprotocol/clientcapabilities.cpp
@@ -27,19 +27,6 @@
namespace LanguageServerProtocol {
-SymbolCapabilities::SymbolKindCapabilities::SymbolKindCapabilities()
-{
- setValueSet({SymbolKind::File, SymbolKind::Module, SymbolKind::Namespace,
- SymbolKind::Package, SymbolKind::Class, SymbolKind::Method,
- SymbolKind::Property, SymbolKind::Field, SymbolKind::Constructor,
- SymbolKind::Enum, SymbolKind::Interface, SymbolKind::Function,
- SymbolKind::Variable, SymbolKind::Constant, SymbolKind::String,
- SymbolKind::Number, SymbolKind::Boolean, SymbolKind::Array,
- SymbolKind::Object, SymbolKind::Key, SymbolKind::Null,
- SymbolKind::EnumMember, SymbolKind::Struct, SymbolKind::Event,
- SymbolKind::Operator, SymbolKind::TypeParameter});
-}
-
Utils::optional<QList<SymbolKind> > SymbolCapabilities::SymbolKindCapabilities::valueSet() const
{
Utils::optional<QList<int>> array = optionalArray<int>(valueSetKey);
@@ -55,13 +42,6 @@ void SymbolCapabilities::SymbolKindCapabilities::setValueSet(const QList<SymbolK
insert(valueSetKey, enumArrayToJsonArray<SymbolKind>(valueSet));
}
-
-ClientCapabilities::ClientCapabilities()
-{
- setTextDocument(TextDocumentClientCapabilities());
- setWorkspace(WorkspaceClientCapabilities());
-}
-
bool ClientCapabilities::isValid(QStringList *error) const
{
return checkOptional<WorkspaceClientCapabilities>(error, workspaceKey)
@@ -85,14 +65,6 @@ bool WorkspaceClientCapabilities::isValid(QStringList *error) const
&& checkOptional<bool>(error,configurationKey);
}
-TextDocumentClientCapabilities::SynchronizationCapabilities::SynchronizationCapabilities()
-{
- setDynamicRegistration(true);
- setWillSave(true);
- setWillSaveWaitUntil(false);
- setDidSave(true);
-}
-
bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(QStringList *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
@@ -101,19 +73,6 @@ bool TextDocumentClientCapabilities::SynchronizationCapabilities::isValid(QStrin
&& checkOptional<bool>(error, didSaveKey);
}
-TextDocumentClientCapabilities::TextDocumentClientCapabilities()
-{
- setSynchronization(SynchronizationCapabilities());
- setDocumentSymbol(SymbolCapabilities());
- setCompletion(CompletionCapabilities());
- CodeActionCapabilities cac;
- CodeActionCapabilities::CodeActionLiteralSupport literalSupport;
- literalSupport.setCodeActionKind(
- CodeActionCapabilities::CodeActionLiteralSupport::CodeActionKind(QList<QString>{"*"}));
- cac.setCodeActionLiteralSupport(literalSupport);
- setCodeAction(cac);
-}
-
bool TextDocumentClientCapabilities::isValid(QStringList *error) const
{
return checkOptional<SynchronizationCapabilities>(error, synchronizationKey)
@@ -136,24 +95,12 @@ bool TextDocumentClientCapabilities::isValid(QStringList *error) const
&& checkOptional<DynamicRegistrationCapabilities>(error, renameKey);
}
-SymbolCapabilities::SymbolCapabilities()
-{
- setSymbolKind(SymbolKindCapabilities());
-}
-
bool SymbolCapabilities::isValid(QStringList *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
&& checkOptional<SymbolKindCapabilities>(error, symbolKindKey);
}
-TextDocumentClientCapabilities::CompletionCapabilities::CompletionCapabilities()
-{
- setDynamicRegistration(true);
- setCompletionItem(CompletionItemCapbilities());
- setCompletionItemKind(CompletionItemKindCapabilities());
-}
-
bool TextDocumentClientCapabilities::CompletionCapabilities::isValid(QStringList *error) const
{
return DynamicRegistrationCapabilities::isValid(error)
diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h
index c10341b3f0..3664007dd1 100644
--- a/src/libs/languageserverprotocol/clientcapabilities.h
+++ b/src/libs/languageserverprotocol/clientcapabilities.h
@@ -46,13 +46,11 @@ public:
class LANGUAGESERVERPROTOCOL_EXPORT SymbolCapabilities : public DynamicRegistrationCapabilities
{
public:
- SymbolCapabilities();
using DynamicRegistrationCapabilities::DynamicRegistrationCapabilities;
- class SymbolKindCapabilities : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT SymbolKindCapabilities : public JsonObject
{
public:
- SymbolKindCapabilities();
using JsonObject::JsonObject;
/*
@@ -85,13 +83,11 @@ public:
class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentClientCapabilities : public JsonObject
{
public:
- TextDocumentClientCapabilities();
using JsonObject::JsonObject;
- class SynchronizationCapabilities : public DynamicRegistrationCapabilities
+ class LANGUAGESERVERPROTOCOL_EXPORT SynchronizationCapabilities : public DynamicRegistrationCapabilities
{
public:
- SynchronizationCapabilities();
using DynamicRegistrationCapabilities::DynamicRegistrationCapabilities;
// The client supports sending will save notifications.
@@ -124,16 +120,14 @@ public:
{ insert(synchronizationKey, synchronization); }
void clearSynchronization() { remove(synchronizationKey); }
- class CompletionCapabilities : public DynamicRegistrationCapabilities
+ class LANGUAGESERVERPROTOCOL_EXPORT CompletionCapabilities : public DynamicRegistrationCapabilities
{
public:
- CompletionCapabilities();
using DynamicRegistrationCapabilities::DynamicRegistrationCapabilities;
- class CompletionItemCapbilities : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT CompletionItemCapbilities : public JsonObject
{
public:
- CompletionItemCapbilities();
using JsonObject::JsonObject;
/*
@@ -180,7 +174,7 @@ public:
{ insert(completionItemKey, completionItem); }
void clearCompletionItem() { remove(completionItemKey); }
- class CompletionItemKindCapabilities : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT CompletionItemKindCapabilities : public JsonObject
{
public:
CompletionItemKindCapabilities();
@@ -227,7 +221,7 @@ public:
{ insert(completionKey, completion); }
void clearCompletion() { remove(completionKey); }
- class HoverCapabilities : public DynamicRegistrationCapabilities
+ class LANGUAGESERVERPROTOCOL_EXPORT HoverCapabilities : public DynamicRegistrationCapabilities
{
public:
using DynamicRegistrationCapabilities::DynamicRegistrationCapabilities;
@@ -246,12 +240,12 @@ public:
void setHover(const HoverCapabilities &hover) { insert(hoverKey, hover); }
void clearHover() { remove(hoverKey); }
- class SignatureHelpCapabilities : public DynamicRegistrationCapabilities
+ class LANGUAGESERVERPROTOCOL_EXPORT SignatureHelpCapabilities : public DynamicRegistrationCapabilities
{
public:
using DynamicRegistrationCapabilities::DynamicRegistrationCapabilities;
- class SignatureInformationCapabilities : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT SignatureInformationCapabilities : public JsonObject
{
public:
using JsonObject::JsonObject;
@@ -355,17 +349,17 @@ public:
{ insert(implementationKey, implementation); }
void clearImplementation() { remove(implementationKey); }
- class CodeActionCapabilities : public DynamicRegistrationCapabilities
+ class LANGUAGESERVERPROTOCOL_EXPORT CodeActionCapabilities : public DynamicRegistrationCapabilities
{
public:
using DynamicRegistrationCapabilities::DynamicRegistrationCapabilities;
- class CodeActionLiteralSupport : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT CodeActionLiteralSupport : public JsonObject
{
public:
using JsonObject::JsonObject;
- class CodeActionKind : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT CodeActionKind : public JsonObject
{
public:
using JsonObject::JsonObject;
@@ -454,7 +448,7 @@ public:
void setApplyEdit(bool applyEdit) { insert(applyEditKey, applyEdit); }
void clearApplyEdit() { remove(applyEditKey); }
- class WorkspaceEditCapabilities : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceEditCapabilities : public JsonObject
{
public:
using JsonObject::JsonObject;
@@ -522,7 +516,6 @@ public:
class LANGUAGESERVERPROTOCOL_EXPORT ClientCapabilities : public JsonObject
{
public:
- ClientCapabilities();
using JsonObject::JsonObject;
// Workspace specific client capabilities.
diff --git a/src/libs/languageserverprotocol/icontent.h b/src/libs/languageserverprotocol/icontent.h
index af14604739..1b57165b2e 100644
--- a/src/libs/languageserverprotocol/icontent.h
+++ b/src/libs/languageserverprotocol/icontent.h
@@ -92,7 +92,7 @@ using ResponseHandler = std::function<void(const QByteArray &, QTextCodec *)>;
using ResponseHandlers = std::function<void(MessageId, const QByteArray &, QTextCodec *)>;
using MethodHandler = std::function<void(const QString, MessageId, const IContent *)>;
-inline LANGUAGESERVERPROTOCOL_EXPORT uint qHash(const LanguageServerProtocol::MessageId &id)
+inline uint qHash(const LanguageServerProtocol::MessageId &id)
{
if (Utils::holds_alternative<int>(id))
return QT_PREPEND_NAMESPACE(qHash(Utils::get<int>(id)));
@@ -102,8 +102,7 @@ inline LANGUAGESERVERPROTOCOL_EXPORT uint qHash(const LanguageServerProtocol::Me
}
template <typename Error>
-inline LANGUAGESERVERPROTOCOL_EXPORT QDebug operator<<(QDebug stream,
- const LanguageServerProtocol::MessageId &id)
+inline QDebug operator<<(QDebug stream, const LanguageServerProtocol::MessageId &id)
{
if (Utils::holds_alternative<int>(id))
stream << Utils::get<int>(id);
diff --git a/src/libs/languageserverprotocol/initializemessages.cpp b/src/libs/languageserverprotocol/initializemessages.cpp
index 0464f8a13c..92e82d5107 100644
--- a/src/libs/languageserverprotocol/initializemessages.cpp
+++ b/src/libs/languageserverprotocol/initializemessages.cpp
@@ -54,27 +54,18 @@ QString Trace::toString() const
}
#undef RETURN_CASE
-TextDocumentClientCapabilities::CompletionCapabilities::CompletionItemCapbilities::CompletionItemCapbilities()
-{
-}
-
Utils::optional<QList<MarkupKind>>
TextDocumentClientCapabilities::CompletionCapabilities::CompletionItemCapbilities::
documentationFormat() const
{
- Utils::optional<QList<int>> array = optionalArray<int>(documentationFormatKey);
- if (!array)
- return Utils::nullopt;
- return Utils::make_optional(Utils::transform(array.value(), [] (int value) {
- return static_cast<MarkupKind>(value);
- }));
+ return optionalArray<MarkupKind>(documentationFormatKey);
}
void
TextDocumentClientCapabilities::CompletionCapabilities::CompletionItemCapbilities::
setDocumentationFormat(const QList<MarkupKind> &documentationFormat)
{
- insert(documentationFormatKey, enumArrayToJsonArray<MarkupKind>(documentationFormat));
+ insertArray(documentationFormatKey, documentationFormat);
}
TextDocumentClientCapabilities::CompletionCapabilities::CompletionItemKindCapabilities::CompletionItemKindCapabilities()
@@ -111,36 +102,26 @@ setValueSet(const QList<CompletionItemKind::Kind> &valueSet)
Utils::optional<QList<MarkupKind> > TextDocumentClientCapabilities::HoverCapabilities::contentFormat() const
{
- Utils::optional<QList<int>> array = optionalArray<int>(contentFormatKey);
- if (!array)
- return Utils::nullopt;
- return Utils::make_optional(Utils::transform(array.value(), [] (int value) {
- return static_cast<MarkupKind>(value);
- }));
+ return optionalArray<MarkupKind>(contentFormatKey);
}
void TextDocumentClientCapabilities::HoverCapabilities::setContentFormat(const QList<MarkupKind> &contentFormat)
{
- insert(contentFormatKey, enumArrayToJsonArray<MarkupKind>(contentFormat));
+ insertArray(contentFormatKey, contentFormat);
}
Utils::optional<QList<MarkupKind>>
TextDocumentClientCapabilities::SignatureHelpCapabilities::SignatureInformationCapabilities::
documentationFormat() const
{
- Utils::optional<QList<int>> array = optionalArray<int>(documentationFormatKey);
- if (!array)
- return Utils::nullopt;
- return Utils::make_optional(Utils::transform(array.value(), [] (int value) {
- return static_cast<MarkupKind>(value);
- }));
+ return optionalArray<MarkupKind>(documentationFormatKey);
}
void
TextDocumentClientCapabilities::SignatureHelpCapabilities::SignatureInformationCapabilities::
setDocumentationFormat(const QList<MarkupKind> &documentationFormat)
{
- insert(documentationFormatKey, enumArrayToJsonArray<MarkupKind>(documentationFormat));
+ insertArray(documentationFormatKey, documentationFormat);
}
InitializeParams::InitializeParams()
diff --git a/src/libs/languageserverprotocol/jsonkeys.h b/src/libs/languageserverprotocol/jsonkeys.h
index 6dfc40c252..e3673085eb 100644
--- a/src/libs/languageserverprotocol/jsonkeys.h
+++ b/src/libs/languageserverprotocol/jsonkeys.h
@@ -69,6 +69,7 @@ constexpr char contentChangesKey[] = "contentChanges";
constexpr char contentCharsetName[] = "charset";
constexpr char contentFormatKey[] = "contentFormat";
constexpr char contentKey[] = "value";
+constexpr char contentsKey[] = "contents";
constexpr char contentLengthFieldName[] = "Content-Length";
constexpr char contentTypeFieldName[] = "Content-Type";
constexpr char contextKey[] = "context";
diff --git a/src/libs/languageserverprotocol/jsonobject.cpp b/src/libs/languageserverprotocol/jsonobject.cpp
index 1f471db47b..0156276a67 100644
--- a/src/libs/languageserverprotocol/jsonobject.cpp
+++ b/src/libs/languageserverprotocol/jsonobject.cpp
@@ -61,11 +61,7 @@ JsonObject &JsonObject::operator=(const JsonObject &other) = default;
JsonObject &JsonObject::operator=(JsonObject &&other)
{
-#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
m_jsonObject.swap(other.m_jsonObject);
-#else
- m_jsonObject = other.m_jsonObject; // NOTE use QJsonObject::swap when minimum required Qt version >= 5.10
-#endif
return *this;
}
diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.h b/src/libs/languageserverprotocol/jsonrpcmessages.h
index 66c28bea4b..473c9fe580 100644
--- a/src/libs/languageserverprotocol/jsonrpcmessages.h
+++ b/src/libs/languageserverprotocol/jsonrpcmessages.h
@@ -232,6 +232,7 @@ template <typename Result, typename ErrorDataType>
class Response : public JsonRpcMessage
{
public:
+ explicit Response(const MessageId &id) { setId(id); }
using JsonRpcMessage::JsonRpcMessage;
MessageId id() const
diff --git a/src/libs/languageserverprotocol/languagefeatures.cpp b/src/libs/languageserverprotocol/languagefeatures.cpp
index 06793217f1..cfb4cc6fab 100644
--- a/src/libs/languageserverprotocol/languagefeatures.cpp
+++ b/src/libs/languageserverprotocol/languagefeatures.cpp
@@ -49,19 +49,19 @@ constexpr const char DocumentOnTypeFormattingRequest::methodName[];
constexpr const char RenameRequest::methodName[];
constexpr const char SignatureHelpRequest::methodName[];
-MarkedString LanguageServerProtocol::Hover::content() const
+HoverContent LanguageServerProtocol::Hover::content() const
{
- return MarkedString(value(contentKey));
+ return HoverContent(value(contentsKey));
}
-void Hover::setContent(const MarkedString &content)
+void Hover::setContent(const HoverContent &content)
{
- if (auto val = Utils::get_if<MarkedLanguageString>(&content))
- insert(contentKey, *val);
+ if (auto val = Utils::get_if<MarkedString>(&content))
+ insert(contentsKey, *val);
else if (auto val = Utils::get_if<MarkupContent>(&content))
- insert(contentKey, *val);
- else if (auto val = Utils::get_if<QList<MarkedLanguageString>>(&content))
- insert(contentKey, LanguageClientArray<MarkedLanguageString>(*val).toJson());
+ insert(contentsKey, *val);
+ else if (auto val = Utils::get_if<QList<MarkedString>>(&content))
+ insert(contentsKey, LanguageClientArray<MarkedString>(*val).toJson());
else
QTC_ASSERT_STRING("LanguageClient Using unknown type Hover::setContent");
}
@@ -334,31 +334,52 @@ DocumentHighlightsResult::DocumentHighlightsResult(const QJsonValue &value)
MarkedString::MarkedString(const QJsonValue &value)
{
+ if (value.isObject()) {
+ MarkedLanguageString string(value.toObject());
+ if (string.isValid(nullptr))
+ emplace<MarkedLanguageString>(string);
+ } else if (value.isString()) {
+ emplace<QString>(value.toString());
+ }
+}
+
+LanguageServerProtocol::MarkedString::operator QJsonValue() const
+{
+ if (auto val = Utils::get_if<QString>(this))
+ return *val;
+ if (auto val = Utils::get_if<MarkedLanguageString>(this))
+ return QJsonValue(*val);
+ return {};
+}
+
+HoverContent::HoverContent(const QJsonValue &value)
+{
if (value.isArray()) {
- emplace<QList<MarkedLanguageString>>(
- LanguageClientArray<MarkedLanguageString>(value).toList());
+ emplace<QList<MarkedString>>(LanguageClientArray<MarkedString>(value).toList());
} else if (value.isObject()) {
const QJsonObject &object = value.toObject();
MarkedLanguageString markedLanguageString(object);
if (markedLanguageString.isValid(nullptr))
- emplace<MarkedLanguageString>(markedLanguageString);
+ emplace<MarkedString>(markedLanguageString);
else
emplace<MarkupContent>(MarkupContent(object));
+ } else if (value.isString()) {
+ emplace<MarkedString>(MarkedString(value.toString()));
}
}
-bool MarkedString::isValid(QStringList *errorHierarchy) const
+bool HoverContent::isValid(QStringList *errorHierarchy) const
{
- if (Utils::holds_alternative<MarkedLanguageString>(*this)
+ if (Utils::holds_alternative<MarkedString>(*this)
|| Utils::holds_alternative<MarkupContent>(*this)
- || Utils::holds_alternative<QList<MarkedLanguageString>>(*this)) {
+ || Utils::holds_alternative<QList<MarkedString>>(*this)) {
return true;
}
if (errorHierarchy) {
*errorHierarchy << QCoreApplication::translate(
- "LanguageServerProtocol::MarkedString",
- "MarkedString should be either MarkedLanguageString, "
- "MarkupContent, or QList<MarkedLanguageString>.");
+ "LanguageServerProtocol::HoverContent",
+ "HoverContent should be either MarkedString, "
+ "MarkupContent, or QList<MarkedString>.");
}
return false;
}
diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h
index 30f3591e64..ddd732718a 100644
--- a/src/libs/languageserverprotocol/languagefeatures.h
+++ b/src/libs/languageserverprotocol/languagefeatures.h
@@ -58,14 +58,31 @@ public:
{ return check<QString>(error, languageKey) && check<QString>(error, valueKey); }
};
-class MarkedString : public Utils::variant<MarkedLanguageString, QList<MarkedLanguageString>, MarkupContent>
+class LANGUAGESERVERPROTOCOL_EXPORT MarkedString
+ : public Utils::variant<QString, MarkedLanguageString>
{
public:
MarkedString() = default;
- explicit MarkedString(const MarkedLanguageString &other) : variant(other) {}
- explicit MarkedString(const QList<MarkedLanguageString> &other) : variant(other) {}
- explicit MarkedString(const MarkupContent &other) : variant(other) {}
+ explicit MarkedString(const MarkedLanguageString &other)
+ : variant(other)
+ {}
+ explicit MarkedString(const QString &other)
+ : variant(other)
+ {}
explicit MarkedString(const QJsonValue &value);
+
+ operator QJsonValue() const;
+};
+
+class LANGUAGESERVERPROTOCOL_EXPORT HoverContent
+ : public Utils::variant<MarkedString, QList<MarkedString>, MarkupContent>
+{
+public:
+ HoverContent() = default;
+ explicit HoverContent(const MarkedString &other) : variant(other) {}
+ explicit HoverContent(const QList<MarkedString> &other) : variant(other) {}
+ explicit HoverContent(const MarkupContent &other) : variant(other) {}
+ explicit HoverContent(const QJsonValue &value);
bool isValid(QStringList *errorHierarchy) const;
};
@@ -74,15 +91,15 @@ class LANGUAGESERVERPROTOCOL_EXPORT Hover : public JsonObject
public:
using JsonObject::JsonObject;
- MarkedString content() const;
- void setContent(const MarkedString &content);
+ HoverContent content() const;
+ void setContent(const HoverContent &content);
Utils::optional<Range> range() const { return optionalValue<Range>(rangeKey); }
void setRange(const Range &range) { insert(rangeKey, range); }
void clearRange() { remove(rangeKey); }
bool isValid(QStringList *error) const override
- { return check<MarkedString>(error, contentKey) && checkOptional<Range>(error, rangeKey); }
+ { return check<HoverContent>(error, contentsKey) && checkOptional<Range>(error, rangeKey); }
};
class LANGUAGESERVERPROTOCOL_EXPORT HoverRequest
@@ -332,9 +349,23 @@ public:
using variant::variant;
DocumentSymbolsResult() : variant(nullptr) {}
DocumentSymbolsResult(const QJsonValue &value);
+ DocumentSymbolsResult(const DocumentSymbolsResult &other) : variant(other) {}
+ DocumentSymbolsResult(DocumentSymbolsResult &&other) : variant(std::move(other)) {}
+
using variant::operator=;
+ DocumentSymbolsResult &operator =(DocumentSymbolsResult &&other)
+ {
+ variant::operator=(std::move(other));
+ return *this;
+ }
+ DocumentSymbolsResult &operator =(const DocumentSymbolsResult &other)
+ {
+ variant::operator=(other);
+ return *this;
+ }
};
+
class LANGUAGESERVERPROTOCOL_EXPORT DocumentSymbolsRequest
: public Request<DocumentSymbolsResult, std::nullptr_t, DocumentSymbolParams>
{
diff --git a/src/libs/languageserverprotocol/lsptypes.cpp b/src/libs/languageserverprotocol/lsptypes.cpp
index 991f7cc1f8..8aa1ecf81c 100644
--- a/src/libs/languageserverprotocol/lsptypes.cpp
+++ b/src/libs/languageserverprotocol/lsptypes.cpp
@@ -324,8 +324,10 @@ Position::Position(const QTextCursor &cursor)
int Position::toPositionInDocument(QTextDocument *doc) const
{
const QTextBlock block = doc->findBlockByNumber(line());
- if (!block.isValid() || block.length() <= character())
+ if (!block.isValid())
return -1;
+ if (block.length() <= character())
+ return block.position() + block.length();
return block.position() + character();
}
@@ -360,7 +362,7 @@ bool Range::overlaps(const Range &range) const
return contains(range.start()) || contains(range.end());
}
-bool DocumentFilter::applies(const Utils::FileName &fileName, const Utils::MimeType &mimeType) const
+bool DocumentFilter::applies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType) const
{
if (Utils::optional<QString> _scheme = scheme()) {
if (_scheme.value() == fileName.toString())
@@ -404,14 +406,30 @@ DocumentUri::DocumentUri(const QString &other)
: QUrl(QUrl::fromPercentEncoding(other.toLocal8Bit()))
{ }
-DocumentUri::DocumentUri(const Utils::FileName &other)
+DocumentUri::DocumentUri(const Utils::FilePath &other)
: QUrl(QUrl::fromLocalFile(other.toString()))
{ }
-Utils::FileName DocumentUri::toFileName() const
+Utils::FilePath DocumentUri::toFileName() const
{
- return isLocalFile() ? Utils::FileName::fromUserInput(QUrl(*this).toLocalFile())
- : Utils::FileName();
+ return isLocalFile() ? Utils::FilePath::fromUserInput(QUrl(*this).toLocalFile())
+ : Utils::FilePath();
+}
+
+MarkupKind::MarkupKind(const QJsonValue &value)
+{
+ m_value = value.toString() == "markdown" ? markdown : plaintext;
+}
+
+LanguageServerProtocol::MarkupKind::operator QJsonValue() const
+{
+ switch (m_value) {
+ case MarkupKind::markdown:
+ return "markdown";
+ case MarkupKind::plaintext:
+ return "plaintext";
+ }
+ return {};
}
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/lsptypes.h b/src/libs/languageserverprotocol/lsptypes.h
index 9fe9a47a63..ade3ac7ccf 100644
--- a/src/libs/languageserverprotocol/lsptypes.h
+++ b/src/libs/languageserverprotocol/lsptypes.h
@@ -45,16 +45,16 @@ class LANGUAGESERVERPROTOCOL_EXPORT DocumentUri : public QUrl
{
public:
DocumentUri() = default;
- Utils::FileName toFileName() const;
+ Utils::FilePath toFileName() const;
static DocumentUri fromProtocol(const QString &uri) { return DocumentUri(uri); }
- static DocumentUri fromFileName(const Utils::FileName &file) { return DocumentUri(file); }
+ static DocumentUri fromFileName(const Utils::FilePath &file) { return DocumentUri(file); }
operator QJsonValue() const { return QJsonValue(toString()); }
private:
DocumentUri(const QString &other);
- DocumentUri(const Utils::FileName &other);
+ DocumentUri(const Utils::FilePath &other);
friend class LanguageClientValue<QString>;
};
@@ -372,16 +372,30 @@ public:
void setPattern(const QString &pattern) { insert(patternKey, pattern); }
void clearPattern() { remove(patternKey); }
- bool applies(const Utils::FileName &fileName,
+ bool applies(const Utils::FilePath &fileName,
const Utils::MimeType &mimeType = Utils::MimeType()) const;
bool isValid(QStringList *error) const override;
};
-enum class MarkupKind
+class LANGUAGESERVERPROTOCOL_EXPORT MarkupKind
{
- plaintext,
- markdown,
+public:
+ enum Value { plaintext, markdown };
+ MarkupKind() = default;
+ MarkupKind(const Value value)
+ : m_value(value)
+ {}
+ MarkupKind(const QJsonValue &value);
+
+ operator QJsonValue() const;
+ Value value() const { return m_value; }
+
+ bool operator==(const Value &value) const { return m_value == value; }
+
+ bool isValid(void *) const { return true; }
+private:
+ Value m_value = plaintext;
};
class LANGUAGESERVERPROTOCOL_EXPORT MarkupContent : public JsonObject
@@ -390,15 +404,15 @@ public:
using JsonObject::JsonObject;
// The type of the Markup
- MarkupKind kind() const { return static_cast<MarkupKind>(typedValue<int>(kindKey)); }
- void setKind(MarkupKind kind) { insert(kindKey, static_cast<int>(kind)); }
+ MarkupKind kind() const { return value(kindKey); }
+ void setKind(MarkupKind kind) { insert(kindKey, kind); }
// The content itself
QString content() const { return typedValue<QString>(contentKey); }
void setContent(const QString &content) { insert(contentKey, content); }
bool isValid(QStringList *error) const override
- { return check<int>(error, kindKey) && check<QString>(error, contentKey); }
+ { return check<MarkupKind>(error, kindKey) && check<QString>(error, contentKey); }
};
class LANGUAGESERVERPROTOCOL_EXPORT MarkupOrString : public Utils::variant<QString, MarkupContent>
diff --git a/src/libs/languageserverprotocol/lsputils.h b/src/libs/languageserverprotocol/lsputils.h
index ee98db37f4..4646f181e9 100644
--- a/src/libs/languageserverprotocol/lsputils.h
+++ b/src/libs/languageserverprotocol/lsputils.h
@@ -71,6 +71,8 @@ public:
using Utils::variant<QList<T>, std::nullptr_t>::variant;
using Utils::variant<QList<T>, std::nullptr_t>::operator=;
+ LanguageClientArray() {}
+
LanguageClientArray(const QList<T> &list)
{ *this = list; }
diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp
index fcd1fadeac..6ebf4f431f 100644
--- a/src/libs/languageserverprotocol/servercapabilities.cpp
+++ b/src/libs/languageserverprotocol/servercapabilities.cpp
@@ -161,7 +161,7 @@ bool ServerCapabilities::WorkspaceServerCapabilities::WorkspaceFoldersCapabiliti
&& checkOptional<QString, bool>(error, changeNotificationsKey);
}
-bool TextDocumentRegistrationOptions::filterApplies(const Utils::FileName &fileName,
+bool TextDocumentRegistrationOptions::filterApplies(const Utils::FilePath &fileName,
const Utils::MimeType &mimeType) const
{
const LanguageClientArray<DocumentFilter> &selector = documentSelector();
diff --git a/src/libs/languageserverprotocol/servercapabilities.h b/src/libs/languageserverprotocol/servercapabilities.h
index 0e31821b17..71d3e4a496 100644
--- a/src/libs/languageserverprotocol/servercapabilities.h
+++ b/src/libs/languageserverprotocol/servercapabilities.h
@@ -52,7 +52,7 @@ public:
void setDocumentSelector(const LanguageClientArray<DocumentFilter> &documentSelector)
{ insert(documentSelectorKey, documentSelector.toJson()); }
- bool filterApplies(const Utils::FileName &fileName,
+ bool filterApplies(const Utils::FilePath &fileName,
const Utils::MimeType &mimeType = Utils::MimeType()) const;
bool isValid(QStringList *error) const override
@@ -268,7 +268,7 @@ public:
void setDocumentSelector(const LanguageClientArray<DocumentFilter> &documentSelector)
{ insert(documentSelectorKey, documentSelector.toJson()); }
- bool filterApplies(const Utils::FileName &fileName,
+ bool filterApplies(const Utils::FilePath &fileName,
const Utils::MimeType &mimeType = Utils::MimeType()) const;
// The id used to register the request. The id can be used to deregister
diff --git a/src/libs/languageserverprotocol/textsynchronization.h b/src/libs/languageserverprotocol/textsynchronization.h
index 2b659366cd..fa81cae51a 100644
--- a/src/libs/languageserverprotocol/textsynchronization.h
+++ b/src/libs/languageserverprotocol/textsynchronization.h
@@ -83,7 +83,7 @@ public:
void setTextDocument(const VersionedTextDocumentIdentifier &textDocument)
{ insert(textDocumentKey, textDocument); }
- class TextDocumentContentChangeEvent : public JsonObject
+ class LANGUAGESERVERPROTOCOL_EXPORT TextDocumentContentChangeEvent : public JsonObject
{
/*
* An event describing a change to a text document. If range and rangeLength are omitted
diff --git a/src/libs/languageserverprotocol/workspace.cpp b/src/libs/languageserverprotocol/workspace.cpp
index 9f73af2ac0..e411878877 100644
--- a/src/libs/languageserverprotocol/workspace.cpp
+++ b/src/libs/languageserverprotocol/workspace.cpp
@@ -98,4 +98,14 @@ ExecuteCommandParams::ExecuteCommandParams(const Command &command)
setArguments(command.arguments().value());
}
+LanguageServerProtocol::WorkSpaceFolderResult::operator const QJsonValue() const
+{
+ if (!Utils::holds_alternative<QList<WorkSpaceFolder>>(*this))
+ return QJsonValue::Null;
+ QJsonArray array;
+ for (auto folder : Utils::get<QList<WorkSpaceFolder>>(*this))
+ array.append(QJsonValue(folder));
+ return array;
+}
+
} // namespace LanguageServerProtocol
diff --git a/src/libs/languageserverprotocol/workspace.h b/src/libs/languageserverprotocol/workspace.h
index 5f69d2c782..bf6a1b9096 100644
--- a/src/libs/languageserverprotocol/workspace.h
+++ b/src/libs/languageserverprotocol/workspace.h
@@ -29,8 +29,17 @@
namespace LanguageServerProtocol {
+class LANGUAGESERVERPROTOCOL_EXPORT WorkSpaceFolderResult
+ : public Utils::variant<QList<WorkSpaceFolder>, std::nullptr_t>
+{
+public:
+ using variant::variant;
+ using variant::operator=;
+ operator const QJsonValue() const;
+};
+
class LANGUAGESERVERPROTOCOL_EXPORT WorkSpaceFolderRequest : public Request<
- Utils::variant<QList<WorkSpaceFolder>, Utils::nullopt_t>, std::nullptr_t, std::nullptr_t>
+ WorkSpaceFolderResult, std::nullptr_t, std::nullptr_t>
{
public:
WorkSpaceFolderRequest();
diff --git a/src/libs/languageutils/CMakeLists.txt b/src/libs/languageutils/CMakeLists.txt
new file mode 100644
index 0000000000..0cc47e7c60
--- /dev/null
+++ b/src/libs/languageutils/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_qtc_library(LanguageUtils
+ PUBLIC_DEPENDS Qt5::Core
+ SOURCES
+ componentversion.cpp componentversion.h
+ fakemetaobject.cpp fakemetaobject.h
+ languageutils_global.h
+)
diff --git a/src/libs/libs.pro b/src/libs/libs.pro
index 26495bbbf0..cbd788ced0 100644
--- a/src/libs/libs.pro
+++ b/src/libs/libs.pro
@@ -14,9 +14,9 @@ SUBDIRS += \
qmleditorwidgets \
glsl \
ssh \
- sqlite \
clangsupport \
- languageserverprotocol
+ languageserverprotocol \
+ sqlite
qtHaveModule(quick) {
SUBDIRS += \
diff --git a/src/libs/modelinglib/CMakeLists.txt b/src/libs/modelinglib/CMakeLists.txt
new file mode 100644
index 0000000000..7b09c932e4
--- /dev/null
+++ b/src/libs/modelinglib/CMakeLists.txt
@@ -0,0 +1,196 @@
+add_qtc_library(Modeling
+ DEFINES MODELING_LIBRARY
+ DEPENDS Qt5::Widgets Utils
+ PUBLIC_DEPENDS OptionalSvg
+ INCLUDES qtserialization/inc
+ PUBLIC_INCLUDES "${CMAKE_CURRENT_LIST_DIR}"
+ SOURCES
+ qmt/config/configcontroller.cpp qmt/config/configcontroller.h
+ qmt/config/sourcepos.cpp qmt/config/sourcepos.h
+ qmt/config/stereotypedefinitionparser.cpp qmt/config/stereotypedefinitionparser.h
+ qmt/config/stringtextsource.cpp qmt/config/stringtextsource.h
+ qmt/config/textscanner.cpp qmt/config/textscanner.h
+ qmt/config/textsource.h
+ qmt/config/token.cpp qmt/config/token.h
+ qmt/controller/container.h
+ qmt/controller/namecontroller.cpp qmt/controller/namecontroller.h
+ qmt/controller/references.h
+ qmt/controller/selection.cpp qmt/controller/selection.h
+ qmt/controller/undocommand.cpp qmt/controller/undocommand.h
+ qmt/controller/undocontroller.cpp qmt/controller/undocontroller.h
+ qmt/diagram_controller/dclonevisitor.cpp qmt/diagram_controller/dclonevisitor.h
+ qmt/diagram_controller/dcontainer.h
+ qmt/diagram_controller/dfactory.cpp qmt/diagram_controller/dfactory.h
+ qmt/diagram_controller/dflatassignmentvisitor.cpp qmt/diagram_controller/dflatassignmentvisitor.h
+ qmt/diagram_controller/diagramcontroller.cpp qmt/diagram_controller/diagramcontroller.h
+ qmt/diagram_controller/dreferences.h
+ qmt/diagram_controller/dselection.h
+ qmt/diagram_controller/dupdatevisitor.cpp qmt/diagram_controller/dupdatevisitor.h
+ qmt/diagram_controller/dvoidvisitor.cpp qmt/diagram_controller/dvoidvisitor.h
+ qmt/diagram/dannotation.cpp qmt/diagram/dannotation.h
+ qmt/diagram/dassociation.cpp qmt/diagram/dassociation.h
+ qmt/diagram/dboundary.cpp qmt/diagram/dboundary.h
+ qmt/diagram/dclass.cpp qmt/diagram/dclass.h
+ qmt/diagram/dcomponent.cpp qmt/diagram/dcomponent.h
+ qmt/diagram/dconnection.cpp qmt/diagram/dconnection.h
+ qmt/diagram/dconstvisitor.h
+ qmt/diagram/ddependency.cpp qmt/diagram/ddependency.h
+ qmt/diagram/ddiagram.cpp qmt/diagram/ddiagram.h
+ qmt/diagram/delement.cpp qmt/diagram/delement.h
+ qmt/diagram/dinheritance.cpp qmt/diagram/dinheritance.h
+ qmt/diagram/ditem.cpp qmt/diagram/ditem.h
+ qmt/diagram/dobject.cpp qmt/diagram/dobject.h
+ qmt/diagram/dpackage.cpp qmt/diagram/dpackage.h
+ qmt/diagram/drelation.cpp qmt/diagram/drelation.h
+ qmt/diagram/dswimlane.cpp qmt/diagram/dswimlane.h
+ qmt/diagram/dvisitor.h
+ qmt/diagram_scene/capabilities/alignable.h
+ qmt/diagram_scene/capabilities/editable.h
+ qmt/diagram_scene/capabilities/intersectionable.h
+ qmt/diagram_scene/capabilities/latchable.h
+ qmt/diagram_scene/capabilities/moveable.h
+ qmt/diagram_scene/capabilities/relationable.h
+ qmt/diagram_scene/capabilities/resizable.h
+ qmt/diagram_scene/capabilities/selectable.h
+ qmt/diagram_scene/capabilities/windable.h
+ qmt/diagram_scene/diagramgraphicsscene.cpp qmt/diagram_scene/diagramgraphicsscene.h
+ qmt/diagram_scene/diagramsceneconstants.h
+ qmt/diagram_scene/diagramscenemodel.cpp qmt/diagram_scene/diagramscenemodel.h
+ qmt/diagram_scene/diagramscenemodelitemvisitors.cpp qmt/diagram_scene/diagramscenemodelitemvisitors.h
+ qmt/diagram_scene/items/annotationitem.cpp qmt/diagram_scene/items/annotationitem.h
+ qmt/diagram_scene/items/associationitem.cpp qmt/diagram_scene/items/associationitem.h
+ qmt/diagram_scene/items/boundaryitem.cpp qmt/diagram_scene/items/boundaryitem.h
+ qmt/diagram_scene/items/classitem.cpp qmt/diagram_scene/items/classitem.h
+ qmt/diagram_scene/items/componentitem.cpp qmt/diagram_scene/items/componentitem.h
+ qmt/diagram_scene/items/connectionitem.cpp qmt/diagram_scene/items/connectionitem.h
+ qmt/diagram_scene/items/diagramitem.cpp qmt/diagram_scene/items/diagramitem.h
+ qmt/diagram_scene/items/itemitem.cpp qmt/diagram_scene/items/itemitem.h
+ qmt/diagram_scene/items/objectitem.cpp qmt/diagram_scene/items/objectitem.h
+ qmt/diagram_scene/items/packageitem.cpp qmt/diagram_scene/items/packageitem.h
+ qmt/diagram_scene/items/relationitem.cpp qmt/diagram_scene/items/relationitem.h
+ qmt/diagram_scene/items/stereotypedisplayvisitor.cpp qmt/diagram_scene/items/stereotypedisplayvisitor.h
+ qmt/diagram_scene/items/swimlaneitem.cpp qmt/diagram_scene/items/swimlaneitem.h
+ qmt/diagram_scene/latchcontroller.cpp qmt/diagram_scene/latchcontroller.h
+ qmt/diagram_scene/parts/alignbuttonsitem.cpp qmt/diagram_scene/parts/alignbuttonsitem.h
+ qmt/diagram_scene/parts/alignlineitem.cpp qmt/diagram_scene/parts/alignlineitem.h
+ qmt/diagram_scene/parts/arrowitem.cpp qmt/diagram_scene/parts/arrowitem.h
+ qmt/diagram_scene/parts/contextlabelitem.cpp qmt/diagram_scene/parts/contextlabelitem.h
+ qmt/diagram_scene/parts/customiconitem.cpp qmt/diagram_scene/parts/customiconitem.h
+ qmt/diagram_scene/parts/editabletextitem.cpp qmt/diagram_scene/parts/editabletextitem.h
+ qmt/diagram_scene/parts/pathselectionitem.cpp qmt/diagram_scene/parts/pathselectionitem.h
+ qmt/diagram_scene/parts/rectangularselectionitem.cpp qmt/diagram_scene/parts/rectangularselectionitem.h
+ qmt/diagram_scene/parts/relationstarter.cpp qmt/diagram_scene/parts/relationstarter.h
+ qmt/diagram_scene/parts/stereotypesitem.cpp qmt/diagram_scene/parts/stereotypesitem.h
+ qmt/diagram_scene/parts/templateparameterbox.cpp qmt/diagram_scene/parts/templateparameterbox.h
+ qmt/diagram_ui/diagram_mime_types.h
+ qmt/diagram_ui/diagramsmanager.cpp qmt/diagram_ui/diagramsmanager.h
+ qmt/diagram_ui/diagramsviewinterface.h
+ qmt/diagram_ui/sceneinspector.cpp qmt/diagram_ui/sceneinspector.h
+ qmt/diagram_widgets_ui/diagramsview.cpp qmt/diagram_widgets_ui/diagramsview.h
+ qmt/diagram_widgets_ui/diagramview.cpp qmt/diagram_widgets_ui/diagramview.h
+ qmt/diagram_widgets_ui/stackeddiagramsview.cpp qmt/diagram_widgets_ui/stackeddiagramsview.h
+ qmt/document_controller/documentcontroller.cpp qmt/document_controller/documentcontroller.h
+ qmt/infrastructure/contextmenuaction.cpp qmt/infrastructure/contextmenuaction.h
+ qmt/infrastructure/exceptions.cpp qmt/infrastructure/exceptions.h
+ qmt/infrastructure/geometryutilities.cpp qmt/infrastructure/geometryutilities.h
+ qmt/infrastructure/handle.h
+ qmt/infrastructure/handles.h
+ qmt/infrastructure/ioexceptions.cpp qmt/infrastructure/ioexceptions.h
+ qmt/infrastructure/qcompressedfile.cpp qmt/infrastructure/qcompressedfile.h
+ qmt/infrastructure/qmtassert.h
+ qmt/infrastructure/qmt_global.h
+ qmt/infrastructure/uid.h
+ qmt/model_controller/mchildrenvisitor.cpp qmt/model_controller/mchildrenvisitor.h
+ qmt/model_controller/mclonevisitor.cpp qmt/model_controller/mclonevisitor.h
+ qmt/model_controller/mcontainer.h
+ qmt/model_controller/mflatassignmentvisitor.cpp qmt/model_controller/mflatassignmentvisitor.h
+ qmt/model_controller/modelcontroller.cpp qmt/model_controller/modelcontroller.h
+ qmt/model_controller/mreferences.h
+ qmt/model_controller/mselection.h
+ qmt/model_controller/mvoidvisitor.cpp qmt/model_controller/mvoidvisitor.h
+ qmt/model/massociation.cpp qmt/model/massociation.h
+ qmt/model/mcanvasdiagram.cpp qmt/model/mcanvasdiagram.h
+ qmt/model/mclass.cpp qmt/model/mclass.h
+ qmt/model/mclassmember.cpp qmt/model/mclassmember.h
+ qmt/model/mcomponent.cpp qmt/model/mcomponent.h
+ qmt/model/mconnection.cpp qmt/model/mconnection.h
+ qmt/model/mconstvisitor.h
+ qmt/model/mdependency.cpp qmt/model/mdependency.h
+ qmt/model/mdiagram.cpp qmt/model/mdiagram.h
+ qmt/model/melement.cpp qmt/model/melement.h
+ qmt/model/minheritance.cpp qmt/model/minheritance.h
+ qmt/model/mitem.cpp qmt/model/mitem.h
+ qmt/model/mobject.cpp qmt/model/mobject.h
+ qmt/model/mpackage.cpp qmt/model/mpackage.h
+ qmt/model/mrelation.cpp qmt/model/mrelation.h
+ qmt/model/msourceexpansion.cpp qmt/model/msourceexpansion.h
+ qmt/model/mvisitor.h
+ qmt/model_ui/modeltreeviewinterface.h
+ qmt/model_ui/sortedtreemodel.cpp qmt/model_ui/sortedtreemodel.h
+ qmt/model_ui/stereotypescontroller.cpp qmt/model_ui/stereotypescontroller.h
+ qmt/model_ui/treemodel.cpp qmt/model_ui/treemodel.h
+ qmt/model_ui/treemodelmanager.cpp qmt/model_ui/treemodelmanager.h
+ qmt/model_widgets_ui/classmembersedit.cpp qmt/model_widgets_ui/classmembersedit.h
+ qmt/model_widgets_ui/modeltreeview.cpp qmt/model_widgets_ui/modeltreeview.h
+ qmt/model_widgets_ui/palettebox.cpp qmt/model_widgets_ui/palettebox.h
+ qmt/model_widgets_ui/propertiesview.cpp qmt/model_widgets_ui/propertiesview.h
+ qmt/model_widgets_ui/propertiesviewmview.cpp qmt/model_widgets_ui/propertiesviewmview.h
+ qmt/project_controller/projectcontroller.cpp qmt/project_controller/projectcontroller.h
+ qmt/project/project.cpp qmt/project/project.h
+ qmt/resources/resources.qrc
+ qmt/serializer/diagramserializer.cpp qmt/serializer/diagramserializer.h
+ qmt/serializer/infrastructureserializer.cpp qmt/serializer/infrastructureserializer.h
+ qmt/serializer/modelserializer.cpp qmt/serializer/modelserializer.h
+ qmt/serializer/projectserializer.cpp qmt/serializer/projectserializer.h
+ qmt/stereotype/customrelation.cpp qmt/stereotype/customrelation.h
+ qmt/stereotype/iconshape.cpp qmt/stereotype/iconshape.h
+ qmt/stereotype/shape.h
+ qmt/stereotype/shapepaintvisitor.cpp qmt/stereotype/shapepaintvisitor.h
+ qmt/stereotype/shapes.cpp qmt/stereotype/shapes.h
+ qmt/stereotype/shapevalue.cpp qmt/stereotype/shapevalue.h
+ qmt/stereotype/shapevisitor.h
+ qmt/stereotype/stereotypecontroller.cpp qmt/stereotype/stereotypecontroller.h
+ qmt/stereotype/stereotypeicon.cpp qmt/stereotype/stereotypeicon.h
+ qmt/stereotype/toolbar.cpp qmt/stereotype/toolbar.h
+ qmt/style/defaultstyle.cpp
+ qmt/style/defaultstyleengine.cpp qmt/style/defaultstyleengine.h
+ qmt/style/defaultstyle.h
+ qmt/style/objectvisuals.cpp qmt/style/objectvisuals.h
+ qmt/style/relationstarterstyle.cpp qmt/style/relationstarterstyle.h
+ qmt/style/stylecontroller.cpp qmt/style/stylecontroller.h
+ qmt/style/style.cpp
+ qmt/style/styledobject.cpp qmt/style/styledobject.h
+ qmt/style/styledrelation.cpp qmt/style/styledrelation.h
+ qmt/style/styleengine.h
+ qmt/style/style.h
+ qmt/tasks/alignonrastervisitor.cpp qmt/tasks/alignonrastervisitor.h
+ qmt/tasks/diagramscenecontroller.cpp qmt/tasks/diagramscenecontroller.h
+ qmt/tasks/finddiagramvisitor.cpp qmt/tasks/finddiagramvisitor.h
+ qmt/tasks/findrootdiagramvisitor.cpp qmt/tasks/findrootdiagramvisitor.h
+ qmt/tasks/ielementtasks.h
+ qmt/tasks/isceneinspector.h
+ qmt/tasks/voidelementtasks.cpp qmt/tasks/voidelementtasks.h
+ qstringparser/qstringparser.cpp qstringparser/qstringparser.h
+ qtserialization/inc/qark/access.h
+ qtserialization/inc/qark/archivebasics.h
+ qtserialization/inc/qark/attribute.h
+ qtserialization/inc/qark/baseclass.h
+ qtserialization/inc/qark/flag.h
+ qtserialization/inc/qark/friend_access.h
+ qtserialization/inc/qark/impl/loadingrefmap.h
+ qtserialization/inc/qark/impl/objectid.h
+ qtserialization/inc/qark/impl/savingrefmap.h
+ qtserialization/inc/qark/parameters.h
+ qtserialization/inc/qark/qxmlinarchive.h
+ qtserialization/inc/qark/qxmloutarchive.h
+ qtserialization/inc/qark/reference.h
+ qtserialization/inc/qark/serialize_basic.h
+ qtserialization/inc/qark/serialize_container.h
+ qtserialization/inc/qark/serialize_enum.h
+ qtserialization/inc/qark/serialize.h
+ qtserialization/inc/qark/serialize_pointer.h
+ qtserialization/inc/qark/tag.h
+ qtserialization/inc/qark/typeregistry.h
+ qtserialization/src/flag.cpp
+ qtserialization/src/savingrefmap.cpp
+)
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
index 37e74adeac..3bcc0727fb 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.cpp
@@ -173,14 +173,13 @@ void ModelTreeView::dragMoveEvent(QDragMoveEvent *event)
if (dynamic_cast<MObject*>(modelElement))
accept = true;
if (m_autoDelayIndex == dropIndex) {
- if (m_autoDelayStartTime.elapsed() > 1000) {
+ if (m_autoDelayStartTimer.elapsed() > 1000) {
setExpanded(dropIndex, !isExpanded(dropIndex));
- m_autoDelayStartTime.start();
+ m_autoDelayStartTimer.start();
}
} else {
m_autoDelayIndex = dropIndex;
- m_autoDelayStartTime = QTime::currentTime();
- m_autoDelayStartTime.start();
+ m_autoDelayStartTimer.start();
}
}
event->setAccepted(accept);
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h
index 724097a365..565d3671c2 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/modeltreeview.h
@@ -25,11 +25,11 @@
#pragma once
-#include <QTreeView>
#include "qmt/infrastructure/qmt_global.h"
#include "qmt/model_ui/modeltreeviewinterface.h"
-#include <QTime>
+#include <QElapsedTimer>
+#include <QTreeView>
namespace qmt {
@@ -70,7 +70,7 @@ private:
SortedTreeModel *m_sortedTreeModel = nullptr;
IElementTasks *m_elementTasks = nullptr;
QModelIndex m_autoDelayIndex;
- QTime m_autoDelayStartTime;
+ QElapsedTimer m_autoDelayStartTimer;
};
} // namespace qmt
diff --git a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
index 63d716d2d1..c8b11d44e1 100644
--- a/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
+++ b/src/libs/modelinglib/qmt/model_widgets_ui/propertiesviewmview.cpp
@@ -352,7 +352,7 @@ 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);
- connect(m_stereotypeComboBox, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated),
+ connect(m_stereotypeComboBox, QOverload<const QString &>::of(&QComboBox::activated),
this, &PropertiesView::MView::onStereotypesChanged);
}
if (!m_stereotypeComboBox->hasFocus()) {
@@ -580,7 +580,7 @@ void PropertiesView::MView::visitMDependency(const MDependency *dependency)
m_directionSelector = new QComboBox(m_topWidget);
m_directionSelector->addItems(QStringList({ "->", "<-", "<->" }));
addRow(tr("Direction:"), m_directionSelector, "direction");
- connect(m_directionSelector, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ connect(m_directionSelector, QOverload<int>::of(&QComboBox::activated),
this, &PropertiesView::MView::onDependencyDirectionChanged);
}
if (isSingleSelection) {
@@ -664,7 +664,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
m_endAKind = new QComboBox(m_topWidget);
m_endAKind->addItems({ tr("Association"), tr("Aggregation"), tr("Composition") });
addRow(tr("Relationship:"), m_endAKind, "relationship a");
- connect(m_endAKind, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ connect(m_endAKind, QOverload<int>::of(&QComboBox::activated),
this, &PropertiesView::MView::onAssociationEndAKindChanged);
}
if (isSingleSelection) {
@@ -729,7 +729,7 @@ void PropertiesView::MView::visitMAssociation(const MAssociation *association)
m_endBKind = new QComboBox(m_topWidget);
m_endBKind->addItems({ tr("Association"), tr("Aggregation"), tr("Composition") });
addRow(tr("Relationship:"), m_endBKind, "relationship b");
- connect(m_endBKind, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ connect(m_endBKind, QOverload<int>::of(&QComboBox::activated),
this, &PropertiesView::MView::onAssociationEndBKindChanged);
}
if (isSingleSelection) {
@@ -930,7 +930,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
m_visualSecondaryRoleSelector->addItems({ tr("Normal"), tr("Lighter"), tr("Darker"),
tr("Soften"), tr("Outline"), tr("Flat") });
addRow(tr("Role:"), m_visualSecondaryRoleSelector, "role");
- connect(m_visualSecondaryRoleSelector, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ connect(m_visualSecondaryRoleSelector, QOverload<int>::of(&QComboBox::activated),
this, &PropertiesView::MView::onVisualSecondaryRoleChanged);
}
if (!m_visualSecondaryRoleSelector->hasFocus()) {
@@ -958,7 +958,7 @@ void PropertiesView::MView::visitDObject(const DObject *object)
m_stereotypeDisplaySelector->addItems({ tr("Smart"), tr("None"), tr("Label"),
tr("Decoration"), tr("Icon") });
addRow(tr("Stereotype display:"), m_stereotypeDisplaySelector, "stereotype display");
- connect(m_stereotypeDisplaySelector, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ connect(m_stereotypeDisplaySelector, QOverload<int>::of(&QComboBox::activated),
this, &PropertiesView::MView::onStereotypeDisplayChanged);
}
if (!m_stereotypeDisplaySelector->hasFocus()) {
@@ -995,7 +995,7 @@ void PropertiesView::MView::visitDClass(const DClass *klass)
m_templateDisplaySelector = new QComboBox(m_topWidget);
m_templateDisplaySelector->addItems({ tr("Smart"), tr("Box"), tr("Angle Brackets") });
addRow(tr("Template display:"), m_templateDisplaySelector, "template display");
- connect(m_templateDisplaySelector, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ connect(m_templateDisplaySelector, QOverload<int>::of(&QComboBox::activated),
this, &PropertiesView::MView::onTemplateDisplayChanged);
}
if (!m_templateDisplaySelector->hasFocus()) {
@@ -1126,7 +1126,7 @@ void PropertiesView::MView::visitDAnnotation(const DAnnotation *annotation)
tr("Subtitle"), tr("Emphasized"),
tr("Soften"), tr("Footnote") }));
addRow(tr("Role:"), m_annotationVisualRoleSelector, "visual role");
- connect(m_annotationVisualRoleSelector, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
+ connect(m_annotationVisualRoleSelector, QOverload<int>::of(&QComboBox::activated),
this, &PropertiesView::MView::onAnnotationVisualRoleChanged);
}
if (!m_annotationVisualRoleSelector->hasFocus()) {
diff --git a/src/libs/qmldebug/CMakeLists.txt b/src/libs/qmldebug/CMakeLists.txt
new file mode 100644
index 0000000000..cdc4c36fb4
--- /dev/null
+++ b/src/libs/qmldebug/CMakeLists.txt
@@ -0,0 +1,18 @@
+add_qtc_library(QmlDebug
+ DEPENDS Qt5::Network Utils
+ SOURCES
+ baseenginedebugclient.cpp baseenginedebugclient.h
+ basetoolsclient.cpp basetoolsclient.h
+ qdebugmessageclient.cpp qdebugmessageclient.h
+ qmldebug_global.h
+ qmldebugclient.cpp qmldebugclient.h
+ qmldebugcommandlinearguments.h
+ qmldebugconnection.cpp qmldebugconnection.h
+ qmldebugconnectionmanager.cpp qmldebugconnectionmanager.h
+ qmldebugconstants.h
+ qmlenginecontrolclient.cpp qmlenginecontrolclient.h
+ qmlenginedebugclient.h
+ qmloutputparser.cpp qmloutputparser.h
+ qmltoolsclient.cpp qmltoolsclient.h
+ qpacketprotocol.cpp qpacketprotocol.h
+)
diff --git a/src/libs/qmldebug/baseenginedebugclient.cpp b/src/libs/qmldebug/baseenginedebugclient.cpp
index 86f54741fc..45cf7590c9 100644
--- a/src/libs/qmldebug/baseenginedebugclient.cpp
+++ b/src/libs/qmldebug/baseenginedebugclient.cpp
@@ -121,7 +121,7 @@ void BaseEngineDebugClient::decode(QDataStream &ds,
{
ObjectReference obj;
obj.m_debugId = prop.m_value.toInt();
- prop.m_value = qVariantFromValue(obj);
+ prop.m_value = QVariant::fromValue(obj);
break;
}
case QmlObjectProperty::Unknown:
diff --git a/src/libs/qmldebug/qmldebugcommandlinearguments.h b/src/libs/qmldebug/qmldebugcommandlinearguments.h
index 0e265c27cc..0c9979647a 100644
--- a/src/libs/qmldebug/qmldebugcommandlinearguments.h
+++ b/src/libs/qmldebug/qmldebugcommandlinearguments.h
@@ -39,7 +39,7 @@ enum QmlDebugServicesPreset {
QmlPreviewServices
};
-static inline QString qmlDebugServices(QmlDebugServicesPreset preset)
+inline QString qmlDebugServices(QmlDebugServicesPreset preset)
{
switch (preset) {
case NoQmlDebugServices:
@@ -58,7 +58,7 @@ static inline QString qmlDebugServices(QmlDebugServicesPreset preset)
}
}
-static inline QString qmlDebugCommandLineArguments(QmlDebugServicesPreset services,
+inline QString qmlDebugCommandLineArguments(QmlDebugServicesPreset services,
const QString &connectionMode, bool block)
{
if (services == NoQmlDebugServices)
@@ -68,19 +68,19 @@ static inline QString qmlDebugCommandLineArguments(QmlDebugServicesPreset servic
.arg(QLatin1String(block ? ",block" : "")).arg(qmlDebugServices(services));
}
-static inline QString qmlDebugTcpArguments(QmlDebugServicesPreset services,
- Utils::Port port, bool block = true)
+inline QString qmlDebugTcpArguments(QmlDebugServicesPreset services,
+ Utils::Port port, bool block = true)
{
return qmlDebugCommandLineArguments(services, QString("port:%1").arg(port.number()), block);
}
-static inline QString qmlDebugNativeArguments(QmlDebugServicesPreset services, bool block = true)
+inline QString qmlDebugNativeArguments(QmlDebugServicesPreset services, bool block = true)
{
return qmlDebugCommandLineArguments(services, QLatin1String("native"), block);
}
-static inline QString qmlDebugLocalArguments(QmlDebugServicesPreset services, const QString &socket,
- bool block = true)
+inline QString qmlDebugLocalArguments(QmlDebugServicesPreset services, const QString &socket,
+ bool block = true)
{
return qmlDebugCommandLineArguments(services, QLatin1String("file:") + socket, block);
}
diff --git a/src/libs/qmldebug/qmldebugconnection.cpp b/src/libs/qmldebug/qmldebugconnection.cpp
index 6664df2b99..143277b379 100644
--- a/src/libs/qmldebug/qmldebugconnection.cpp
+++ b/src/libs/qmldebug/qmldebugconnection.cpp
@@ -45,17 +45,16 @@ const QString clientId = QLatin1String("QDeclarativeDebugClient");
class QmlDebugConnectionPrivate
{
public:
- QmlDebugConnectionPrivate();
- QPacketProtocol *protocol;
- QLocalServer *server;
- QIODevice *device; // Currently a QTcpSocket or a QLocalSocket
+ QPacketProtocol *protocol = nullptr;
+ QLocalServer *server = nullptr;
+ QIODevice *device = nullptr; // Currently a QTcpSocket or a QLocalSocket
- bool gotHello;
+ bool gotHello = false;
QHash <QString, float> serverPlugins;
QHash<QString, QmlDebugClient *> plugins;
- int currentDataStreamVersion;
- int maximumDataStreamVersion;
+ int currentDataStreamVersion = QmlDebugConnection::minimumDataStreamVersion();
+ int maximumDataStreamVersion = QDataStream::Qt_DefaultCompiledVersion;
void advertisePlugins();
void flush();
@@ -75,13 +74,6 @@ static QString socketErrorToString(QAbstractSocket::SocketError error)
return QmlDebugConnection::tr("Error: %1").arg(errorString);
}
-QmlDebugConnectionPrivate::QmlDebugConnectionPrivate() :
- protocol(0), server(0), device(0), gotHello(false),
- currentDataStreamVersion(QmlDebugConnection::minimumDataStreamVersion()),
- maximumDataStreamVersion(QDataStream::Qt_DefaultCompiledVersion)
-{
-}
-
void QmlDebugConnectionPrivate::advertisePlugins()
{
if (!gotHello)
@@ -118,7 +110,7 @@ void QmlDebugConnection::socketDisconnected()
if (d->protocol) {
d->protocol->disconnect();
d->protocol->deleteLater();
- d->protocol = 0;
+ d->protocol = nullptr;
}
if (d->device) {
// Don't allow any "connected()" or "disconnected()" signals to be triggered anymore.
@@ -126,7 +118,7 @@ void QmlDebugConnection::socketDisconnected()
d->device->disconnect();
// Don't immediately delete it as it may do some cleanup on returning from a signal.
d->device->deleteLater();
- d->device = 0;
+ d->device = nullptr;
}
}
@@ -220,7 +212,7 @@ void QmlDebugConnection::protocolReadyRead()
QHash<QString, QmlDebugClient *>::Iterator iter = d->plugins.begin();
for (; iter != d->plugins.end(); ++iter) {
- const QString pluginName = iter.key();
+ const QString &pluginName = iter.key();
QmlDebugClient::State newState = QmlDebugClient::Unavailable;
if (d->serverPlugins.contains(pluginName))
newState = QmlDebugClient::Enabled;
@@ -282,7 +274,7 @@ void QmlDebugConnection::close()
QmlDebugClient *QmlDebugConnection::client(const QString &name) const
{
Q_D(const QmlDebugConnection);
- return d->plugins.value(name, 0);
+ return d->plugins.value(name, nullptr);
}
bool QmlDebugConnection::addClient(const QString &name, QmlDebugClient *client)
@@ -324,16 +316,11 @@ bool QmlDebugConnection::sendMessage(const QString &name, const QByteArray &mess
return true;
}
-int QmlDebugConnection::minimumDataStreamVersion()
-{
- return QDataStream::Qt_4_7;
-}
-
void QmlDebugConnectionPrivate::flush()
{
- if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(device))
+ if (auto socket = qobject_cast<QAbstractSocket *>(device))
socket->flush();
- else if (QLocalSocket *socket = qobject_cast<QLocalSocket *>(device))
+ else if (auto socket = qobject_cast<QLocalSocket *>(device))
socket->flush();
}
@@ -341,7 +328,7 @@ void QmlDebugConnection::connectToHost(const QString &hostName, quint16 port)
{
Q_D(QmlDebugConnection);
socketDisconnected();
- QTcpSocket *socket = new QTcpSocket(this);
+ auto socket = new QTcpSocket(this);
socket->setProxy(QNetworkProxy::NoProxy);
d->device = socket;
d->protocol = new QPacketProtocol(socket, this);
@@ -352,8 +339,8 @@ void QmlDebugConnection::connectToHost(const QString &hostName, quint16 port)
emit logStateChange(socketStateToString(state));
});
- connect(socket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>
- (&QAbstractSocket::error), this, [this](QAbstractSocket::SocketError error) {
+ connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),
+ this, [this](QAbstractSocket::SocketError error) {
emit logError(socketErrorToString(error));
socketDisconnected();
});
@@ -391,8 +378,8 @@ void QmlDebugConnection::newConnection()
connect(socket, &QLocalSocket::disconnected, this, &QmlDebugConnection::socketDisconnected);
- connect(socket, static_cast<void (QLocalSocket::*)(QLocalSocket::LocalSocketError)>
- (&QLocalSocket::error), this, [this](QLocalSocket::LocalSocketError error) {
+ connect(socket, QOverload<QLocalSocket::LocalSocketError>::of(&QLocalSocket::error),
+ this, [this](QLocalSocket::LocalSocketError error) {
emit logError(socketErrorToString(static_cast<QAbstractSocket::SocketError>(error)));
socketDisconnected();
});
@@ -420,12 +407,11 @@ void QmlDebugConnection::setMaximumDataStreamVersion(int maximumVersion)
QAbstractSocket::SocketState QmlDebugConnection::socketState() const
{
Q_D(const QmlDebugConnection);
- if (QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(d->device))
+ if (auto socket = qobject_cast<QAbstractSocket *>(d->device))
return socket->state();
- else if (QLocalSocket *socket = qobject_cast<QLocalSocket *>(d->device))
+ if (auto socket = qobject_cast<QLocalSocket *>(d->device))
return static_cast<QAbstractSocket::SocketState>(socket->state());
- else
- return QAbstractSocket::UnconnectedState;
+ return QAbstractSocket::UnconnectedState;
}
} // namespace QmlDebug
diff --git a/src/libs/qmldebug/qmldebugconnection.h b/src/libs/qmldebug/qmldebugconnection.h
index 6fe2e35a16..6ca73a1f3c 100644
--- a/src/libs/qmldebug/qmldebugconnection.h
+++ b/src/libs/qmldebug/qmldebugconnection.h
@@ -30,6 +30,7 @@
#include <QObject>
#include <QUrl>
#include <QAbstractSocket>
+#include <QDataStream>
namespace QmlDebug {
@@ -38,10 +39,9 @@ class QmlDebugConnectionPrivate;
class QMLDEBUG_EXPORT QmlDebugConnection : public QObject
{
Q_OBJECT
- Q_DISABLE_COPY(QmlDebugConnection)
Q_DECLARE_PRIVATE(QmlDebugConnection)
public:
- QmlDebugConnection(QObject * = 0);
+ QmlDebugConnection(QObject *parent = nullptr);
~QmlDebugConnection() override;
void connectToHost(const QString &hostName, quint16 port);
@@ -62,7 +62,10 @@ public:
float serviceVersion(const QString &serviceName) const;
bool sendMessage(const QString &name, const QByteArray &message);
- static int minimumDataStreamVersion();
+ static constexpr int minimumDataStreamVersion()
+ {
+ return QDataStream::Qt_4_7;
+ }
signals:
void connected();
diff --git a/src/libs/qmleditorwidgets/CMakeLists.txt b/src/libs/qmleditorwidgets/CMakeLists.txt
new file mode 100644
index 0000000000..b235601754
--- /dev/null
+++ b/src/libs/qmleditorwidgets/CMakeLists.txt
@@ -0,0 +1,22 @@
+add_qtc_library(QmlEditorWidgets
+ DEPENDS qmljs Utils Qt5::Widgets
+ SOURCES
+ colorbox.cpp colorbox.h
+ colorbutton.cpp colorbutton.h
+ contextpanetext.ui
+ contextpanetextwidget.cpp contextpanetextwidget.h
+ contextpanewidget.cpp contextpanewidget.h
+ contextpanewidgetborderimage.ui
+ contextpanewidgetimage.cpp contextpanewidgetimage.h contextpanewidgetimage.ui
+ contextpanewidgetrectangle.cpp contextpanewidgetrectangle.h contextpanewidgetrectangle.ui
+ customcolordialog.cpp customcolordialog.h
+ easingpane/easingcontextpane.cpp easingpane/easingcontextpane.h easingpane/easingcontextpane.ui
+ easingpane/easinggraph.cpp easingpane/easinggraph.h
+ easingpane/easingpane.qrc
+ filewidget.cpp filewidget.h
+ fontsizespinbox.cpp fontsizespinbox.h
+ gradientline.cpp gradientline.h
+ huecontrol.cpp huecontrol.h
+ qmleditorwidgets_global.h
+ resources.qrc
+)
diff --git a/src/libs/qmleditorwidgets/colorbox.cpp b/src/libs/qmleditorwidgets/colorbox.cpp
index ad8109c27d..b0da2642e2 100644
--- a/src/libs/qmleditorwidgets/colorbox.cpp
+++ b/src/libs/qmleditorwidgets/colorbox.cpp
@@ -29,12 +29,10 @@
static inline QString properName(const QColor &color)
{
- QString s;
if (color.alpha() == 255)
- s.sprintf("#%02x%02x%02x", color.red(), color.green(), color.blue());
+ return QString::asprintf("#%02x%02x%02x", color.red(), color.green(), color.blue());
else
- s.sprintf("#%02x%02x%02x%02x", color.alpha(), color.red(), color.green(), color.blue());
- return s;
+ return QString::asprintf("#%02x%02x%02x%02x", color.alpha(), color.red(), color.green(), color.blue());
}
static inline QColor properColor(const QString &str)
diff --git a/src/libs/qmleditorwidgets/contextpanetextwidget.cpp b/src/libs/qmleditorwidgets/contextpanetextwidget.cpp
index bba9bf4d95..70b6c700db 100644
--- a/src/libs/qmleditorwidgets/contextpanetextwidget.cpp
+++ b/src/libs/qmleditorwidgets/contextpanetextwidget.cpp
@@ -73,8 +73,7 @@ ContextPaneTextWidget::ContextPaneTextWidget(QWidget *parent) :
connect(parentContextWidget->colorDialog(), &CustomColorDialog::rejected,
this, &ContextPaneTextWidget::onColorDialogCancled);
- connect(ui->fontSizeSpinBox,
- static_cast<void (QmlEditorWidgets::FontSizeSpinBox::*)(int)>(&QmlEditorWidgets::FontSizeSpinBox::valueChanged),
+ connect(ui->fontSizeSpinBox, QOverload<int>::of(&QmlEditorWidgets::FontSizeSpinBox::valueChanged),
this, &ContextPaneTextWidget::onFontSizeChanged);
connect(ui->fontSizeSpinBox, &QmlEditorWidgets::FontSizeSpinBox::formatChanged,
this, &ContextPaneTextWidget::onFontFormatChanged);
@@ -104,7 +103,7 @@ ContextPaneTextWidget::ContextPaneTextWidget(QWidget *parent) :
connect(ui->bottomAlignmentButton, &QToolButton::toggled,
this, &ContextPaneTextWidget::onVerticalAlignmentChanged);
- connect(ui->styleComboBox, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged),
+ connect(ui->styleComboBox, QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
this, &ContextPaneTextWidget::onStyleComboBoxChanged);
}
diff --git a/src/libs/qmleditorwidgets/customcolordialog.cpp b/src/libs/qmleditorwidgets/customcolordialog.cpp
index a99410467f..de603e0ea9 100644
--- a/src/libs/qmleditorwidgets/customcolordialog.cpp
+++ b/src/libs/qmleditorwidgets/customcolordialog.cpp
@@ -113,17 +113,13 @@ CustomColorDialog::CustomColorDialog(QWidget *parent) : QFrame(parent )
resize(sizeHint());
connect(m_colorBox, &ColorBox::colorChanged, this, &CustomColorDialog::onColorBoxChanged);
- connect(m_alphaSpinBox,
- static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ connect(m_alphaSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this, &CustomColorDialog::spinBoxChanged);
- connect(m_rSpinBox,
- static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ connect(m_rSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this, &CustomColorDialog::spinBoxChanged);
- connect(m_gSpinBox,
- static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ connect(m_gSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this, &CustomColorDialog::spinBoxChanged);
- connect(m_bSpinBox,
- static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
+ connect(m_bSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
this, &CustomColorDialog::spinBoxChanged);
connect(m_hueControl, &HueControl::hueChanged, this, &CustomColorDialog::onHueChanged);
diff --git a/src/libs/qmljs/CMakeLists.txt b/src/libs/qmljs/CMakeLists.txt
new file mode 100644
index 0000000000..6a4ef362bc
--- /dev/null
+++ b/src/libs/qmljs/CMakeLists.txt
@@ -0,0 +1,53 @@
+add_qtc_library(qmljs
+ DEPENDS ExtensionSystem Utils
+ PUBLIC_DEPENDS CPlusPlus Qt5::Widgets Qt5::Xml LanguageUtils
+ SOURCES
+ jsoncheck.cpp jsoncheck.h
+ parser/qmldirparser.cpp parser/qmldirparser_p.h
+ parser/qmlerror.cpp parser/qmlerror.h
+ parser/qmljsast.cpp parser/qmljsast_p.h
+ parser/qmljsastfwd_p.h
+ parser/qmljsastvisitor.cpp parser/qmljsastvisitor_p.h
+ parser/qmljsengine_p.cpp parser/qmljsengine_p.h
+ parser/qmljsglobal_p.h
+ parser/qmljsgrammar.cpp parser/qmljsgrammar_p.h
+ parser/qmljskeywords_p.h
+ parser/qmljslexer.cpp parser/qmljslexer_p.h
+ parser/qmljsmemorypool_p.h
+ parser/qmljsparser.cpp parser/qmljsparser_p.h
+ persistenttrie.cpp persistenttrie.h
+ qmljs_global.h
+ qmljsbind.cpp qmljsbind.h
+ qmljsbundle.cpp qmljsbundle.h
+ qmljscheck.cpp qmljscheck.h
+ qmljscodeformatter.cpp qmljscodeformatter.h
+ qmljscompletioncontextfinder.cpp qmljscompletioncontextfinder.h
+ qmljsconstants.h
+ qmljscontext.cpp qmljscontext.h
+ qmljsdialect.cpp qmljsdialect.h
+ qmljsdocument.cpp qmljsdocument.h
+ qmljsevaluate.cpp qmljsevaluate.h
+ qmljsfindexportedcpptypes.cpp qmljsfindexportedcpptypes.h
+ qmljsicons.cpp qmljsicons.h
+ qmljsicontextpane.h
+ qmljsimportdependencies.cpp qmljsimportdependencies.h
+ qmljsindenter.cpp qmljsindenter.h
+ qmljsinterpreter.cpp qmljsinterpreter.h
+ qmljslineinfo.cpp qmljslineinfo.h
+ qmljslink.cpp qmljslink.h
+ qmljsmodelmanagerinterface.cpp qmljsmodelmanagerinterface.h
+ qmljsplugindumper.cpp qmljsplugindumper.h
+ qmljspropertyreader.cpp qmljspropertyreader.h
+ qmljsreformatter.cpp qmljsreformatter.h
+ qmljsrewriter.cpp qmljsrewriter.h
+ qmljsscanner.cpp qmljsscanner.h
+ qmljsscopeastpath.cpp qmljsscopeastpath.h
+ qmljsscopebuilder.cpp qmljsscopebuilder.h
+ qmljsscopechain.cpp qmljsscopechain.h
+ qmljssimplereader.cpp qmljssimplereader.h
+ qmljsstaticanalysismessage.cpp qmljsstaticanalysismessage.h
+ qmljstypedescriptionreader.cpp qmljstypedescriptionreader.h
+ qmljsutils.cpp qmljsutils.h
+ qmljsvalueowner.cpp qmljsvalueowner.h
+ qmljsviewercontext.cpp qmljsviewercontext.h
+)
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
index 19d367be1b..ab7a33917e 100644
--- a/src/libs/qmljs/parser/qmljslexer.cpp
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
@@ -116,6 +116,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_tokenText.reserve(1024);
_errorMessage.clear();
_tokenSpell = QStringRef();
+ _rawString = QStringRef();
_codePtr = code.unicode();
_endPtr = _codePtr + code.length();
@@ -149,13 +150,20 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
void Lexer::scanChar()
{
- unsigned sequenceLength = isLineTerminatorSequence();
+ if (_skipLinefeed) {
+ Q_ASSERT(*_codePtr == QLatin1Char('\n'));
+ ++_codePtr;
+ _skipLinefeed = false;
+ }
_char = *_codePtr++;
- if (sequenceLength == 2)
- _char = *_codePtr++;
-
++_currentColumnNumber;
+
if (isLineTerminator()) {
+ if (_char == QLatin1Char('\r')) {
+ if (_codePtr < _endPtr && *_codePtr == QLatin1Char('\n'))
+ _skipLinefeed = true;
+ _char = QLatin1Char('\n');
+ }
++_currentLineNumber;
_currentColumnNumber = 0;
}
@@ -232,6 +240,7 @@ int Lexer::lex()
again:
_tokenSpell = QStringRef();
+ _rawString = QStringRef();
_tokenKind = scanToken();
_tokenLength = _codePtr - _tokenStartPtr - 1;
@@ -807,12 +816,15 @@ int Lexer::scanString(ScanStringMode mode)
QChar quote = (mode == TemplateContinuation) ? QChar(TemplateHead) : QChar(mode);
bool multilineStringLiteral = false;
- const QChar *startCode = _codePtr;
+ const QChar *startCode = _codePtr - 1;
+ // in case we just parsed a \r, we need to reset this flag to get things working
+ // correctly in the loop below and afterwards
+ _skipLinefeed = false;
if (_engine) {
while (_codePtr <= _endPtr) {
- if (isLineTerminator() && quote != QLatin1Char('`')) {
- if (qmlMode())
+ if (isLineTerminator()) {
+ if ((quote == QLatin1Char('`') || qmlMode()))
break;
_errorCode = IllegalCharacter;
_errorMessage = QCoreApplication::translate("QmlParser", "Stray newline in string literal");
@@ -822,7 +834,8 @@ int Lexer::scanString(ScanStringMode mode)
} else if (_char == '$' && quote == QLatin1Char('`')) {
break;
} else if (_char == quote) {
- _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
+ _tokenSpell = _engine->midRef(startCode - _code.unicode(), _codePtr - startCode - 1);
+ _rawString = _tokenSpell;
scanChar();
if (quote == QLatin1Char('`'))
@@ -835,28 +848,36 @@ int Lexer::scanString(ScanStringMode mode)
else
return T_STRING_LITERAL;
}
- scanChar();
+ // don't use scanChar() here, that would transform \r sequences and the midRef() call would create the wrong result
+ _char = *_codePtr++;
+ ++_currentColumnNumber;
}
}
+ // rewind by one char, so things gets scanned correctly
+ --_codePtr;
+
_validTokenText = true;
- _tokenText.resize(0);
- startCode--;
- while (startCode != _codePtr - 1)
- _tokenText += *startCode++;
+ _tokenText = QString(startCode, _codePtr - startCode);
+
+ auto setRawString = [&](const QChar *end) {
+ QString raw(startCode, end - startCode - 1);
+ raw.replace(QLatin1String("\r\n"), QLatin1String("\n"));
+ raw.replace(QLatin1Char('\r'), QLatin1Char('\n'));
+ _rawString = _engine->newStringRef(raw);
+ };
+
+ scanChar();
while (_codePtr <= _endPtr) {
- if (unsigned sequenceLength = isLineTerminatorSequence()) {
- multilineStringLiteral = true;
- _tokenText += _char;
- if (sequenceLength == 2)
- _tokenText += *_codePtr;
- scanChar();
- } else if (_char == mode) {
+ if (_char == quote) {
scanChar();
- if (_engine)
+ if (_engine) {
_tokenSpell = _engine->newStringRef(_tokenText);
+ if (quote == QLatin1Char('`'))
+ setRawString(_codePtr - 1);
+ }
if (quote == QLatin1Char('`'))
_bracesCount = _outerTemplateBraceCount.pop();
@@ -871,8 +892,10 @@ int Lexer::scanString(ScanStringMode mode)
scanChar();
scanChar();
_bracesCount = 1;
- if (_engine)
+ if (_engine) {
_tokenSpell = _engine->newStringRef(_tokenText);
+ setRawString(_codePtr - 2);
+ }
return (mode == TemplateHead ? T_TEMPLATE_HEAD : T_TEMPLATE_MIDDLE);
} else if (_char == QLatin1Char('\\')) {
diff --git a/src/libs/qmljs/parser/qmljslexer_p.h b/src/libs/qmljs/parser/qmljslexer_p.h
index 39128b4409..5773606c39 100644
--- a/src/libs/qmljs/parser/qmljslexer_p.h
+++ b/src/libs/qmljs/parser/qmljslexer_p.h
@@ -146,6 +146,7 @@ public:
int tokenStartColumn() const { return _tokenColumn; }
inline QStringRef tokenSpell() const { return _tokenSpell; }
+ inline QStringRef rawString() const { return _rawString; }
double tokenValue() const { return _tokenValue; }
QString tokenText() const;
@@ -198,6 +199,7 @@ private:
QString _tokenText;
QString _errorMessage;
QStringRef _tokenSpell;
+ QStringRef _rawString;
const QChar *_codePtr;
const QChar *_endPtr;
@@ -233,6 +235,7 @@ private:
bool _followsClosingBrace;
bool _delimited;
bool _qmlMode;
+ bool _skipLinefeed = false;
int _generatorLevel = 0;
bool _staticIsKeyword = false;
};
diff --git a/src/libs/qmljs/persistenttrie.cpp b/src/libs/qmljs/persistenttrie.cpp
index f3be5a48ca..08c17dd164 100644
--- a/src/libs/qmljs/persistenttrie.cpp
+++ b/src/libs/qmljs/persistenttrie.cpp
@@ -545,7 +545,6 @@ QDebug &operator<<(QDebug &dbg, const Trie &trie)
}
Trie::Trie() {}
Trie::Trie(const TrieNode::Ptr &trie) : trie(trie) {}
-Trie::Trie(const Trie &o) : trie(o.trie){}
QStringList Trie::complete(const QString &root, const QString &base,
LookupFlags flags) const
diff --git a/src/libs/qmljs/persistenttrie.h b/src/libs/qmljs/persistenttrie.h
index 35ab652967..184525b13e 100644
--- a/src/libs/qmljs/persistenttrie.h
+++ b/src/libs/qmljs/persistenttrie.h
@@ -79,7 +79,6 @@ class QMLJS_EXPORT Trie
public:
Trie();
Trie(const TrieNode::Ptr &t);
- Trie(const Trie &o);
QStringList complete(const QString &root, const QString &base = QString(),
LookupFlags flags = LookupFlags(CaseInsensitive|Partial)) const;
diff --git a/src/libs/qmljs/qmljs-lib.pri b/src/libs/qmljs/qmljs-lib.pri
index 2aa95a9f7a..47967446bf 100644
--- a/src/libs/qmljs/qmljs-lib.pri
+++ b/src/libs/qmljs/qmljs-lib.pri
@@ -36,7 +36,6 @@ HEADERS += \
$$PWD/jsoncheck.h \
$$PWD/qmljssimplereader.h \
$$PWD/persistenttrie.h \
- $$PWD/qmljsqrcparser.h \
$$PWD/qmljsconstants.h \
$$PWD/qmljsimportdependencies.h \
$$PWD/qmljsviewercontext.h \
@@ -70,7 +69,6 @@ SOURCES += \
$$PWD/jsoncheck.cpp \
$$PWD/qmljssimplereader.cpp \
$$PWD/persistenttrie.cpp \
- $$PWD/qmljsqrcparser.cpp \
$$PWD/qmljsimportdependencies.cpp \
$$PWD/qmljsviewercontext.cpp \
$$PWD/qmljsdialect.cpp
diff --git a/src/libs/qmljs/qmljs.qbs b/src/libs/qmljs/qmljs.qbs
index ddfb4c200e..a2580cab1e 100644
--- a/src/libs/qmljs/qmljs.qbs
+++ b/src/libs/qmljs/qmljs.qbs
@@ -42,7 +42,6 @@ Project {
"qmljsmodelmanagerinterface.cpp", "qmljsmodelmanagerinterface.h",
"qmljsplugindumper.cpp", "qmljsplugindumper.h",
"qmljspropertyreader.cpp", "qmljspropertyreader.h",
- "qmljsqrcparser.cpp", "qmljsqrcparser.h",
"qmljsreformatter.cpp", "qmljsreformatter.h",
"qmljsrewriter.cpp", "qmljsrewriter.h",
"qmljsscanner.cpp", "qmljsscanner.h",
diff --git a/src/libs/qmljs/qmljsbundle.cpp b/src/libs/qmljs/qmljsbundle.cpp
index ec46379f2c..9789d37492 100644
--- a/src/libs/qmljs/qmljsbundle.cpp
+++ b/src/libs/qmljs/qmljsbundle.cpp
@@ -35,11 +35,6 @@
namespace QmlJS {
typedef PersistentTrie::Trie Trie;
-QmlBundle::QmlBundle(const QmlBundle &o)
- : m_name(o.m_name), m_searchPaths(o.searchPaths()), m_installPaths(o.installPaths()),
- m_supportedImports(o.m_supportedImports), m_implicitImports(o.m_implicitImports)
-{ }
-
QmlBundle::QmlBundle()
{ }
diff --git a/src/libs/qmljs/qmljsbundle.h b/src/libs/qmljs/qmljsbundle.h
index 0bf00ab755..8057abc6d7 100644
--- a/src/libs/qmljs/qmljsbundle.h
+++ b/src/libs/qmljs/qmljsbundle.h
@@ -51,7 +51,6 @@ class QMLJS_EXPORT QmlBundle
{
typedef PersistentTrie::Trie Trie;
public:
- QmlBundle(const QmlBundle &o);
QmlBundle();
QmlBundle(const QString &name,
const Trie &searchPaths,
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index ea43a4dec8..e5243830cd 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -384,6 +384,7 @@ protected:
_possiblyUndeclaredUses.clear();
_seenNonDeclarationStatement = false;
_formalParameterNames.clear();
+ QTC_ASSERT(_block == 0, _block = 0);
}
void postVisit(Node *ast)
@@ -399,8 +400,11 @@ protected:
if (ast->name.isEmpty())
return false;
const QString &name = ast->name.toString();
- if (!_declaredFunctions.contains(name) && !_declaredVariables.contains(name))
+ if (!_declaredFunctions.contains(name)
+ && !(_declaredVariables.contains(name)
+ || _declaredBlockVariables.contains({name, _block}))) {
_possiblyUndeclaredUses[name].append(ast->identifierToken);
+ }
return false;
}
@@ -416,13 +420,26 @@ protected:
if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())
return true;
const QString &name = ast->bindingIdentifier.toString();
-
- if (_formalParameterNames.contains(name))
+ VariableScope scope = ast->scope;
+ if (_formalParameterNames.contains(name)) {
addMessage(WarnAlreadyFormalParameter, ast->identifierToken, name);
- else if (_declaredFunctions.contains(name))
+ } else if (_declaredFunctions.contains(name)) {
addMessage(WarnAlreadyFunction, ast->identifierToken, name);
- else if (_declaredVariables.contains(name))
- addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
+ } else if (scope == VariableScope::Let || scope == VariableScope::Const) {
+ if (_declaredBlockVariables.contains({name, _block}))
+ addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
+ } else if (scope == VariableScope::Var) {
+ 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;
+ }
+ }
+ }
+ }
if (_possiblyUndeclaredUses.contains(name)) {
foreach (const SourceLocation &loc, _possiblyUndeclaredUses.value(name)) {
@@ -430,7 +447,10 @@ protected:
}
_possiblyUndeclaredUses.remove(name);
}
- _declaredVariables[name] = ast;
+ if (scope == VariableScope::Let || scope == VariableScope::Const)
+ _declaredBlockVariables[{name, _block}] = ast;
+ else
+ _declaredVariables[name] = ast;
return true;
}
@@ -451,7 +471,7 @@ protected:
if (_formalParameterNames.contains(name))
addMessage(WarnAlreadyFormalParameter, ast->identifierToken, name);
- else if (_declaredVariables.contains(name))
+ else if (_declaredVariables.contains(name) || _declaredBlockVariables.contains({name, _block}))
addMessage(WarnAlreadyVar, ast->identifierToken, name);
else if (_declaredFunctions.contains(name))
addMessage(WarnDuplicateDeclaration, ast->identifierToken, name);
@@ -469,6 +489,25 @@ protected:
return false;
}
+ bool visit(Block *) override
+ {
+ ++_block;
+ return true;
+ }
+
+ void endVisit(Block *) override
+ {
+ auto it = _declaredBlockVariables.begin();
+ auto end = _declaredBlockVariables.end();
+ while (it != end) {
+ if (it.key().second == _block)
+ it = _declaredBlockVariables.erase(it);
+ else
+ ++it;
+ }
+ --_block;
+ }
+
private:
void addMessage(Type type, const SourceLocation &loc, const QString &arg1 = QString())
{
@@ -478,9 +517,11 @@ private:
QList<Message> _messages;
QStringList _formalParameterNames;
QHash<QString, PatternElement *> _declaredVariables;
+ QHash<QPair<QString, uint>, PatternElement *> _declaredBlockVariables;
QHash<QString, FunctionDeclaration *> _declaredFunctions;
QHash<QString, QList<SourceLocation> > _possiblyUndeclaredUses;
bool _seenNonDeclarationStatement;
+ uint _block = 0;
};
class IdsThatShouldNotBeUsedInDesigner : public QStringList
@@ -1635,7 +1676,7 @@ bool Check::visit(CallExpression *ast)
if (!whiteListedFunction && !isMathFunction && !isDateFunction && !isDirectInConnectionsScope)
addMessage(ErrFunctionsNotSupportedInQmlUi, location);
- static const QStringList globalFunctions = {"String", "Boolean", "Date", "Number", "Object", "QT_TR_NOOP", "QT_TRANSLATE_NOOP", "QT_TRID_NOOP"};
+ static const QStringList globalFunctions = {"String", "Boolean", "Date", "Number", "Object", "Array", "QT_TR_NOOP", "QT_TRANSLATE_NOOP", "QT_TRID_NOOP"};
if (!name.isEmpty() && name.at(0).isUpper() && !globalFunctions.contains(name)) {
addMessage(WarnExpectedNewWithUppercaseFunction, location);
diff --git a/src/libs/qmljs/qmljsdialect.cpp b/src/libs/qmljs/qmljsdialect.cpp
index 0cb463b2e5..cfe71b2265 100644
--- a/src/libs/qmljs/qmljsdialect.cpp
+++ b/src/libs/qmljs/qmljsdialect.cpp
@@ -30,7 +30,6 @@
namespace QmlJS {
-
bool Dialect::isQmlLikeLanguage() const
{
switch (m_dialect) {
@@ -233,7 +232,7 @@ QDebug operator << (QDebug &dbg, const Dialect &dialect)
return dbg;
}
-PathAndLanguage::PathAndLanguage(const Utils::FileName &path, Dialect language)
+PathAndLanguage::PathAndLanguage(const Utils::FilePath &path, Dialect language)
: m_path(path), m_language(language)
{ }
@@ -294,11 +293,11 @@ void PathsAndLanguages::compact()
return;
int oldCompactionPlace = 0;
- Utils::FileName oldPath = m_list.first().path();
+ Utils::FilePath oldPath = m_list.first().path();
QList<PathAndLanguage> compactedList;
bool restrictFailed = false;
for (int i = 1; i < m_list.length(); ++i) {
- Utils::FileName newPath = m_list.at(i).path();
+ Utils::FilePath newPath = m_list.at(i).path();
if (newPath == oldPath) {
int newCompactionPlace = i - 1;
compactedList << m_list.mid(oldCompactionPlace, newCompactionPlace - oldCompactionPlace);
diff --git a/src/libs/qmljs/qmljsdialect.h b/src/libs/qmljs/qmljsdialect.h
index 8d1ca30deb..230642e145 100644
--- a/src/libs/qmljs/qmljsdialect.h
+++ b/src/libs/qmljs/qmljsdialect.h
@@ -78,11 +78,8 @@ QMLJS_EXPORT QDebug operator << (QDebug &dbg, const Dialect &dialect);
class QMLJS_EXPORT PathAndLanguage {
public:
- PathAndLanguage(const Utils::FileName &path = Utils::FileName(), Dialect language = Dialect::AnyLanguage);
- PathAndLanguage(const PathAndLanguage &o)
- : m_path(o.path()), m_language(o.language())
- { }
- Utils::FileName path() const {
+ PathAndLanguage(const Utils::FilePath &path = Utils::FilePath(), Dialect language = Dialect::AnyLanguage);
+ Utils::FilePath path() const {
return m_path;
}
Dialect language() const {
@@ -91,7 +88,7 @@ public:
bool operator ==(const PathAndLanguage &other) const;
bool operator < (const PathAndLanguage &other) const;
private:
- Utils::FileName m_path;
+ Utils::FilePath m_path;
Dialect m_language;
};
@@ -130,11 +127,8 @@ public:
explicit PathsAndLanguages(const QList<PathAndLanguage> &list)
: m_list(list)
{ }
- PathsAndLanguages(const PathsAndLanguages &o)
- : m_list(o.m_list)
- { }
- bool maybeInsert(const Utils::FileName &path, Dialect language = Dialect::AnyLanguage) {
+ bool maybeInsert(const Utils::FilePath &path, Dialect language = Dialect::AnyLanguage) {
return maybeInsert(PathAndLanguage(path, language));
}
diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index a4551b1c1c..6ebe5b0b2f 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -458,14 +458,6 @@ Snapshot::~Snapshot()
{
}
-Snapshot::Snapshot(const Snapshot &o)
- : _documents(o._documents),
- _documentsByPath(o._documentsByPath),
- _libraries(o._libraries),
- _dependencies(o._dependencies)
-{
-}
-
void Snapshot::insert(const Document::Ptr &document, bool allowInvalid)
{
if (document && (allowInvalid || document->qmlProgram() || document->jsProgram())) {
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index 4029373992..82df720776 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -230,7 +230,6 @@ class QMLJS_EXPORT Snapshot
public:
Snapshot();
- Snapshot(const Snapshot &o);
~Snapshot();
typedef Base::iterator iterator;
diff --git a/src/libs/qmljs/qmljsimportdependencies.cpp b/src/libs/qmljs/qmljsimportdependencies.cpp
index adc9c9ff57..afa8d58b3a 100644
--- a/src/libs/qmljs/qmljsimportdependencies.cpp
+++ b/src/libs/qmljs/qmljsimportdependencies.cpp
@@ -25,9 +25,9 @@
#include "qmljsimportdependencies.h"
#include "qmljsinterpreter.h"
-#include "qmljsqrcparser.h"
#include "qmljsviewercontext.h"
+#include <utils/qrcparser.h>
#include <utils/qtcassert.h>
#include <QCryptographicHash>
@@ -139,10 +139,10 @@ ImportKey::ImportKey(ImportType::Enum type, const QString &path, int majorVersio
break;
case ImportType::File:
case ImportType::QrcFile:
- splitPath = QrcParser::normalizedQrcFilePath(path).split(QLatin1Char('/'));
+ splitPath = Utils::QrcParser::normalizedQrcFilePath(path).split(QLatin1Char('/'));
break;
case ImportType::QrcDirectory:
- splitPath = QrcParser::normalizedQrcDirectoryPath(path).split(QLatin1Char('/'));
+ splitPath = Utils::QrcParser::normalizedQrcDirectoryPath(path).split(QLatin1Char('/'));
if (splitPath.length() > 1 && splitPath.last().isEmpty())
splitPath.removeLast();
break;
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 03083501b6..91f195f8fc 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -2340,6 +2340,16 @@ Import::Import(const Import &other)
valid(other.valid), used(false)
{ }
+Import &Import::operator=(const Import &other)
+{
+ object = other.object;
+ info = other.info;
+ libraryPath = other.libraryPath;
+ valid = other.valid;
+ used = false;
+ return *this;
+}
+
TypeScope::TypeScope(const Imports *imports, ValueOwner *valueOwner)
: ObjectValue(valueOwner)
, m_imports(imports)
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 9da1aa8635..f2e953180c 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -1038,6 +1038,7 @@ class QMLJS_EXPORT Import {
public:
Import();
Import(const Import &other);
+ Import &operator=(const Import &other);
// const!
ObjectValue *object;
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 737ec6cc46..1acdb68ed9 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -30,9 +30,10 @@
#include "qmljsbind.h"
#include "qmljsutils.h"
#include "qmljsmodelmanagerinterface.h"
-#include "qmljsqrcparser.h"
#include "qmljsconstants.h"
+#include <utils/qrcparser.h>
+
#include <QDir>
using namespace LanguageUtils;
@@ -557,7 +558,7 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr d
foreach (const QString &path,
ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName())) {
processImport(ImportInfo::qrcDirectoryImport(
- QrcParser::qrcDirectoryPathForQrcFilePath(path)));
+ Utils::QrcParser::qrcDirectoryPathForQrcFilePath(path)));
}
}
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 82d4da3f4a..6bb1bc8ff9 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -52,6 +52,8 @@
#include <stdio.h>
+using namespace Utils;
+
namespace QmlJS {
QMLJS_EXPORT Q_LOGGING_CATEGORY(qmljsLog, "qtc.qmljs.common", QtWarningMsg)
@@ -1098,14 +1100,14 @@ void ModelManagerInterface::updateImportPaths()
PathAndLanguage pAndL = iPaths.at(i);
const QString canonicalPath = pAndL.path().toFileInfo().canonicalFilePath();
if (!canonicalPath.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(canonicalPath),
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(canonicalPath),
pAndL.language());
}
}
while (vCtxsIter.hasNext()) {
vCtxsIter.next();
foreach (const QString &path, vCtxsIter.value().paths)
- allImportPaths.maybeInsert(Utils::FileName::fromString(path), vCtxsIter.value().language);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(path), vCtxsIter.value().language);
}
pInfoIter.toFront();
while (pInfoIter.hasNext()) {
@@ -1116,7 +1118,7 @@ void ModelManagerInterface::updateImportPaths()
.searchPaths().stringList()) {
const QString canonicalPath = QFileInfo(path).canonicalFilePath();
if (!canonicalPath.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(canonicalPath), l);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(canonicalPath), l);
}
}
}
@@ -1125,16 +1127,16 @@ void ModelManagerInterface::updateImportPaths()
pInfoIter.next();
QString pathAtt = pInfoIter.value().qtQmlPath;
if (!pathAtt.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(pathAtt), Dialect::QmlQtQuick2);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(pathAtt), Dialect::QmlQtQuick2);
}
{
QString pathAtt = defaultProjectInfo().qtQmlPath;
if (!pathAtt.isEmpty())
- allImportPaths.maybeInsert(Utils::FileName::fromString(pathAtt), Dialect::QmlQtQuick2);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(pathAtt), Dialect::QmlQtQuick2);
}
foreach (const QString &path, m_defaultImportPaths)
- allImportPaths.maybeInsert(Utils::FileName::fromString(path), Dialect::Qml);
+ allImportPaths.maybeInsert(Utils::FilePath::fromString(path), Dialect::Qml);
allImportPaths.compact();
{
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h
index 5de25eead3..cd36cbca2f 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.h
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h
@@ -28,11 +28,11 @@
#include "qmljs_global.h"
#include "qmljsbundle.h"
#include "qmljsdocument.h"
-#include "qmljsqrcparser.h"
#include "qmljsdialect.h"
#include <cplusplus/CppDocument.h>
#include <utils/environment.h>
+#include <utils/qrcparser.h>
#include <QFuture>
#include <QHash>
@@ -255,7 +255,7 @@ private:
void cleanupFutures();
void iterateQrcFiles(ProjectExplorer::Project *project,
QrcResourceSelector resources,
- std::function<void(QrcParser::ConstPtr)> callback);
+ std::function<void(Utils::QrcParser::ConstPtr)> callback);
mutable QMutex m_mutex;
QmlJS::Snapshot m_validSnapshot;
@@ -272,7 +272,7 @@ private:
QTimer *m_asyncResetTimer = nullptr;
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > m_queuedCppDocuments;
QFuture<void> m_cppQmlTypesUpdater;
- QrcCache m_qrcCache;
+ Utils::QrcCache m_qrcCache;
QHash<QString, QString> m_qrcContents;
CppDataHash m_cppDataHash;
diff --git a/src/libs/qmljs/qmljsreformatter.cpp b/src/libs/qmljs/qmljsreformatter.cpp
index e95ff2f339..d60d6179f3 100644
--- a/src/libs/qmljs/qmljsreformatter.cpp
+++ b/src/libs/qmljs/qmljsreformatter.cpp
@@ -96,6 +96,7 @@ class Rewriter : protected Visitor
int _lastNewlineOffset = -1;
bool _hadEmptyLine = false;
int _binaryExpDepth = 0;
+ bool _hasOpenComment = false;
public:
Rewriter(Document::Ptr doc)
@@ -201,6 +202,9 @@ protected:
void out(const QString &str, const SourceLocation &lastLoc = SourceLocation())
{
+ if (_hasOpenComment) {
+ newLine();
+ }
if (lastLoc.isValid()) {
QList<SourceLocation> comments = _doc->engine()->comments();
for (; _nextComment < comments.size(); ++_nextComment) {
@@ -371,6 +375,7 @@ protected:
{
// if preceded by a newline, it's an empty line!
_hadEmptyLine = _line.trimmed().isEmpty();
+ _hasOpenComment = false;
// if the preceding line wasn't empty, reindent etc.
if (!_hadEmptyLine) {
@@ -524,6 +529,7 @@ protected:
out(" ");
out(toString(nextCommentLoc));
+ _hasOpenComment = true;
}
}
}
@@ -531,6 +537,39 @@ protected:
bool visit(UiPragma *ast) override
{
out("pragma ", ast->pragmaToken);
+ out(ast->name.toString());
+ newLine();
+ return false;
+ }
+
+ bool visit(UiEnumDeclaration *ast) override
+ {
+ out(ast->enumToken);
+ out(" ");
+ out(ast->name.toString());
+ out(" ");
+ out("{"); // TODO: out(ast->lbraceToken);
+ newLine();
+
+ accept(ast->members);
+
+ out(ast->rbraceToken);
+ return false;
+ }
+
+ bool visit(UiEnumMemberList *list) override
+ {
+ for (UiEnumMemberList *it = list; it; it = it->next) {
+ out(it->memberToken);
+ if (it->valueToken.isValid()) {
+ out(" = ");
+ out(it->valueToken);
+ }
+ if (it->next) {
+ out(",");
+ }
+ newLine();
+ }
return false;
}
@@ -563,9 +602,10 @@ protected:
bool visit(UiObjectInitializer *ast) override
{
out(ast->lbraceToken);
- if (ast->members)
+ if (ast->members) {
lnAcceptIndented(ast->members);
- newLine();
+ newLine();
+ }
out(ast->rbraceToken);
return false;
}
@@ -593,10 +633,10 @@ protected:
if (!ast->typeModifier.isNull()) {
out(ast->typeModifierToken);
out("<");
- out(ast->typeToken);
+ accept(ast->memberType);
out(">");
} else {
- out(ast->typeToken);
+ accept(ast->memberType);
}
out(" ");
if (ast->statement) {
@@ -677,8 +717,10 @@ protected:
bool visit(ObjectPattern *ast) override
{
out(ast->lbraceToken);
- lnAcceptIndented(ast->properties);
- newLine();
+ if (ast->properties) {
+ lnAcceptIndented(ast->properties);
+ newLine();
+ }
out(ast->rbraceToken);
return false;
}
@@ -914,14 +956,23 @@ protected:
bool visit(VariableStatement *ast) override
{
- out("var ", ast->declarationKindToken);
+ out(ast->declarationKindToken);
+ out(" ");
accept(ast->declarations);
return false;
}
bool visit(PatternElement *ast) override
{
-
+ if (ast->isForDeclaration) {
+ if (ast->scope == VariableScope::Var) {
+ out("var ");
+ } else if (ast->scope == VariableScope::Let) {
+ out("let ");
+ } else if (ast->scope == VariableScope::Const) {
+ out("const ");
+ }
+ }
out(ast->identifierToken);
if (ast->initializer) {
if (ast->isVariableDeclaration())
@@ -985,7 +1036,12 @@ protected:
out(ast->forToken);
out(" ");
out(ast->lparenToken);
- accept(ast->initialiser);
+ if (ast->initialiser) {
+ accept(ast->initialiser);
+ } else if (ast->declarations) {
+ out("var ");
+ accept(ast->declarations);
+ }
out("; ", ast->firstSemicolonToken);
accept(ast->condition);
out("; ", ast->secondSemicolonToken);
@@ -1273,6 +1329,8 @@ protected:
{
for (FormalParameterList *it = ast; it; it = it->next) {
out(it->element->bindingIdentifier.toString()); // TODO
+ if (it->next)
+ out(", ");
}
return false;
}
diff --git a/src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp b/src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp
index c8f03ea8d9..8e1deea715 100644
--- a/src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp
+++ b/src/libs/qt-breakpad/qtcrashhandler/dumpsender.cpp
@@ -145,8 +145,7 @@ void DumpSender::sendDumpAndQuit()
connect(reply, &QNetworkReply::uploadProgress, this, &DumpSender::uploadProgress);
connect(reply, &QNetworkReply::finished, QCoreApplication::instance(), &QCoreApplication::quit);
- connect(reply,
- static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
+ connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
QCoreApplication::instance(), &QCoreApplication::quit);
}
diff --git a/src/libs/qtcreatorcdbext/CMakeLists.txt b/src/libs/qtcreatorcdbext/CMakeLists.txt
new file mode 100644
index 0000000000..15ab799083
--- /dev/null
+++ b/src/libs/qtcreatorcdbext/CMakeLists.txt
@@ -0,0 +1,46 @@
+#todo
+# - handle if there is no debug python lib python35_d
+# - needs to be tested
+
+if (MINGW)
+ message(STATUS "MinGW detected. Removing qtcreatorcdbext from build.")
+ return()
+endif()
+
+include(CheckIncludeFile)
+check_include_file(wdbgexts.h HAVE_WDBGEXTS_H)
+if (NOT HAVE_WDBGEXTS_H)
+ message(WARNING "wdbgexts.h not found. Removing qtcreatorcdbext from build.")
+ return()
+endif()
+
+find_package(PythonLibs 3.5)
+if (NOT ${PYTHONLIBS_FOUND})
+ message(WARNING "PythonLibs 3.5 not found. Removing qtcreatorcdbext from build.")
+ return()
+endif()
+
+add_qtc_library(qtcreatorcdbext
+ DEPENDS ${PYTHON_LIBRARIES}
+ INCLUDES ${PYTHON_INCLUDE_DIR}
+ DEFINES WITH_PYTHON=1
+ SOURCES
+ common.cpp common.h
+ containers.cpp containers.h
+ eventcallback.cpp eventcallback.h
+ extensioncontext.cpp extensioncontext.h
+ gdbmihelpers.cpp gdbmihelpers.h
+ iinterfacepointer.h
+ knowntype.h
+ outputcallback.cpp outputcallback.h
+ pycdbextmodule.cpp pycdbextmodule.h
+ pyfield.cpp pyfield.h
+ pystdoutredirect.cpp pystdoutredirect.h
+ pytype.cpp pytype.h
+ pyvalue.cpp pyvalue.h
+ qtcreatorcdbextension.cpp
+ stringutils.cpp stringutils.h
+ symbolgroup.cpp symbolgroup.h
+ symbolgroupnode.cpp symbolgroupnode.h
+ symbolgroupvalue.cpp symbolgroupvalue.h
+)
diff --git a/src/libs/qtcreatorcdbext/common.h b/src/libs/qtcreatorcdbext/common.h
index b538313b3f..fd76c1be7e 100644
--- a/src/libs/qtcreatorcdbext/common.h
+++ b/src/libs/qtcreatorcdbext/common.h
@@ -34,9 +34,16 @@
#include <windows.h>
#define KDEXT_64BIT
-#pragma warning( disable : 4838 )
-#include <wdbgexts.h>
-#pragma warning( default : 4838 )
+#ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wc++11-narrowing"
+# include <wdbgexts.h>
+# pragma clang diagnostic pop
+#else
+# pragma warning( disable : 4838 )
+# include <wdbgexts.h>
+# pragma warning( default : 4838 )
+#endif // __clang__
#include <dbgeng.h>
typedef IDebugControl3 CIDebugControl;
diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro b/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro
index 545656dc24..774e889b2a 100644
--- a/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro
+++ b/src/libs/qtcreatorcdbext/qtcreatorcdbext.pro
@@ -100,7 +100,7 @@ HEADERS += extensioncontext.h \
symbolgroupnode.h
isEmpty(PYTHON_INSTALL_DIR):PYTHON_INSTALL_DIR=$$(PYTHON_INSTALL_DIR)
-exists($$PYTHON_INSTALL_DIR) {
+!isEmpty(PYTHON_INSTALL_DIR):exists($$PYTHON_INSTALL_DIR) {
DEFINES += WITH_PYTHON=1
INCLUDEPATH += $$PYTHON_INSTALL_DIR/include
diff --git a/src/libs/sqlite/CMakeLists.txt b/src/libs/sqlite/CMakeLists.txt
new file mode 100644
index 0000000000..22ba4bac34
--- /dev/null
+++ b/src/libs/sqlite/CMakeLists.txt
@@ -0,0 +1,27 @@
+add_qtc_library(Sqlite
+ DEFINES
+ SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS
+ SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA
+ BUILD_SQLITE_LIBRARY
+ DEPENDS Qt5::Core
+ PUBLIC_INCLUDES "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/../3rdparty/sqlite"
+ SOURCES
+ ../3rdparty/sqlite/sqlite3.c
+ createtablesqlstatementbuilder.cpp createtablesqlstatementbuilder.h
+ sqlitebasestatement.cpp sqlitebasestatement.h
+ sqlitecolumn.h
+ sqlitedatabase.cpp sqlitedatabase.h
+ sqlitedatabasebackend.cpp sqlitedatabasebackend.h
+ sqliteexception.cpp sqliteexception.h
+ sqliteglobal.cpp sqliteglobal.h
+ sqliteindex.h
+ sqlitereadstatement.cpp sqlitereadstatement.h
+ sqlitereadwritestatement.cpp sqlitereadwritestatement.h
+ sqlitetable.h
+ sqlitetransaction.h
+ sqlitewritestatement.cpp sqlitewritestatement.h
+ sqlstatementbuilder.cpp sqlstatementbuilder.h
+ sqlstatementbuilderexception.h
+ utf8string.cpp utf8string.h
+ utf8stringvector.cpp utf8stringvector.h
+)
diff --git a/src/libs/sqlite/README.md b/src/libs/sqlite/README.md
new file mode 100644
index 0000000000..88944dcd42
--- /dev/null
+++ b/src/libs/sqlite/README.md
@@ -0,0 +1,13 @@
+# SQLite
+
+Minimum version is the same as the sqlite version in the source tree.
+
+We compile SQLite with the flowing settings:
+* SQLITE_THREADSAFE=2
+* SQLITE_ENABLE_FTS4
+* SQLITE_ENABLE_FTS3_PARENTHESIS
+* SQLITE_ENABLE_UNLOCK_NOTIFY
+* SQLITE_ENABLE_COLUMN_METADATA
+* SQLITE_ENABLE_JSON1
+
+Be prepared that we demand more functionality from SQLite in the future.
diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri
index fb46370052..4d7f906a19 100644
--- a/src/libs/sqlite/sqlite-lib.pri
+++ b/src/libs/sqlite/sqlite-lib.pri
@@ -19,16 +19,14 @@ SOURCES += \
$$PWD/sqlitereadwritestatement.cpp \
$$PWD/sqlitewritestatement.cpp \
$$PWD/sqlstatementbuilder.cpp \
- $$PWD/sqlstatementbuilderexception.cpp \
$$PWD/utf8string.cpp \
$$PWD/utf8stringvector.cpp \
$$PWD/sqlitedatabase.cpp \
- $$PWD/sqlitetable.cpp \
- $$PWD/sqlitecolumn.cpp \
$$PWD/sqlitebasestatement.cpp
HEADERS += \
$$PWD/createtablesqlstatementbuilder.h \
$$PWD/sqlitedatabasebackend.h \
+ $$PWD/sqlitedatabaseinterface.h \
$$PWD/sqliteexception.h \
$$PWD/sqliteglobal.h \
$$PWD/sqlitereadstatement.h \
@@ -48,4 +46,6 @@ HEADERS += \
DEFINES += SQLITE_THREADSAFE=2 SQLITE_ENABLE_FTS4 SQLITE_ENABLE_FTS3_PARENTHESIS \
SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_COLUMN_METADATA SQLITE_ENABLE_JSON1
+OTHER_FILES += README.md
+
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/sqlite/sqlite-source.pri b/src/libs/sqlite/sqlite-source.pri
index b297e31da2..5729293901 100644
--- a/src/libs/sqlite/sqlite-source.pri
+++ b/src/libs/sqlite/sqlite-source.pri
@@ -17,12 +17,9 @@ SOURCES += \
sqliteworkerthread.cpp \
sqlitewritestatement.cpp \
sqlstatementbuilder.cpp \
- sqlstatementbuilderexception.cpp \
utf8string.cpp \
utf8stringvector.cpp \
sqlitedatabase.cpp \
- sqlitetable.cpp \
- sqlitecolumn.cpp \
tablewriteworker.cpp \
tablewriteworkerproxy.cpp
HEADERS += \
diff --git a/src/libs/sqlite/sqlitecolumn.cpp b/src/libs/sqlite/sqlitecolumn.cpp
deleted file mode 100644
index 201f1fbcb9..0000000000
--- a/src/libs/sqlite/sqlitecolumn.cpp
+++ /dev/null
@@ -1,31 +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 "sqlitecolumn.h"
-
-namespace Sqlite {
-
-
-} // namespace Sqlite
diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h
index d0eae28f79..2c35a293c2 100644
--- a/src/libs/sqlite/sqlitedatabase.h
+++ b/src/libs/sqlite/sqlitedatabase.h
@@ -26,6 +26,7 @@
#pragma once
#include "sqlitedatabasebackend.h"
+#include "sqlitedatabaseinterface.h"
#include "sqliteglobal.h"
#include "sqlitetable.h"
#include "sqlitetransaction.h"
@@ -43,7 +44,7 @@ using namespace std::chrono_literals;
class ReadStatement;
class WriteStatement;
-class SQLITE_EXPORT Database final : public TransactionInterface
+class SQLITE_EXPORT Database final : public TransactionInterface, public DatabaseInterface
{
template <typename Database>
friend class Statement;
@@ -105,19 +106,18 @@ public:
return m_databaseBackend.changesCount();
}
- int totalChangesCount()
- {
- return m_databaseBackend.totalChangesCount();
- }
+ int totalChangesCount() { return m_databaseBackend.totalChangesCount(); }
+
+ void walCheckpointFull() override { m_databaseBackend.walCheckpointFull(); }
private:
- void deferredBegin();
- void immediateBegin();
- void exclusiveBegin();
- void commit();
- void rollback();
- void lock();
- void unlock();
+ void deferredBegin() override;
+ void immediateBegin() override;
+ void exclusiveBegin() override;
+ void commit() override;
+ void rollback() override;
+ void lock() override;
+ void unlock() override;
void initializeTables();
void registerTransactionStatements();
diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp
index a42564aca5..bf9dfab6fc 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.cpp
+++ b/src/libs/sqlite/sqlitedatabasebackend.cpp
@@ -406,6 +406,27 @@ void DatabaseBackend::setBusyTimeout(std::chrono::milliseconds timeout)
sqlite3_busy_timeout(m_databaseHandle, int(timeout.count()));
}
+void DatabaseBackend::walCheckpointFull()
+{
+ int resultCode = sqlite3_wal_checkpoint_v2(m_databaseHandle,
+ nullptr,
+ SQLITE_CHECKPOINT_TRUNCATE,
+ nullptr,
+ nullptr);
+
+ switch (resultCode) {
+ case SQLITE_OK:
+ break;
+ case SQLITE_BUSY:
+ throw DatabaseIsBusy("DatabaseBackend::walCheckpointFull: Operation could not concluded "
+ "because database is busy!");
+ case SQLITE_ERROR:
+ throwException("DatabaseBackend::walCheckpointFull: Error occurred!");
+ case SQLITE_MISUSE:
+ throwExceptionStatic("DatabaseBackend::walCheckpointFull: Misuse of database!");
+ }
+}
+
void DatabaseBackend::throwExceptionStatic(const char *whatHasHappens)
{
throw Exception(whatHasHappens);
diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h
index 2de55672aa..7f3973f878 100644
--- a/src/libs/sqlite/sqlitedatabasebackend.h
+++ b/src/libs/sqlite/sqlitedatabasebackend.h
@@ -85,6 +85,8 @@ public:
void setBusyTimeout(std::chrono::milliseconds timeout);
+ void walCheckpointFull();
+
protected:
bool databaseIsOpen() const;
diff --git a/src/libs/sqlite/sqlstatementbuilderexception.cpp b/src/libs/sqlite/sqlitedatabaseinterface.h
index 82f5b4f792..61ea3ac928 100644
--- a/src/libs/sqlite/sqlstatementbuilderexception.cpp
+++ b/src/libs/sqlite/sqlitedatabaseinterface.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.
@@ -23,12 +23,15 @@
**
****************************************************************************/
-#include "sqlstatementbuilderexception.h"
+#pragma once
namespace Sqlite {
+class DatabaseInterface
+{
+public:
+ virtual void walCheckpointFull() = 0;
-
-
-
-
+protected:
+ ~DatabaseInterface() = default;
+};
} // namespace Sqlite
diff --git a/src/libs/ssh/CMakeLists.txt b/src/libs/ssh/CMakeLists.txt
new file mode 100644
index 0000000000..6f5d1cb764
--- /dev/null
+++ b/src/libs/ssh/CMakeLists.txt
@@ -0,0 +1,22 @@
+add_qtc_library(QtcSsh
+ DEPENDS Qt5::Core Qt5::Network Qt5::Widgets Utils
+ SOURCES
+ sftpdefs.cpp sftpdefs.h
+ sftpfilesystemmodel.cpp sftpfilesystemmodel.h
+ sftpsession.cpp sftpsession.h
+ sftptransfer.cpp sftptransfer.h
+ ssh.qrc
+ ssh_global.h
+ sshconnection.cpp sshconnection.h
+ sshconnectionmanager.cpp sshconnectionmanager.h
+ sshkeycreationdialog.cpp sshkeycreationdialog.h sshkeycreationdialog.ui
+ sshlogging.cpp sshlogging_p.h
+ sshprocess.cpp sshprocess.h
+ sshconnection.cpp sshconnection.h
+ sshconnectionmanager.cpp sshconnectionmanager.h
+ sshkeycreationdialog.cpp sshkeycreationdialog.h sshkeycreationdialog.ui
+ sshlogging.cpp sshlogging_p.h
+ sshremoteprocess.cpp sshremoteprocess.h
+ sshremoteprocessrunner.cpp sshremoteprocessrunner.h
+ sshsettings.cpp sshsettings.h
+)
diff --git a/src/libs/ssh/sftpfilesystemmodel.cpp b/src/libs/ssh/sftpfilesystemmodel.cpp
index 555796b812..0e9eb48e5e 100644
--- a/src/libs/ssh/sftpfilesystemmodel.cpp
+++ b/src/libs/ssh/sftpfilesystemmodel.cpp
@@ -30,6 +30,7 @@
#include "sshconnectionmanager.h"
#include <utils/qtcassert.h>
+#include <utils/utilsicons.h>
#include <QFileInfo>
#include <QHash>
@@ -167,9 +168,9 @@ QVariant SftpFileSystemModel::data(const QModelIndex &index, int role) const
switch (node->fileInfo.type) {
case FileTypeRegular:
case FileTypeOther:
- return QIcon(":/ssh/images/unknownfile.png");
+ return Utils::Icons::UNKNOWN_FILE.icon();
case FileTypeDirectory:
- return QIcon(":/ssh/images/dir.png");
+ return Utils::Icons::DIR.icon();
case FileTypeUnknown:
return QIcon(":/ssh/images/help.png"); // Shows a question mark.
}
diff --git a/src/libs/ssh/sftpsession.cpp b/src/libs/ssh/sftpsession.cpp
index 0119bea266..528475ed2b 100644
--- a/src/libs/ssh/sftpsession.cpp
+++ b/src/libs/ssh/sftpsession.cpp
@@ -83,6 +83,8 @@ struct SftpSession::SftpSessionPrivate
SftpJobId queueCommand(CommandType command, const QStringList &paths)
{
+ qCDebug(sshLog) << "queueing command" << int(command) << paths;
+
const SftpJobId jobId = nextJobId++;
pendingCommands.enqueue(Command(command, paths, jobId));
runNextCommand();
@@ -111,6 +113,7 @@ SftpSession::SftpSession(const QStringList &connectionArgs) : d(new SftpSessionP
{
d->connectionArgs = connectionArgs;
connect(&d->sftpProc, &QProcess::started, [this] {
+ qCDebug(sshLog) << "sftp process started";
d->sftpProc.write("\n"); // Force initial prompt.
});
connect(&d->sftpProc, &QProcess::errorOccurred, [this](QProcess::ProcessError error) {
@@ -120,6 +123,8 @@ SftpSession::SftpSession(const QStringList &connectionArgs) : d(new SftpSessionP
}
});
connect(&d->sftpProc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [this] {
+ qCDebug(sshLog) << "sftp process finished";
+
d->state = State::Inactive;
if (d->sftpProc.exitStatus() != QProcess::NormalExit) {
emit done(tr("sftp crashed."));
@@ -138,7 +143,7 @@ void SftpSession::doStart()
{
if (d->state != State::Starting)
return;
- const FileName sftpBinary = SshSettings::sftpFilePath();
+ const FilePath sftpBinary = SshSettings::sftpFilePath();
if (!sftpBinary.exists()) {
d->state = State::Inactive;
emit done(tr("Cannot establish SFTP session: sftp binary \"%1\" does not exist.")
@@ -269,6 +274,8 @@ void SftpSession::start()
void SftpSession::quit()
{
+ qCDebug(sshLog) << "quitting sftp session, current state is" << int(state());
+
switch (state()) {
case State::Starting:
case State::Closing:
diff --git a/src/libs/ssh/sftptransfer.cpp b/src/libs/ssh/sftptransfer.cpp
index 887d8f36fa..52b821bc39 100644
--- a/src/libs/ssh/sftptransfer.cpp
+++ b/src/libs/ssh/sftptransfer.cpp
@@ -132,7 +132,7 @@ SftpTransfer::SftpTransfer(const FilesToTransfer &files, Internal::FileTransferT
void SftpTransfer::doStart()
{
- const FileName sftpBinary = SshSettings::sftpFilePath();
+ const FilePath sftpBinary = SshSettings::sftpFilePath();
if (!sftpBinary.exists()) {
emitError(tr("sftp binary \"%1\" does not exist.").arg(sftpBinary.toUserOutput()));
return;
diff --git a/src/libs/ssh/ssh.qrc b/src/libs/ssh/ssh.qrc
index 4b0c6a8c51..9801217093 100644
--- a/src/libs/ssh/ssh.qrc
+++ b/src/libs/ssh/ssh.qrc
@@ -1,7 +1,5 @@
<RCC>
<qresource prefix="/ssh">
- <file>images/dir.png</file>
<file>images/help.png</file>
- <file>images/unknownfile.png</file>
</qresource>
</RCC>
diff --git a/src/libs/ssh/sshconnection.cpp b/src/libs/ssh/sshconnection.cpp
index 91d8446db9..b368ccc8ef 100644
--- a/src/libs/ssh/sshconnection.cpp
+++ b/src/libs/ssh/sshconnection.cpp
@@ -231,7 +231,7 @@ void SshConnection::disconnectFromHost()
case Connecting:
case Connected:
if (!d->sharingEnabled) {
- emitDisconnected();
+ QTimer::singleShot(0, this, &SshConnection::emitDisconnected);
return;
}
d->state = Disconnecting;
@@ -309,7 +309,7 @@ SshConnection::~SshConnection()
delete d;
}
-SshRemoteProcessPtr SshConnection::createRemoteProcess(const QByteArray &command)
+SshRemoteProcessPtr SshConnection::createRemoteProcess(const QString &command)
{
QTC_ASSERT(state() == Connected, return SshRemoteProcessPtr());
return SshRemoteProcessPtr(new SshRemoteProcess(command, d->connectionArgs()));
@@ -317,7 +317,7 @@ SshRemoteProcessPtr SshConnection::createRemoteProcess(const QByteArray &command
SshRemoteProcessPtr SshConnection::createRemoteShell()
{
- return createRemoteProcess(QByteArray());
+ return createRemoteProcess({});
}
SftpTransferPtr SshConnection::createUpload(const FilesToTransfer &files,
@@ -342,7 +342,7 @@ void SshConnection::doConnectToHost()
{
if (d->state != Connecting)
return;
- const FileName sshBinary = SshSettings::sshFilePath();
+ const FilePath sshBinary = SshSettings::sshFilePath();
if (!sshBinary.exists()) {
emitError(tr("Cannot establish SSH connection: ssh binary \"%1\" does not exist.")
.arg(sshBinary.toUserOutput()));
diff --git a/src/libs/ssh/sshconnection.h b/src/libs/ssh/sshconnection.h
index 1b5775682e..89af4d71d9 100644
--- a/src/libs/ssh/sshconnection.h
+++ b/src/libs/ssh/sshconnection.h
@@ -111,7 +111,7 @@ public:
bool sharingEnabled() const;
~SshConnection();
- SshRemoteProcessPtr createRemoteProcess(const QByteArray &command);
+ SshRemoteProcessPtr createRemoteProcess(const QString &command);
SshRemoteProcessPtr createRemoteShell();
SftpTransferPtr createUpload(const FilesToTransfer &files,
FileTransferErrorHandling errorHandlingMode);
diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp
index 4bd09b37e1..635f23e150 100644
--- a/src/libs/ssh/sshremoteprocess.cpp
+++ b/src/libs/ssh/sshremoteprocess.cpp
@@ -54,21 +54,19 @@ using namespace Internal;
struct SshRemoteProcess::SshRemoteProcessPrivate
{
- QByteArray remoteCommand;
+ QString remoteCommand;
QStringList connectionArgs;
QString displayName;
bool useTerminal = false;
};
-SshRemoteProcess::SshRemoteProcess(const QByteArray &command, const QStringList &connectionArgs)
+SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &connectionArgs)
: d(new SshRemoteProcessPrivate)
{
d->remoteCommand = command;
d->connectionArgs = connectionArgs;
- connect(this,
- static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
- [this] {
+ connect(this, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this] {
QString error;
if (exitStatus() == QProcess::CrashExit)
error = tr("The ssh process crashed: %1").arg(errorString());
@@ -129,7 +127,7 @@ QStringList SshRemoteProcess::fullLocalCommandLine() const
if (!d->displayName.isEmpty())
args.prepend("-X");
if (!d->remoteCommand.isEmpty())
- args << QLatin1String(d->remoteCommand);
+ args << d->remoteCommand;
args.prepend(SshSettings::sshFilePath().toString());
return args;
}
diff --git a/src/libs/ssh/sshremoteprocess.h b/src/libs/ssh/sshremoteprocess.h
index 82dd1b9dcb..02ab3546fd 100644
--- a/src/libs/ssh/sshremoteprocess.h
+++ b/src/libs/ssh/sshremoteprocess.h
@@ -30,10 +30,6 @@
#include <QStringList>
-QT_BEGIN_NAMESPACE
-class QByteArray;
-QT_END_NAMESPACE
-
namespace QSsh {
class SshConnection;
@@ -56,7 +52,7 @@ signals:
void done(const QString &error);
private:
- SshRemoteProcess(const QByteArray &command, const QStringList &connectionArgs);
+ SshRemoteProcess(const QString &command, const QStringList &connectionArgs);
void doStart();
struct SshRemoteProcessPrivate;
diff --git a/src/libs/ssh/sshremoteprocessrunner.cpp b/src/libs/ssh/sshremoteprocessrunner.cpp
index 11b75f6a25..7a062e6ab8 100644
--- a/src/libs/ssh/sshremoteprocessrunner.cpp
+++ b/src/libs/ssh/sshremoteprocessrunner.cpp
@@ -50,7 +50,7 @@ public:
SshRemoteProcessPtr m_process;
SshConnection *m_connection;
bool m_runInTerminal;
- QByteArray m_command;
+ QString m_command;
QString m_lastConnectionErrorString;
QProcess::ExitStatus m_exitStatus;
QByteArray m_stdout;
@@ -76,8 +76,7 @@ SshRemoteProcessRunner::~SshRemoteProcessRunner()
delete d;
}
-void SshRemoteProcessRunner::run(const QByteArray &command,
- const SshConnectionParameters &sshParams)
+void SshRemoteProcessRunner::run(const QString &command, const SshConnectionParameters &sshParams)
{
QTC_ASSERT(d->m_state == Inactive, return);
@@ -85,14 +84,14 @@ void SshRemoteProcessRunner::run(const QByteArray &command,
runInternal(command, sshParams);
}
-void SshRemoteProcessRunner::runInTerminal(const QByteArray &command,
+void SshRemoteProcessRunner::runInTerminal(const QString &command,
const SshConnectionParameters &sshParams)
{
d->m_runInTerminal = true;
runInternal(command, sshParams);
}
-void SshRemoteProcessRunner::runInternal(const QByteArray &command,
+void SshRemoteProcessRunner::runInternal(const QString &command,
const SshConnectionParameters &sshParams)
{
setState(Connecting);
@@ -197,7 +196,7 @@ void SshRemoteProcessRunner::setState(int newState)
}
}
-QByteArray SshRemoteProcessRunner::command() const { return d->m_command; }
+QString SshRemoteProcessRunner::command() const { return d->m_command; }
QString SshRemoteProcessRunner::lastConnectionErrorString() const {
return d->m_lastConnectionErrorString;
}
diff --git a/src/libs/ssh/sshremoteprocessrunner.h b/src/libs/ssh/sshremoteprocessrunner.h
index 029fb6bb3d..082f30ed57 100644
--- a/src/libs/ssh/sshremoteprocessrunner.h
+++ b/src/libs/ssh/sshremoteprocessrunner.h
@@ -39,9 +39,9 @@ public:
SshRemoteProcessRunner(QObject *parent = 0);
~SshRemoteProcessRunner();
- void run(const QByteArray &command, const SshConnectionParameters &sshParams);
- void runInTerminal(const QByteArray &command, const SshConnectionParameters &sshParams);
- QByteArray command() const;
+ void run(const QString &command, const SshConnectionParameters &sshParams);
+ void runInTerminal(const QString &command, const SshConnectionParameters &sshParams);
+ QString command() const;
QString lastConnectionErrorString() const;
@@ -69,7 +69,7 @@ private:
void handleProcessFinished(const QString &error);
void handleStdout();
void handleStderr();
- void runInternal(const QByteArray &command, const QSsh::SshConnectionParameters &sshParams);
+ void runInternal(const QString &command, const QSsh::SshConnectionParameters &sshParams);
void setState(int newState);
Internal::SshRemoteProcessRunnerPrivate * const d;
diff --git a/src/libs/ssh/sshsettings.cpp b/src/libs/ssh/sshsettings.cpp
index 12f17bbade..0086d05376 100644
--- a/src/libs/ssh/sshsettings.cpp
+++ b/src/libs/ssh/sshsettings.cpp
@@ -39,11 +39,11 @@ struct SshSettings
{
bool useConnectionSharing = !HostOsInfo::isWindowsHost();
int connectionSharingTimeOutInMinutes = 10;
- FileName sshFilePath;
- FileName sftpFilePath;
- FileName askpassFilePath;
- FileName keygenFilePath;
- QSsh::SshSettings::SearchPathRetriever searchPathRetriever = [] { return FileNameList(); };
+ FilePath sshFilePath;
+ FilePath sftpFilePath;
+ FilePath askpassFilePath;
+ FilePath keygenFilePath;
+ QSsh::SshSettings::SearchPathRetriever searchPathRetriever = [] { return FilePathList(); };
};
} // namespace Internal
@@ -79,11 +79,11 @@ void SshSettings::loadSettings(QSettings *settings)
value = settings->value(connectionSharingTimeoutKey());
if (value.isValid())
sshSettings->connectionSharingTimeOutInMinutes = value.toInt();
- sshSettings->sshFilePath = FileName::fromString(settings->value(sshFilePathKey()).toString());
- sshSettings->sftpFilePath = FileName::fromString(settings->value(sftpFilePathKey()).toString());
- sshSettings->askpassFilePath = FileName::fromString(
+ sshSettings->sshFilePath = FilePath::fromString(settings->value(sshFilePathKey()).toString());
+ sshSettings->sftpFilePath = FilePath::fromString(settings->value(sftpFilePathKey()).toString());
+ sshSettings->askpassFilePath = FilePath::fromString(
settings->value(askPassFilePathKey()).toString());
- sshSettings->keygenFilePath = FileName::fromString(
+ sshSettings->keygenFilePath = FilePath::fromString(
settings->value(keygenFilePathKey()).toString());
}
@@ -114,51 +114,51 @@ int SshSettings::connectionSharingTimeout()
return sshSettings->connectionSharingTimeOutInMinutes;
}
-static FileName filePathValue(const FileName &value, const QStringList &candidateFileNames)
+static FilePath filePathValue(const FilePath &value, const QStringList &candidateFileNames)
{
if (!value.isEmpty())
return value;
- const QList<FileName> additionalSearchPaths = sshSettings->searchPathRetriever();
+ const QList<FilePath> additionalSearchPaths = sshSettings->searchPathRetriever();
for (const QString &candidate : candidateFileNames) {
- const FileName filePath = Environment::systemEnvironment()
+ const FilePath filePath = Environment::systemEnvironment()
.searchInPath(candidate, additionalSearchPaths);
if (!filePath.isEmpty())
return filePath;
}
- return FileName();
+ return FilePath();
}
-static FileName filePathValue(const FileName &value, const QString &candidateFileName)
+static FilePath filePathValue(const FilePath &value, const QString &candidateFileName)
{
return filePathValue(value, QStringList(candidateFileName));
}
-void SshSettings::setSshFilePath(const FileName &ssh) { sshSettings->sshFilePath = ssh; }
-FileName SshSettings::sshFilePath() { return filePathValue(sshSettings->sshFilePath, "ssh"); }
+void SshSettings::setSshFilePath(const FilePath &ssh) { sshSettings->sshFilePath = ssh; }
+FilePath SshSettings::sshFilePath() { return filePathValue(sshSettings->sshFilePath, "ssh"); }
-void SshSettings::setSftpFilePath(const FileName &sftp) { sshSettings->sftpFilePath = sftp; }
-FileName SshSettings::sftpFilePath() { return filePathValue(sshSettings->sftpFilePath, "sftp"); }
+void SshSettings::setSftpFilePath(const FilePath &sftp) { sshSettings->sftpFilePath = sftp; }
+FilePath SshSettings::sftpFilePath() { return filePathValue(sshSettings->sftpFilePath, "sftp"); }
-void SshSettings::setAskpassFilePath(const FileName &askPass)
+void SshSettings::setAskpassFilePath(const FilePath &askPass)
{
sshSettings->askpassFilePath = askPass;
}
-FileName SshSettings::askpassFilePath()
+FilePath SshSettings::askpassFilePath()
{
- FileName candidate;
+ FilePath candidate;
candidate = sshSettings->askpassFilePath;
if (candidate.isEmpty())
- candidate = FileName::fromString(Environment::systemEnvironment().value("SSH_ASKPASS"));
+ candidate = FilePath::fromString(Environment::systemEnvironment().value("SSH_ASKPASS"));
return filePathValue(candidate, QStringList{"qtc-askpass", "ssh-askpass"});
}
-void SshSettings::setKeygenFilePath(const FileName &keygen)
+void SshSettings::setKeygenFilePath(const FilePath &keygen)
{
sshSettings->keygenFilePath = keygen;
}
-FileName SshSettings::keygenFilePath()
+FilePath SshSettings::keygenFilePath()
{
return filePathValue(sshSettings->keygenFilePath, "ssh-keygen");
}
diff --git a/src/libs/ssh/sshsettings.h b/src/libs/ssh/sshsettings.h
index dc29ead606..08692b6e8c 100644
--- a/src/libs/ssh/sshsettings.h
+++ b/src/libs/ssh/sshsettings.h
@@ -49,19 +49,19 @@ public:
static void setConnectionSharingTimeout(int timeInMinutes);
static int connectionSharingTimeout();
- static void setSshFilePath(const Utils::FileName &ssh);
- static Utils::FileName sshFilePath();
+ static void setSshFilePath(const Utils::FilePath &ssh);
+ static Utils::FilePath sshFilePath();
- static void setSftpFilePath(const Utils::FileName &sftp);
- static Utils::FileName sftpFilePath();
+ static void setSftpFilePath(const Utils::FilePath &sftp);
+ static Utils::FilePath sftpFilePath();
- static void setAskpassFilePath(const Utils::FileName &askPass);
- static Utils::FileName askpassFilePath();
+ static void setAskpassFilePath(const Utils::FilePath &askPass);
+ static Utils::FilePath askpassFilePath();
- static void setKeygenFilePath(const Utils::FileName &keygen);
- static Utils::FileName keygenFilePath();
+ static void setKeygenFilePath(const Utils::FilePath &keygen);
+ static Utils::FilePath keygenFilePath();
- using SearchPathRetriever = std::function<Utils::FileNameList()>;
+ using SearchPathRetriever = std::function<Utils::FilePathList()>;
static void setExtraSearchPathRetriever(const SearchPathRetriever &pathRetriever);
};
diff --git a/src/libs/tracing/CMakeLists.txt b/src/libs/tracing/CMakeLists.txt
new file mode 100644
index 0000000000..153756323e
--- /dev/null
+++ b/src/libs/tracing/CMakeLists.txt
@@ -0,0 +1,35 @@
+if (WITH_TESTS)
+ set(TEST_SOURCES
+ runscenegraphtest.cpp runscenegraphtest.h
+ )
+endif()
+
+add_qtc_library(Tracing
+ DEPENDS Utils Qt5::Qml Qt5::Quick
+ PUBLIC_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}"
+ SOURCES ${TEST_SOURCES}
+ flamegraph.cpp flamegraph.h
+ flamegraphattached.h
+ safecastable.h
+ qml/tracing.qrc
+ timelineabstractrenderer.cpp timelineabstractrenderer.h timelineabstractrenderer_p.h
+ timelineformattime.cpp timelineformattime.h
+ timelineitemsrenderpass.cpp timelineitemsrenderpass.h
+ timelinemodel.cpp timelinemodel.h timelinemodel_p.h
+ timelinemodelaggregator.cpp timelinemodelaggregator.h
+ timelinenotesmodel.cpp timelinenotesmodel.h timelinenotesmodel_p.h
+ timelinenotesrenderpass.cpp timelinenotesrenderpass.h
+ timelineoverviewrenderer.cpp timelineoverviewrenderer.h timelineoverviewrenderer_p.h
+ timelinerenderer.cpp timelinerenderer.h timelinerenderer_p.h
+ timelinerenderpass.cpp timelinerenderpass.h
+ timelinerenderstate.cpp timelinerenderstate.h timelinerenderstate_p.h
+ timelineselectionrenderpass.cpp timelineselectionrenderpass.h
+ timelinetheme.cpp timelinetheme.h
+ timelinetracefile.cpp timelinetracefile.h
+ timelinetracemanager.cpp timelinetracemanager.h
+ timelinezoomcontrol.cpp timelinezoomcontrol.h
+ traceevent.h
+ traceeventtype.h
+ tracestashfile.h
+ tracing_global.h
+)
diff --git a/src/libs/tracing/timelineabstractrenderer.h b/src/libs/tracing/timelineabstractrenderer.h
index f28fd07672..64475ef3ae 100644
--- a/src/libs/tracing/timelineabstractrenderer.h
+++ b/src/libs/tracing/timelineabstractrenderer.h
@@ -35,7 +35,6 @@
namespace Timeline {
-
class TRACING_EXPORT TimelineAbstractRenderer : public QQuickItem
{
Q_OBJECT
diff --git a/src/libs/tracing/timelinemodel_p.h b/src/libs/tracing/timelinemodel_p.h
index 53136571be..bc2ac76850 100644
--- a/src/libs/tracing/timelinemodel_p.h
+++ b/src/libs/tracing/timelinemodel_p.h
@@ -90,7 +90,7 @@ public:
ranges.prepend(start);
return 0;
}
- const Range &range = ranges[--i];
+ const Range &range = ranges.at(--i);
if (range.start < start.start || (range.start == start.start &&
range.duration >= start.duration)) {
ranges.insert(++i, start);
@@ -106,7 +106,7 @@ public:
endTimes.prepend(end);
return 0;
}
- if (endTimes[--i].end <= end.end) {
+ if (endTimes.at(--i).end <= end.end) {
endTimes.insert(++i, end);
return i;
}
diff --git a/src/libs/tracing/timelinerenderer.h b/src/libs/tracing/timelinerenderer.h
index b963ec7871..16a766d695 100644
--- a/src/libs/tracing/timelinerenderer.h
+++ b/src/libs/tracing/timelinerenderer.h
@@ -35,7 +35,6 @@
namespace Timeline {
-
class TRACING_EXPORT TimelineRenderer : public TimelineAbstractRenderer
{
Q_OBJECT
diff --git a/src/libs/tracing/tracestashfile.h b/src/libs/tracing/tracestashfile.h
index c3443e1300..0ab6105047 100644
--- a/src/libs/tracing/tracestashfile.h
+++ b/src/libs/tracing/tracestashfile.h
@@ -153,7 +153,7 @@ public:
void clear()
{
file.remove();
- stream.unsetDevice();
+ stream.setDevice(nullptr);
}
bool flush()
diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt
new file mode 100644
index 0000000000..00307728a6
--- /dev/null
+++ b/src/libs/utils/CMakeLists.txt
@@ -0,0 +1,204 @@
+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}")
+else()
+ message(WARNING "IDE_LIBEXEC_PATH or IDE_BIN_PATH undefined when calculating tools path")
+ set(RELATIVE_TOOLS_PATH "")
+endif()
+
+add_qtc_library(Utils
+ DEPENDS Qt5::Xml
+ PUBLIC_DEPENDS Qt5::Concurrent Qt5::Core Qt5::Network Qt5::Qml Qt5::Gui Qt5::Widgets
+ DEFINES
+ "QTC_REL_TOOLS_PATH=\"${RELATIVE_TOOLS_PATH}\""
+ SOURCES
+ ../3rdparty/optional/optional.hpp
+ ../3rdparty/variant/variant.hpp
+ QtConcurrentTools
+ algorithm.h
+ ansiescapecodehandler.cpp ansiescapecodehandler.h
+ appmainwindow.cpp appmainwindow.h
+ basetreeview.cpp basetreeview.h
+ benchmarker.cpp benchmarker.h
+ buildablehelperlibrary.cpp buildablehelperlibrary.h
+ categorysortfiltermodel.cpp categorysortfiltermodel.h
+ changeset.cpp changeset.h
+ checkablemessagebox.cpp checkablemessagebox.h
+ classnamevalidatinglineedit.cpp classnamevalidatinglineedit.h
+ codegeneration.cpp codegeneration.h
+ completinglineedit.cpp completinglineedit.h
+ completingtextedit.cpp completingtextedit.h
+ consoleprocess.cpp consoleprocess.h consoleprocess_p.h
+ cpplanguage_details.h
+ crumblepath.cpp crumblepath.h
+ delegates.cpp delegates.h
+ declarationmacros.h
+ detailsbutton.cpp detailsbutton.h
+ detailswidget.cpp detailswidget.h
+ differ.cpp differ.h
+ dropsupport.cpp dropsupport.h
+ elfreader.cpp elfreader.h
+ elidinglabel.cpp elidinglabel.h
+ environment.cpp environment.h
+ environmentdialog.cpp environmentdialog.h
+ environmentmodel.cpp environmentmodel.h
+ execmenu.cpp execmenu.h
+ executeondestruction.h
+ fadingindicator.cpp fadingindicator.h
+ faketooltip.cpp faketooltip.h
+ fancylineedit.cpp fancylineedit.h
+ fancymainwindow.cpp fancymainwindow.h
+ filecrumblabel.cpp filecrumblabel.h
+ fileinprojectfinder.cpp fileinprojectfinder.h
+ filenamevalidatinglineedit.cpp filenamevalidatinglineedit.h
+ filesearch.cpp filesearch.h
+ filesystemwatcher.cpp filesystemwatcher.h
+ fileutils.cpp fileutils.h
+ filewizardpage.cpp filewizardpage.h
+ fixedsizeclicklabel.cpp fixedsizeclicklabel.h
+ flowlayout.cpp flowlayout.h
+ functiontraits.h
+ fuzzymatcher.cpp fuzzymatcher.h
+ genericconstants.h
+ globalfilechangeblocker.cpp globalfilechangeblocker.h
+ guard.cpp guard.h
+ headerviewstretcher.cpp headerviewstretcher.h
+ highlightingitemdelegate.cpp highlightingitemdelegate.h
+ historycompleter.cpp historycompleter.h
+ hostosinfo.cpp hostosinfo.h
+ htmldocextractor.cpp htmldocextractor.h
+ icon.cpp icon.h
+ itemviews.cpp itemviews.h
+ json.cpp json.h
+ jsontreeitem.cpp jsontreeitem.h
+ linecolumn.h
+ link.h
+ listmodel.h
+ listutils.h
+ macroexpander.cpp macroexpander.h
+ mapreduce.h
+ mimetypes/mimedatabase.cpp mimetypes/mimedatabase.h mimetypes/mimedatabase_p.h
+ mimetypes/mimeglobpattern.cpp mimetypes/mimeglobpattern_p.h
+ mimetypes/mimemagicrule.cpp mimetypes/mimemagicrule_p.h
+ mimetypes/mimemagicrulematcher.cpp mimetypes/mimemagicrulematcher_p.h
+ mimetypes/mimeprovider.cpp mimetypes/mimeprovider_p.h
+ mimetypes/mimetype.cpp mimetypes/mimetype.h mimetypes/mimetype_p.h
+ mimetypes/mimetypeparser.cpp mimetypes/mimetypeparser_p.h
+ navigationtreeview.cpp navigationtreeview.h
+ networkaccessmanager.cpp networkaccessmanager.h
+ newclasswidget.cpp newclasswidget.h newclasswidget.ui
+ optional.h
+ osspecificaspects.h
+ outputformat.h
+ outputformatter.cpp outputformatter.h
+ overridecursor.cpp overridecursor.h
+ parameteraction.cpp parameteraction.h
+ pathchooser.cpp pathchooser.h
+ pathlisteditor.cpp pathlisteditor.h
+ persistentsettings.cpp persistentsettings.h
+ pointeralgorithm.h
+ port.cpp port.h
+ portlist.cpp portlist.h
+ predicates.h
+ processhandle.cpp processhandle.h
+ progressindicator.cpp progressindicator.h
+ projectintropage.cpp projectintropage.h projectintropage.ui
+ proxyaction.cpp proxyaction.h
+ proxycredentialsdialog.cpp proxycredentialsdialog.h proxycredentialsdialog.ui
+ qrcparser.cpp qrcparser.h
+ qtcassert.cpp qtcassert.h
+ qtcolorbutton.cpp qtcolorbutton.h
+ qtcprocess.cpp qtcprocess.h
+ reloadpromptutils.cpp reloadpromptutils.h
+ removefiledialog.cpp removefiledialog.h removefiledialog.ui
+ runextensions.cpp runextensions.h
+ savedaction.cpp savedaction.h
+ savefile.cpp savefile.h
+ scopedswap.h
+ settingsaccessor.cpp settingsaccessor.h
+ settingsselector.cpp settingsselector.h
+ settingsutils.h
+ shellcommand.cpp shellcommand.h
+ shellcommandpage.cpp shellcommandpage.h
+ sizedarray.h
+ smallstring.h
+ smallstringfwd.h
+ smallstringio.h
+ smallstringiterator.h
+ smallstringlayout.h
+ smallstringliteral.h
+ smallstringmemory.h
+ smallstringvector.h
+ smallstringview.h
+ statuslabel.cpp statuslabel.h
+ stringutils.cpp stringutils.h
+ styledbar.cpp styledbar.h
+ stylehelper.cpp stylehelper.h
+ synchronousprocess.cpp synchronousprocess.h
+ templateengine.cpp templateengine.h
+ temporarydirectory.cpp temporarydirectory.h
+ temporaryfile.cpp temporaryfile.h
+ textfieldcheckbox.cpp textfieldcheckbox.h
+ textfieldcombobox.cpp textfieldcombobox.h
+ textfileformat.cpp textfileformat.h
+ textutils.cpp textutils.h
+ theme/theme.cpp theme/theme.h theme/theme_p.h
+ tooltip/effects.h
+ tooltip/reuse.h
+ tooltip/tips.cpp tooltip/tips.h
+ tooltip/tooltip.cpp tooltip/tooltip.h
+ touchbar/touchbar.h
+ treemodel.cpp treemodel.h
+ treeviewcombobox.cpp treeviewcombobox.h
+ uncommentselection.cpp uncommentselection.h
+ unixutils.cpp unixutils.h
+ url.cpp url.h
+ utils.qrc
+ utils_global.h
+ utilsicons.cpp utilsicons.h
+ variant.h
+ winutils.cpp winutils.h
+ wizard.cpp wizard.h
+ wizardpage.cpp wizardpage.h
+)
+
+extend_qtc_target(Utils CONDITION WIN32
+ SOURCES
+ consoleprocess_win.cpp
+ process_ctrlc_stub.cpp
+ touchbar/touchbar.cpp
+ DEPENDS
+ user32 iphlpapi ws2_32 shell32
+ DEFINES
+ _UNICODE UNICODE
+ PUBLIC_DEFINES
+ _CRT_SECURE_NO_WARNINGS _SCL_SECURE_NO_WARNINGS
+)
+
+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
+ touchbar/touchbar_appdelegate_mac.mm touchbar/touchbar_appdelegate_mac_p.h
+ touchbar/touchbar_mac.mm touchbar/touchbar_mac_p.h
+ DEPENDS
+ ${FWFoundation} ${FWAppKit}
+)
+
+extend_qtc_target(Utils CONDITION UNIX AND NOT APPLE
+ SOURCES
+ consoleprocess_unix.cpp
+ touchbar/touchbar.cpp
+)
+
+if (WIN32)
+ add_qtc_executable(qtcreator_process_stub
+ SOURCES process_stub_win.c
+ DEPENDS shell32
+ DEFINES _UNICODE UNICODE _CRT_SECURE_NO_WARNINGS
+ )
+else()
+ add_qtc_executable(qtcreator_process_stub SOURCES process_stub_unix.c)
+endif()
diff --git a/src/libs/utils/algorithm.h b/src/libs/utils/algorithm.h
index bae78aacda..9e80755a3a 100644
--- a/src/libs/utils/algorithm.h
+++ b/src/libs/utils/algorithm.h
@@ -48,6 +48,323 @@
namespace Utils
{
+/////////////////////////
+// anyOf
+/////////////////////////
+template<typename T, typename F>
+bool anyOf(const T &container, F predicate);
+template<typename T, typename R, typename S>
+bool anyOf(const T &container, R (S::*predicate)() const);
+template<typename T, typename R, typename S>
+bool anyOf(const T &container, R S::*member);
+
+/////////////////////////
+// count
+/////////////////////////
+template<typename T, typename F>
+int count(const T &container, F predicate);
+
+/////////////////////////
+// allOf
+/////////////////////////
+template<typename T, typename F>
+bool allOf(const T &container, F predicate);
+
+/////////////////////////
+// erase
+/////////////////////////
+template<typename T, typename F>
+void erase(T &container, F predicate);
+
+/////////////////////////
+// contains
+/////////////////////////
+template<typename T, typename F>
+bool contains(const T &container, F function);
+template<typename T, typename R, typename S>
+bool contains(const T &container, R (S::*function)() const);
+template<typename C, typename R, typename S>
+bool contains(const C &container, R S::*member);
+
+/////////////////////////
+// findOr
+/////////////////////////
+template<typename C, typename F>
+Q_REQUIRED_RESULT typename C::value_type findOr(const C &container,
+ typename C::value_type other,
+ F function);
+template<typename T, typename R, typename S>
+Q_REQUIRED_RESULT typename T::value_type findOr(const T &container,
+ typename T::value_type other,
+ R (S::*function)() const);
+template<typename T, typename R, typename S>
+Q_REQUIRED_RESULT typename T::value_type findOr(const T &container,
+ typename T::value_type other,
+ R S::*member);
+
+/////////////////////////
+// findOrDefault
+/////////////////////////
+template<typename C, typename F>
+Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
+ typename C::value_type>
+findOrDefault(const C &container, F function);
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
+ typename C::value_type>
+findOrDefault(const C &container, R (S::*function)() const);
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT typename std::enable_if_t<std::is_copy_assignable<typename C::value_type>::value,
+ typename C::value_type>
+findOrDefault(const C &container, R S::*member);
+
+/////////////////////////
+// indexOf
+/////////////////////////
+template<typename C, typename F>
+Q_REQUIRED_RESULT int indexOf(const C &container, F function);
+
+/////////////////////////
+// maxElementOr
+/////////////////////////
+template<typename T>
+typename T::value_type maxElementOr(const T &container, typename T::value_type other);
+
+/////////////////////////
+// filtered
+/////////////////////////
+template<typename C, typename F>
+Q_REQUIRED_RESULT C filtered(const C &container, F predicate);
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT C filtered(const C &container, R (S::*predicate)() const);
+
+/////////////////////////
+// partition
+/////////////////////////
+// Recommended usage:
+// C hit;
+// C miss;
+// std::tie(hit, miss) = Utils::partition(container, predicate);
+template<typename C, typename F>
+Q_REQUIRED_RESULT std::tuple<C, C> partition(const C &container, F predicate);
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT std::tuple<C, C> partition(const C &container, R (S::*predicate)() const);
+
+/////////////////////////
+// filteredUnique
+/////////////////////////
+template<typename C>
+Q_REQUIRED_RESULT C filteredUnique(const C &container);
+
+/////////////////////////
+// qobject_container_cast
+/////////////////////////
+template<class T, template<typename> class Container, typename Base>
+Container<T> qobject_container_cast(const Container<Base> &container);
+
+/////////////////////////
+// static_container_cast
+/////////////////////////
+template<class T, template<typename> class Container, typename Base>
+Container<T> static_container_cast(const Container<Base> &container);
+
+/////////////////////////
+// sort
+/////////////////////////
+template<typename Container>
+inline void sort(Container &container);
+template<typename Container, typename Predicate>
+inline void sort(Container &container, Predicate p);
+template<typename Container, typename R, typename S>
+inline void sort(Container &container, R S::*member);
+template<typename Container, typename R, typename S>
+inline void sort(Container &container, R (S::*function)() const);
+
+/////////////////////////
+// reverseForeach
+/////////////////////////
+template<typename Container, typename Op>
+inline void reverseForeach(const Container &c, const Op &operation);
+
+/////////////////////////
+// toReferences
+/////////////////////////
+template<template<typename...> class ResultContainer, typename SourceContainer>
+auto toReferences(SourceContainer &sources);
+template<typename SourceContainer>
+auto toReferences(SourceContainer &sources);
+
+/////////////////////////
+// toConstReferences
+/////////////////////////
+template<template<typename...> class ResultContainer, typename SourceContainer>
+auto toConstReferences(const SourceContainer &sources);
+template<typename SourceContainer>
+auto toConstReferences(const SourceContainer &sources);
+
+/////////////////////////
+// take
+/////////////////////////
+template<class C, typename P>
+Q_REQUIRED_RESULT optional<typename C::value_type> take(C &container, P predicate);
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT decltype(auto) take(C &container, R S::*member);
+template<typename C, typename R, typename S>
+Q_REQUIRED_RESULT decltype(auto) take(C &container, R (S::*function)() const);
+
+/////////////////////////
+// setUnionMerge
+/////////////////////////
+// Works like std::set_union but provides a merge function for items that match
+// !(a > b) && !(b > a) which normally means that there is an "equal" match.
+// It uses iterators to support move_iterators.
+template<class InputIt1, class InputIt2, class OutputIt, class Merge, class Compare>
+OutputIt setUnionMerge(InputIt1 first1,
+ InputIt1 last1,
+ InputIt2 first2,
+ InputIt2 last2,
+ OutputIt d_first,
+ Merge merge,
+ Compare comp);
+template<class InputIt1, class InputIt2, class OutputIt, class Merge>
+OutputIt setUnionMerge(
+ InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt d_first, Merge merge);
+template<class OutputContainer, class InputContainer1, class InputContainer2, class Merge, class Compare>
+OutputContainer setUnionMerge(InputContainer1 &&input1,
+ InputContainer2 &&input2,
+ Merge merge,
+ Compare comp);
+template<class OutputContainer, class InputContainer1, class InputContainer2, class Merge>
+OutputContainer setUnionMerge(InputContainer1 &&input1, InputContainer2 &&input2, Merge merge);
+
+/////////////////////////
+// usize / ssize
+/////////////////////////
+template<typename Container>
+std::make_unsigned_t<typename Container::size_type> usize(Container container);
+template<typename Container>
+std::make_signed_t<typename Container::size_type> ssize(Container container);
+
+/////////////////////////
+// setUnion
+/////////////////////////
+template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
+OutputIterator set_union(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2,
+ OutputIterator result,
+ Compare comp);
+template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
+OutputIterator set_union(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2,
+ OutputIterator result);
+
+/////////////////////////
+// transform
+/////////////////////////
+// function without result type deduction:
+template<typename ResultContainer, // complete result container type
+ typename SC, // input container type
+ typename F> // function type
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
+
+// function with result type deduction:
+template<template<typename> class C, // result container type
+ typename SC, // input container type
+ typename F, // function type
+ typename Value = typename std::decay_t<SC>::value_type,
+ typename Result = std::decay_t<std::result_of_t<F(Value &)>>,
+ typename ResultContainer = C<Result>>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
+template<template<typename, typename> class C, // result container type
+ typename SC, // input container type
+ typename F, // function type
+ typename Value = typename std::decay_t<SC>::value_type,
+ typename Result = std::decay_t<std::result_of_t<F(Value &)>>,
+ typename ResultContainer = C<Result, std::allocator<Result>>>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function);
+
+// member function without result type deduction:
+template<template<typename...> class C, // result container type
+ typename SC, // input container type
+ typename R,
+ typename S>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R (S::*p)() const);
+
+// member function with result type deduction:
+template<typename ResultContainer, // complete result container type
+ typename SC, // input container type
+ typename R,
+ typename S>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R (S::*p)() const);
+
+// member without result type deduction:
+template<typename ResultContainer, // complete result container type
+ typename SC, // input container
+ typename R,
+ typename S>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R S::*p);
+
+// member with result type deduction:
+template<template<typename...> class C, // result container
+ typename SC, // input container
+ typename R,
+ typename S>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, R S::*p);
+
+// same container types for input and output, const input
+// function:
+template<template<typename...> class C, // container type
+ typename F, // function type
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, F function);
+
+// same container types for input and output, const input
+// member function:
+template<template<typename...> class C, // container type
+ typename R,
+ typename S,
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, R (S::*p)() const);
+
+// same container types for input and output, const input
+// members:
+template<template<typename...> class C, // container
+ typename R,
+ typename S,
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT decltype(auto) transform(const C<CArgs...> &container, R S::*p);
+
+// same container types for input and output, non-const input
+// function:
+template<template<typename...> class C, // container type
+ typename F, // function type
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, F function);
+
+// same container types for input and output, non-const input
+// member function:
+template<template<typename...> class C, // container type
+ typename R,
+ typename S,
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, R (S::*p)() const);
+
+// same container types for input and output, non-const input
+// members:
+template<template<typename...> class C, // container
+ typename R,
+ typename S,
+ typename... CArgs> // Arguments to SC
+Q_REQUIRED_RESULT decltype(auto) transform(C<CArgs...> &container, R S::*p);
+
+/////////////////////////////////////////////////////////////////////////////
+//////// Implementations //////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
//////////////////
// anyOf
/////////////////
@@ -367,25 +684,23 @@ decltype(auto) transform(SC &&container, F function)
// function with result type deduction:
template<template<typename> class C, // result container type
- typename SC, // input container type
- typename F, // function type
- typename Value = typename std::decay_t<SC>::value_type,
- typename Result = std::decay_t<std::result_of_t<F(Value&)>>,
- typename ResultContainer = C<Result>>
-Q_REQUIRED_RESULT
-decltype(auto) transform(SC &&container, F function)
+ typename SC, // input container type
+ typename F, // function type
+ typename Value,
+ typename Result,
+ typename ResultContainer>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function)
{
return transform<ResultContainer>(std::forward<SC>(container), function);
}
template<template<typename, typename> class C, // result container type
- typename SC, // input container type
- typename F, // function type
- typename Value = typename std::decay_t<SC>::value_type,
- typename Result = std::decay_t<std::result_of_t<F(Value&)>>,
- typename ResultContainer = C<Result, std::allocator<Result>>>
-Q_REQUIRED_RESULT
-decltype(auto) transform(SC &&container, F function)
+ typename SC, // input container type
+ typename F, // function type
+ typename Value,
+ typename Result,
+ typename ResultContainer>
+Q_REQUIRED_RESULT decltype(auto) transform(SC &&container, F function)
{
return transform<ResultContainer>(std::forward<SC>(container), function);
}
@@ -862,4 +1177,70 @@ std::make_signed_t<typename Container::size_type> ssize(Container container)
{
return static_cast<std::make_signed_t<typename Container::size_type>>(container.size());
}
+
+template<typename Compare>
+struct CompareIter
+{
+ Compare compare;
+
+ explicit constexpr CompareIter(Compare compare)
+ : compare(std::move(compare))
+ {}
+
+ template<typename Iterator1, typename Iterator2>
+ constexpr bool operator()(Iterator1 it1, Iterator2 it2)
+ {
+ return bool(compare(*it1, *it2));
+ }
+};
+
+template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
+OutputIterator set_union_impl(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2,
+ OutputIterator result,
+ Compare comp)
+{
+ auto compare = CompareIter<Compare>(comp);
+
+ while (first1 != last1 && first2 != last2) {
+ if (compare(first1, first2)) {
+ *result = *first1;
+ ++first1;
+ } else if (compare(first2, first1)) {
+ *result = *first2;
+ ++first2;
+ } else {
+ *result = *first1;
+ ++first1;
+ ++first2;
+ }
+ ++result;
+ }
+
+ return std::copy(first2, last2, std::copy(first1, last1, result));
+}
+
+template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Compare>
+OutputIterator set_union(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2,
+ OutputIterator result,
+ Compare comp)
+{
+ return Utils::set_union_impl(first1, last1, first2, last2, result, comp);
+}
+
+template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
+OutputIterator set_union(InputIterator1 first1,
+ InputIterator1 last1,
+ InputIterator2 first2,
+ InputIterator2 last2,
+ OutputIterator result)
+{
+ return Utils::set_union_impl(
+ first1, last1, first2, last2, result, std::less<typename InputIterator1::value_type>{});
+}
} // namespace Utils
diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp
index d77b8d4d55..352b17bb4b 100644
--- a/src/libs/utils/basetreeview.cpp
+++ b/src/libs/utils/basetreeview.cpp
@@ -183,7 +183,7 @@ public:
QAbstractItemModel *m = q->model();
for (int i = 0; i < 100 && a.isValid(); ++i) {
const QString s = m->data(a).toString();
- int w = fm.width(s) + 10;
+ int w = fm.horizontalAdvance(s) + 10;
if (column == 0) {
for (QModelIndex b = a.parent(); b.isValid(); b = b.parent())
w += ind;
@@ -204,7 +204,8 @@ public:
QTC_ASSERT(m, return -1);
QFontMetrics fm = q->fontMetrics();
- int minimum = fm.width(m->headerData(column, Qt::Horizontal).toString()) + 2 * fm.width(QLatin1Char('m'));
+ int minimum = fm.horizontalAdvance(m->headerData(column, Qt::Horizontal).toString())
+ + 2 * fm.horizontalAdvance(QLatin1Char('m'));
considerItems(column, q->indexAt(QPoint(1, 1)), &minimum, false);
QVariant extraIndices = m->data(QModelIndex(), BaseTreeView::ExtraIndicesForColumnWidth);
@@ -254,8 +255,8 @@ public:
// when we have that size already, in that case minimize.
if (currentSize == suggestedSize) {
QFontMetrics fm = q->fontMetrics();
- int headerSize = fm.width(q->model()->headerData(logicalIndex, Qt::Horizontal).toString());
- int minSize = 10 * fm.width(QLatin1Char('x'));
+ int headerSize = fm.horizontalAdvance(q->model()->headerData(logicalIndex, Qt::Horizontal).toString());
+ int minSize = 10 * fm.horizontalAdvance(QLatin1Char('x'));
targetSize = qMax(minSize, headerSize);
}
diff --git a/src/libs/utils/buildablehelperlibrary.cpp b/src/libs/utils/buildablehelperlibrary.cpp
index 3c53e09b2a..33ba624dc4 100644
--- a/src/libs/utils/buildablehelperlibrary.cpp
+++ b/src/libs/utils/buildablehelperlibrary.cpp
@@ -27,11 +27,13 @@
#include "hostosinfo.h"
#include "synchronousprocess.h"
-#include <QDir>
#include <QDateTime>
#include <QDebug>
+#include <QDir>
#include <QRegExp>
+#include <set>
+
namespace Utils {
bool BuildableHelperLibrary::isQtChooser(const QFileInfo &info)
@@ -71,32 +73,54 @@ static bool isQmake(const QString &path)
return !BuildableHelperLibrary::qtVersionForQMake(fi.absoluteFilePath()).isEmpty();
}
-FileName BuildableHelperLibrary::findSystemQt(const Environment &env)
+static FilePath findQmakeInDir(const FilePath &path)
{
- const QString qmake = QLatin1String("qmake");
- FileNameList paths = env.path();
- foreach (const FileName &path, paths) {
- if (path.isEmpty())
- continue;
-
- QDir dir(path.toString());
+ if (path.isEmpty())
+ return FilePath();
+
+ const QString qmake = "qmake";
+ QDir dir(path.toString());
+ if (dir.exists(qmake)) {
+ const QString qmakePath = dir.absoluteFilePath(qmake);
+ if (isQmake(qmakePath))
+ return FilePath::fromString(qmakePath);
+ }
- if (dir.exists(qmake)) {
- const QString qmakePath = dir.absoluteFilePath(qmake);
- if (isQmake(qmakePath))
- return FileName::fromString(qmakePath);
- }
+ // Prefer qmake-qt5 to qmake-qt4 by sorting the filenames in reverse order.
+ const QFileInfoList candidates = dir.entryInfoList(
+ BuildableHelperLibrary::possibleQMakeCommands(),
+ QDir::Files, QDir::Name | QDir::Reversed);
+ for (const QFileInfo &fi : candidates) {
+ if (fi.fileName() == qmake)
+ continue;
+ if (isQmake(fi.absoluteFilePath()))
+ return FilePath::fromFileInfo(fi);
+ }
+ return FilePath();
+}
- // Prefer qmake-qt5 to qmake-qt4 by sorting the filenames in reverse order.
- foreach (const QFileInfo &fi, dir.entryInfoList(possibleQMakeCommands(), QDir::Files, QDir::Name | QDir::Reversed)) {
- if (fi.fileName() == qmake)
- continue;
+FilePath BuildableHelperLibrary::findSystemQt(const Environment &env)
+{
+ const FilePathList list = findQtsInEnvironment(env, 1);
+ return list.size() == 1 ? list.first() : FilePath();
+}
- if (isQmake(fi.absoluteFilePath()))
- return FileName(fi);
- }
+FilePathList BuildableHelperLibrary::findQtsInEnvironment(const Environment &env, int maxCount)
+{
+ FilePathList qmakeList;
+ std::set<QString> canonicalEnvPaths;
+ const FilePathList paths = env.path();
+ for (const FilePath &path : paths) {
+ if (!canonicalEnvPaths.insert(path.toFileInfo().canonicalFilePath()).second)
+ continue;
+ const FilePath qmake = findQmakeInDir(path);
+ if (qmake.isEmpty())
+ continue;
+ qmakeList << qmake;
+ if (maxCount != -1 && qmakeList.size() == maxCount)
+ break;
}
- return FileName();
+ return qmakeList;
}
QString BuildableHelperLibrary::qtVersionForQMake(const QString &qmakePath)
@@ -165,7 +189,7 @@ bool BuildableHelperLibrary::copyFiles(const QString &sourcePath,
QString *errorMessage)
{
// try remove the directory
- if (!FileUtils::removeRecursively(FileName::fromString(targetDirectory), errorMessage))
+ if (!FileUtils::removeRecursively(FilePath::fromString(targetDirectory), errorMessage))
return false;
if (!QDir().mkpath(targetDirectory)) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary", "The target directory %1 could not be created.").arg(targetDirectory);
@@ -196,7 +220,7 @@ bool BuildableHelperLibrary::copyFiles(const QString &sourcePath,
// Helper: Run a build process with merged stdout/stderr
static inline bool runBuildProcessI(QProcess &proc,
- const FileName &binary,
+ const FilePath &binary,
const QStringList &args,
int timeoutS,
bool ignoreNonNullExitCode,
@@ -237,7 +261,7 @@ static inline bool runBuildProcessI(QProcess &proc,
// Run a build process with merged stdout/stderr and qWarn about errors.
static bool runBuildProcess(QProcess &proc,
- const FileName &binary,
+ const FilePath &binary,
const QStringList &args,
int timeoutS,
bool ignoreNonNullExitCode,
@@ -276,7 +300,7 @@ bool BuildableHelperLibrary::buildHelper(const BuildHelperArguments &arguments,
arguments.directory));
log->append(newline);
- const FileName makeFullPath = arguments.environment.searchInPath(arguments.makeCommand);
+ const FilePath makeFullPath = arguments.environment.searchInPath(arguments.makeCommand);
if (QFileInfo::exists(arguments.directory + QLatin1String("/Makefile"))) {
if (makeFullPath.isEmpty()) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary",
diff --git a/src/libs/utils/buildablehelperlibrary.h b/src/libs/utils/buildablehelperlibrary.h
index c818749f2b..45d37d65c4 100644
--- a/src/libs/utils/buildablehelperlibrary.h
+++ b/src/libs/utils/buildablehelperlibrary.h
@@ -37,7 +37,8 @@ class QTCREATOR_UTILS_EXPORT BuildableHelperLibrary
public:
// returns the full path to the first qmake, qmake-qt4, qmake4 that has
// at least version 2.0.0 and thus is a qt4 qmake
- static FileName findSystemQt(const Environment &env);
+ static FilePath findSystemQt(const Environment &env);
+ static FilePathList findQtsInEnvironment(const Environment &env, int maxCount = -1);
static bool isQtChooser(const QFileInfo &info);
static QString qtChooserToQmakePath(const QString &path);
// return true if the qmake at qmakePath is a Qt (used by QtVersion)
@@ -60,9 +61,9 @@ public:
QString directory;
Environment environment;
- FileName qmakeCommand;
+ FilePath qmakeCommand;
QString targetMode;
- FileName mkspec;
+ FilePath mkspec;
QString proFilename;
QStringList qmakeArguments;
diff --git a/src/libs/utils/checkablemessagebox.cpp b/src/libs/utils/checkablemessagebox.cpp
index 857711fd8a..3ec411cfb3 100644
--- a/src/libs/utils/checkablemessagebox.cpp
+++ b/src/libs/utils/checkablemessagebox.cpp
@@ -32,6 +32,7 @@
#include <QLabel>
#include <QPushButton>
#include <QSettings>
+#include <QStyle>
/*!
\class Utils::CheckableMessageBox
@@ -107,6 +108,7 @@ public:
QCheckBox *checkBox = nullptr;
QDialogButtonBox *buttonBox = nullptr;
QAbstractButton *clickedButton = nullptr;
+ QMessageBox::Icon icon = QMessageBox::NoIcon;
};
CheckableMessageBox::CheckableMessageBox(QWidget *parent) :
@@ -148,17 +150,53 @@ void CheckableMessageBox::setText(const QString &t)
d->messageLabel->setText(t);
}
-QPixmap CheckableMessageBox::iconPixmap() const
-{
- if (const QPixmap *p = d->pixmapLabel->pixmap())
- return QPixmap(*p);
+QMessageBox::Icon CheckableMessageBox::icon() const
+{
+ return d->icon;
+}
+
+// See QMessageBoxPrivate::standardIcon
+static QPixmap pixmapForIcon(QMessageBox::Icon icon, QWidget *w)
+{
+ const QStyle *style = w ? w->style() : QApplication::style();
+ const int iconSize = style->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, w);
+ QIcon tmpIcon;
+ switch (icon) {
+ case QMessageBox::Information:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxInformation, nullptr, w);
+ break;
+ case QMessageBox::Warning:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxWarning, nullptr, w);
+ break;
+ case QMessageBox::Critical:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxCritical, nullptr, w);
+ break;
+ case QMessageBox::Question:
+ tmpIcon = style->standardIcon(QStyle::SP_MessageBoxQuestion, nullptr, w);
+ break;
+ default:
+ break;
+ }
+ if (!tmpIcon.isNull()) {
+ QWindow *window = nullptr;
+ if (w) {
+ window = w->windowHandle();
+ if (!window) {
+ if (const QWidget *nativeParent = w->nativeParentWidget())
+ window = nativeParent->windowHandle();
+ }
+ }
+ return tmpIcon.pixmap(window, QSize(iconSize, iconSize));
+ }
return QPixmap();
}
-void CheckableMessageBox::setIconPixmap(const QPixmap &p)
+void CheckableMessageBox::setIcon(QMessageBox::Icon icon)
{
- d->pixmapLabel->setPixmap(p);
- d->pixmapLabel->setVisible(!p.isNull());
+ d->icon = icon;
+ const QPixmap pixmap = pixmapForIcon(icon, this);
+ d->pixmapLabel->setPixmap(pixmap);
+ d->pixmapLabel->setVisible(!pixmap.isNull());
}
bool CheckableMessageBox::isChecked() const
@@ -239,7 +277,7 @@ CheckableMessageBox::question(QWidget *parent,
{
CheckableMessageBox mb(parent);
mb.setWindowTitle(title);
- mb.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Question));
+ mb.setIcon(QMessageBox::Question);
mb.setText(question);
mb.setCheckBoxText(checkBoxText);
mb.setChecked(*checkBoxSetting);
@@ -261,7 +299,7 @@ CheckableMessageBox::information(QWidget *parent,
{
CheckableMessageBox mb(parent);
mb.setWindowTitle(title);
- mb.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Information));
+ mb.setIcon(QMessageBox::Information);
mb.setText(text);
mb.setCheckBoxText(checkBoxText);
mb.setChecked(*checkBoxSetting);
@@ -297,9 +335,7 @@ void initDoNotAskAgainMessageBox(CheckableMessageBox &messageBox, const QString
DoNotAskAgainType type)
{
messageBox.setWindowTitle(title);
- messageBox.setIconPixmap(QMessageBox::standardIcon(type == Information
- ? QMessageBox::Information
- : QMessageBox::Question));
+ messageBox.setIcon(type == Information ? QMessageBox::Information : QMessageBox::Question);
messageBox.setText(text);
messageBox.setCheckBoxVisible(true);
messageBox.setCheckBoxText(type == Information ? CheckableMessageBox::msgDoNotShowAgain()
diff --git a/src/libs/utils/checkablemessagebox.h b/src/libs/utils/checkablemessagebox.h
index c6359f72cd..042e88aa96 100644
--- a/src/libs/utils/checkablemessagebox.h
+++ b/src/libs/utils/checkablemessagebox.h
@@ -42,7 +42,7 @@ class QTCREATOR_UTILS_EXPORT CheckableMessageBox : public QDialog
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText)
- Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap)
+ Q_PROPERTY(QMessageBox::Icon icon READ icon WRITE setIcon)
Q_PROPERTY(bool isChecked READ isChecked WRITE setChecked)
Q_PROPERTY(QString checkBoxText READ checkBoxText WRITE setCheckBoxText)
Q_PROPERTY(QDialogButtonBox::StandardButtons buttons READ standardButtons WRITE setStandardButtons)
@@ -109,9 +109,8 @@ public:
QDialogButtonBox::StandardButton defaultButton() const;
void setDefaultButton(QDialogButtonBox::StandardButton s);
- // See static QMessageBox::standardPixmap()
- QPixmap iconPixmap() const;
- void setIconPixmap (const QPixmap &p);
+ QMessageBox::Icon icon() const;
+ void setIcon(QMessageBox::Icon icon);
// Query the result
QAbstractButton *clickedButton() const;
diff --git a/src/libs/utils/completingtextedit.cpp b/src/libs/utils/completingtextedit.cpp
index f4d7b0441c..3a34973c00 100644
--- a/src/libs/utils/completingtextedit.cpp
+++ b/src/libs/utils/completingtextedit.cpp
@@ -114,7 +114,7 @@ void CompletingTextEdit::setCompleter(QCompleter *c)
completer()->setWidget(this);
completer()->setCompletionMode(QCompleter::PopupCompletion);
- connect(completer(), static_cast<void (QCompleter::*)(const QString &)>(&QCompleter::activated),
+ connect(completer(), QOverload<const QString &>::of(&QCompleter::activated),
this, [this](const QString &str) { d->insertCompletion(str); });
}
diff --git a/src/libs/utils/consoleprocess.h b/src/libs/utils/consoleprocess.h
index 28be67f0bf..3dec9838c3 100644
--- a/src/libs/utils/consoleprocess.h
+++ b/src/libs/utils/consoleprocess.h
@@ -70,7 +70,9 @@ public:
QProcess::ProcessError error() const;
QString errorString() const;
- bool start(const QString &program, const QString &args);
+ enum class MetaCharMode { Abort, Ignore };
+ bool start(const QString &program, const QString &args,
+ MetaCharMode metaCharMode = MetaCharMode::Abort);
public slots:
void stop();
diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp
index 92b69952f6..43afffa0a2 100644
--- a/src/libs/utils/consoleprocess_unix.cpp
+++ b/src/libs/utils/consoleprocess_unix.cpp
@@ -65,7 +65,7 @@ void ConsoleProcess::setSettings(QSettings *settings)
d->m_settings = settings;
}
-bool ConsoleProcess::start(const QString &program, const QString &args)
+bool ConsoleProcess::start(const QString &program, const QString &args, MetaCharMode metaCharMode)
{
if (isRunning())
return false;
@@ -75,7 +75,8 @@ bool ConsoleProcess::start(const QString &program, const QString &args)
QtcProcess::SplitError perr;
QtcProcess::Arguments pargs = QtcProcess::prepareArgs(args, &perr, HostOsInfo::hostOs(),
- &d->m_environment, &d->m_workingDir);
+ &d->m_environment, &d->m_workingDir,
+ metaCharMode == MetaCharMode::Abort);
QString pcmd;
if (perr == QtcProcess::SplitOk) {
pcmd = program;
@@ -436,12 +437,6 @@ bool ConsoleProcess::startTerminalEmulator(QSettings *settings, const QString &w
const Utils::Environment &env)
{
const TerminalCommand term = terminalEmulator(settings);
-#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
- // for 5.9 and below we cannot set the environment
- Q_UNUSED(env);
- return QProcess::startDetached(term.command, QtcProcess::splitArgs(term.openArgs),
- workingDir);
-#else
QProcess process;
process.setProgram(term.command);
process.setArguments(QtcProcess::splitArgs(term.openArgs));
@@ -449,7 +444,6 @@ bool ConsoleProcess::startTerminalEmulator(QSettings *settings, const QString &w
process.setWorkingDirectory(workingDir);
return process.startDetached();
-#endif
}
} // namespace Utils
diff --git a/src/libs/utils/consoleprocess_win.cpp b/src/libs/utils/consoleprocess_win.cpp
index 2a68ddaba8..be65c42cc8 100644
--- a/src/libs/utils/consoleprocess_win.cpp
+++ b/src/libs/utils/consoleprocess_win.cpp
@@ -51,8 +51,10 @@ qint64 ConsoleProcess::applicationMainThreadID() const
return d->m_appMainThreadId;
}
-bool ConsoleProcess::start(const QString &program, const QString &args)
+bool ConsoleProcess::start(const QString &program, const QString &args, MetaCharMode metaCharMode)
{
+ Q_UNUSED(metaCharMode);
+
if (isRunning())
return false;
diff --git a/src/libs/utils/cpplanguage_details.h b/src/libs/utils/cpplanguage_details.h
index 43474d03cb..e9c9a5aa40 100644
--- a/src/libs/utils/cpplanguage_details.h
+++ b/src/libs/utils/cpplanguage_details.h
@@ -29,9 +29,10 @@
namespace Utils {
-enum class Language : unsigned char { C, Cxx };
+enum class Language : unsigned char { None, C, Cxx };
enum class LanguageVersion : unsigned char {
+ None,
C89,
C99,
C11,
diff --git a/src/libs/utils/delegates.cpp b/src/libs/utils/delegates.cpp
index a677c8c992..2240e8a6a4 100644
--- a/src/libs/utils/delegates.cpp
+++ b/src/libs/utils/delegates.cpp
@@ -84,7 +84,7 @@ void AnnotatedItemDelegate::paint(QPainter *painter,
painter->save();
painter->setPen(disabled.color(QPalette::WindowText));
- static int extra = opt.fontMetrics.width(m_delimiter) + 10;
+ static int extra = opt.fontMetrics.horizontalAdvance(m_delimiter) + 10;
const QPixmap &pixmap = opt.icon.pixmap(opt.decorationSize);
const QRect &iconRect = style->itemPixmapRect(opt.rect, opt.decorationAlignment, pixmap);
const QRect &displayRect = style->itemTextRect(opt.fontMetrics, opt.rect,
diff --git a/src/libs/utils/detailsbutton.cpp b/src/libs/utils/detailsbutton.cpp
index 5f2c88eca3..329975afdb 100644
--- a/src/libs/utils/detailsbutton.cpp
+++ b/src/libs/utils/detailsbutton.cpp
@@ -79,7 +79,7 @@ DetailsButton::DetailsButton(QWidget *parent) : QAbstractButton(parent), m_fader
QSize DetailsButton::sizeHint() const
{
// TODO: Adjust this when icons become available!
- const int w = fontMetrics().width(text()) + 32;
+ const int w = fontMetrics().horizontalAdvance(text()) + 32;
if (HostOsInfo::isMacHost())
return QSize(w, 34);
return QSize(w, 22);
diff --git a/src/libs/utils/elidinglabel.cpp b/src/libs/utils/elidinglabel.cpp
index e584bd8bb6..1d90665af5 100644
--- a/src/libs/utils/elidinglabel.cpp
+++ b/src/libs/utils/elidinglabel.cpp
@@ -66,7 +66,7 @@ void ElidingLabel::paintEvent(QPaintEvent *)
QRect contents = contentsRect().adjusted(m, m, -m, -m);
QFontMetrics fm = fontMetrics();
QString txt = text();
- if (txt.length() > 4 && fm.width(txt) > contents.width()) {
+ if (txt.length() > 4 && fm.horizontalAdvance(txt) > contents.width()) {
setToolTip(txt);
txt = fm.elidedText(txt, m_elideMode, contents.width());
} else {
diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp
index a82d6c27f0..d61a75ebf7 100644
--- a/src/libs/utils/environment.cpp
+++ b/src/libs/utils/environment.cpp
@@ -392,14 +392,14 @@ void Environment::clear()
m_values.clear();
}
-FileName Environment::searchInDirectory(const QStringList &execs, const FileName &directory,
- QSet<FileName> &alreadyChecked) const
+FilePath Environment::searchInDirectory(const QStringList &execs, const FilePath &directory,
+ QSet<FilePath> &alreadyChecked) const
{
const int checkedCount = alreadyChecked.count();
alreadyChecked.insert(directory);
if (directory.isEmpty() || alreadyChecked.count() == checkedCount)
- return FileName();
+ return FilePath();
const QString dir = directory.toString();
@@ -407,9 +407,9 @@ FileName Environment::searchInDirectory(const QStringList &execs, const FileName
for (const QString &exec : execs) {
fi.setFile(dir, exec);
if (fi.isFile() && fi.isExecutable())
- return FileName::fromString(fi.absoluteFilePath());
+ return FilePath::fromString(fi.absoluteFilePath());
}
- return FileName();
+ return FilePath();
}
QStringList Environment::appendExeExtensions(const QString &executable) const
@@ -435,23 +435,25 @@ bool Environment::isSameExecutable(const QString &exe1, const QString &exe2) con
const QStringList exe2List = appendExeExtensions(exe2);
for (const QString &i1 : exe1List) {
for (const QString &i2 : exe2List) {
- const FileName f1 = FileName::fromString(i1);
- const FileName f2 = FileName::fromString(i2);
+ const FilePath f1 = FilePath::fromString(i1);
+ const FilePath f2 = FilePath::fromString(i2);
if (f1 == f2)
return true;
if (FileUtils::resolveSymlinks(f1) == FileUtils::resolveSymlinks(f2))
return true;
+ if (FileUtils::fileId(f1) == FileUtils::fileId(f2))
+ return true;
}
}
return false;
}
-FileName Environment::searchInPath(const QString &executable,
- const FileNameList &additionalDirs,
+FilePath Environment::searchInPath(const QString &executable,
+ const FilePathList &additionalDirs,
const PathFilter &func) const
{
if (executable.isEmpty())
- return FileName();
+ return FilePath();
const QString exec = QDir::cleanPath(expandVariables(executable));
const QFileInfo fi(exec);
@@ -462,34 +464,34 @@ FileName Environment::searchInPath(const QString &executable,
for (const QString &path : execs) {
QFileInfo pfi = QFileInfo(path);
if (pfi.isFile() && pfi.isExecutable())
- return FileName::fromString(path);
+ return FilePath::fromString(path);
}
- return FileName::fromString(exec);
+ return FilePath::fromString(exec);
}
- QSet<FileName> alreadyChecked;
- for (const FileName &dir : additionalDirs) {
- FileName tmp = searchInDirectory(execs, dir, alreadyChecked);
+ QSet<FilePath> alreadyChecked;
+ for (const FilePath &dir : additionalDirs) {
+ FilePath tmp = searchInDirectory(execs, dir, alreadyChecked);
if (!tmp.isEmpty() && (!func || func(tmp)))
return tmp;
}
if (executable.contains('/'))
- return FileName();
+ return FilePath();
- for (const FileName &p : path()) {
- FileName tmp = searchInDirectory(execs, p, alreadyChecked);
+ for (const FilePath &p : path()) {
+ FilePath tmp = searchInDirectory(execs, p, alreadyChecked);
if (!tmp.isEmpty() && (!func || func(tmp)))
return tmp;
}
- return FileName();
+ return FilePath();
}
-FileNameList Environment::path() const
+FilePathList Environment::path() const
{
const QStringList pathComponents = value("PATH")
.split(OsSpecificAspects::pathListSeparator(m_osType), QString::SkipEmptyParts);
- return Utils::transform(pathComponents, &FileName::fromUserInput);
+ return Utils::transform(pathComponents, &FilePath::fromUserInput);
}
QString Environment::value(const QString &key) const
@@ -688,6 +690,11 @@ QString Environment::expandVariables(const QString &input) const
return result;
}
+FilePath Environment::expandVariables(const FilePath &variables) const
+{
+ return FilePath::fromString(expandVariables(variables.toString()));
+}
+
QStringList Environment::expandVariables(const QStringList &variables) const
{
return Utils::transform(variables, [this](const QString &i) { return expandVariables(i); });
diff --git a/src/libs/utils/environment.h b/src/libs/utils/environment.h
index cab78a082b..f1e957ab6d 100644
--- a/src/libs/utils/environment.h
+++ b/src/libs/utils/environment.h
@@ -124,17 +124,18 @@ public:
Environment::const_iterator constEnd() const;
Environment::const_iterator constFind(const QString &name) const;
- using PathFilter = std::function<bool(const FileName &)>;
- FileName searchInPath(const QString &executable,
- const FileNameList &additionalDirs = FileNameList(),
+ using PathFilter = std::function<bool(const FilePath &)>;
+ FilePath searchInPath(const QString &executable,
+ const FilePathList &additionalDirs = FilePathList(),
const PathFilter &func = PathFilter()) const;
- FileNameList path() const;
+ FilePathList path() const;
QStringList appendExeExtensions(const QString &executable) const;
bool isSameExecutable(const QString &exe1, const QString &exe2) 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;
@@ -143,8 +144,8 @@ public:
static void modifySystemEnvironment(const QList<EnvironmentItem> &list); // use with care!!!
private:
- FileName searchInDirectory(const QStringList &execs, const FileName &directory,
- QSet<FileName> &alreadyChecked) const;
+ FilePath searchInDirectory(const QStringList &execs, const FilePath &directory,
+ QSet<FilePath> &alreadyChecked) const;
QMap<QString, QString> m_values;
OsType m_osType;
};
diff --git a/src/libs/utils/filecrumblabel.cpp b/src/libs/utils/filecrumblabel.cpp
index a4bbe37c44..cf03af553c 100644
--- a/src/libs/utils/filecrumblabel.cpp
+++ b/src/libs/utils/filecrumblabel.cpp
@@ -38,22 +38,22 @@ FileCrumbLabel::FileCrumbLabel(QWidget *parent)
setTextFormat(Qt::RichText);
setWordWrap(true);
connect(this, &QLabel::linkActivated, this, [this](const QString &url) {
- emit pathClicked(FileName::fromString(QUrl(url).toLocalFile()));
+ emit pathClicked(FilePath::fromString(QUrl(url).toLocalFile()));
});
- setPath(FileName());
+ setPath(FilePath());
}
-static QString linkForPath(const FileName &path, const QString &display)
+static QString linkForPath(const FilePath &path, const QString &display)
{
return "<a href=\""
+ QUrl::fromLocalFile(path.toString()).toString(QUrl::FullyEncoded) + "\">"
+ display + "</a>";
}
-void FileCrumbLabel::setPath(const FileName &path)
+void FileCrumbLabel::setPath(const FilePath &path)
{
QStringList links;
- FileName current = path;
+ FilePath current = path;
while (!current.isEmpty()) {
const QString fileName = current.fileName();
if (!fileName.isEmpty()) {
diff --git a/src/libs/utils/filecrumblabel.h b/src/libs/utils/filecrumblabel.h
index 6320b115c0..05dd050812 100644
--- a/src/libs/utils/filecrumblabel.h
+++ b/src/libs/utils/filecrumblabel.h
@@ -38,10 +38,10 @@ class QTCREATOR_UTILS_EXPORT FileCrumbLabel : public QLabel
public:
FileCrumbLabel(QWidget *parent = nullptr);
- void setPath(const FileName &path);
+ void setPath(const FilePath &path);
signals:
- void pathClicked(const FileName &path);
+ void pathClicked(const FilePath &path);
};
} // Utils
diff --git a/src/libs/utils/fileinprojectfinder.cpp b/src/libs/utils/fileinprojectfinder.cpp
index 2be64260e8..3dbde17792 100644
--- a/src/libs/utils/fileinprojectfinder.cpp
+++ b/src/libs/utils/fileinprojectfinder.cpp
@@ -24,15 +24,20 @@
****************************************************************************/
#include "fileinprojectfinder.h"
+
+#include "algorithm.h"
#include "fileutils.h"
#include "hostosinfo.h"
+#include "qrcparser.h"
#include "qtcassert.h"
+#include <QCursor>
#include <QDebug>
+#include <QDir>
#include <QFileInfo>
#include <QLoggingCategory>
+#include <QMenu>
#include <QUrl>
-#include <QDir>
#include <algorithm>
@@ -77,7 +82,7 @@ static bool checkPath(const QString &candidate, int matchLength,
FileInProjectFinder::FileInProjectFinder() = default;
FileInProjectFinder::~FileInProjectFinder() = default;
-void FileInProjectFinder::setProjectDirectory(const FileName &absoluteProjectPath)
+void FileInProjectFinder::setProjectDirectory(const FilePath &absoluteProjectPath)
{
if (absoluteProjectPath == m_projectDir)
return;
@@ -90,21 +95,22 @@ void FileInProjectFinder::setProjectDirectory(const FileName &absoluteProjectPat
m_cache.clear();
}
-FileName FileInProjectFinder::projectDirectory() const
+FilePath FileInProjectFinder::projectDirectory() const
{
return m_projectDir;
}
-void FileInProjectFinder::setProjectFiles(const FileNameList &projectFiles)
+void FileInProjectFinder::setProjectFiles(const FilePathList &projectFiles)
{
if (m_projectFiles == projectFiles)
return;
m_projectFiles = projectFiles;
m_cache.clear();
+ m_qrcUrlFinder.setProjectFiles(projectFiles);
}
-void FileInProjectFinder::setSysroot(const FileName &sysroot)
+void FileInProjectFinder::setSysroot(const FilePath &sysroot)
{
if (m_sysroot == sysroot)
return;
@@ -113,7 +119,7 @@ void FileInProjectFinder::setSysroot(const FileName &sysroot)
m_cache.clear();
}
-void FileInProjectFinder::addMappedPath(const FileName &localFilePath, const QString &remoteFilePath)
+void FileInProjectFinder::addMappedPath(const FilePath &localFilePath, const QString &remoteFilePath)
{
const QStringList segments = remoteFilePath.split('/', QString::SkipEmptyParts);
@@ -136,18 +142,29 @@ void FileInProjectFinder::addMappedPath(const FileName &localFilePath, const QSt
folder specified. Third, we walk the list of project files, and search for a file name match
there. If all fails, it returns the original path from the file URL.
*/
-QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const
+FilePathList FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const
{
qCDebug(finderLog) << "FileInProjectFinder: trying to find file" << fileUrl.toString() << "...";
+ if (fileUrl.scheme() == "qrc" || fileUrl.toString().startsWith(':')) {
+ const FilePathList result = m_qrcUrlFinder.find(fileUrl);
+ if (!result.isEmpty()) {
+ if (success)
+ *success = true;
+ return result;
+ }
+ }
+
QString originalPath = fileUrl.toLocalFile();
if (originalPath.isEmpty()) // e.g. qrc://
originalPath = fileUrl.path();
- QString result = originalPath;
+ FilePathList result;
bool found = findFileOrDirectory(originalPath, [&](const QString &fileName, int) {
- result = fileName;
+ result << FilePath::fromString(fileName);
});
+ if (!found)
+ result << FilePath::fromString(originalPath);
if (success)
*success = found;
@@ -155,12 +172,12 @@ QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const
return result;
}
-bool FileInProjectFinder::handleSuccess(const QString &originalPath, const QString &found,
+bool FileInProjectFinder::handleSuccess(const QString &originalPath, const QStringList &found,
int matchLength, const char *where) const
{
qCDebug(finderLog) << "FileInProjectFinder: found" << found << where;
CacheEntry entry;
- entry.path = found;
+ entry.paths = found;
entry.matchLength = matchLength;
m_cache.insert(originalPath, entry);
return true;
@@ -189,8 +206,10 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH
if (node) {
if (!node->localPath.isEmpty()) {
const QString localPath = node->localPath.toString();
- if (checkPath(localPath, origLength, fileHandler, directoryHandler))
- return handleSuccess(originalPath, localPath, origLength, "in mapped paths");
+ if (checkPath(localPath, origLength, fileHandler, directoryHandler)) {
+ return handleSuccess(originalPath, QStringList(localPath), origLength,
+ "in mapped paths");
+ }
} else if (directoryHandler) {
directoryHandler(node->children.keys(), origLength);
qCDebug(finderLog) << "FileInProjectFinder: found virtual directory" << originalPath
@@ -203,13 +222,18 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH
if (it != m_cache.end()) {
qCDebug(finderLog) << "FileInProjectFinder: checking cache ...";
// check if cached path is still there
- const CacheEntry &candidate = it.value();
- if (checkPath(candidate.path, candidate.matchLength, fileHandler, directoryHandler)) {
- qCDebug(finderLog) << "FileInProjectFinder: found" << candidate.path << "in the cache";
- return true;
- } else {
- m_cache.erase(it);
+ CacheEntry &candidate = it.value();
+ for (auto pathIt = candidate.paths.begin(); pathIt != candidate.paths.end();) {
+ if (checkPath(*pathIt, candidate.matchLength, fileHandler, directoryHandler)) {
+ qCDebug(finderLog) << "FileInProjectFinder: found" << *pathIt << "in the cache";
+ ++pathIt;
+ } else {
+ pathIt = candidate.paths.erase(pathIt);
+ }
}
+ if (!candidate.paths.empty())
+ return true;
+ m_cache.erase(it);
}
if (!m_projectDir.isEmpty()) {
@@ -231,7 +255,7 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH
if (prefixToIgnore == -1
&& checkPath(originalPath, origLength, fileHandler, directoryHandler)) {
- return handleSuccess(originalPath, originalPath, origLength,
+ return handleSuccess(originalPath, QStringList(originalPath), origLength,
"in project directory");
}
}
@@ -254,8 +278,11 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH
candidate.remove(0, prefixToIgnore);
candidate.prepend(m_projectDir.toString());
const int matchLength = origLength - prefixToIgnore;
- if (checkPath(candidate, matchLength, fileHandler, directoryHandler))
- return handleSuccess(originalPath, candidate, matchLength, "in project directory");
+ // FIXME: This might be a worse match than what we find later.
+ if (checkPath(candidate, matchLength, fileHandler, directoryHandler)) {
+ return handleSuccess(originalPath, QStringList(candidate), matchLength,
+ "in project directory");
+ }
prefixToIgnore = originalPath.indexOf(separator, prefixToIgnore + 1);
}
}
@@ -264,31 +291,38 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH
qCDebug(finderLog) << "FileInProjectFinder: checking project files ...";
QStringList matches;
- const QString lastSegment = FileName::fromString(originalPath).fileName();
+ const QString lastSegment = FilePath::fromString(originalPath).fileName();
if (fileHandler)
matches.append(filesWithSameFileName(lastSegment));
if (directoryHandler)
matches.append(pathSegmentsWithSameName(lastSegment));
- const QString matchedFilePath = bestMatch(matches, originalPath);
- const int matchLength = commonPostFixLength(matchedFilePath, originalPath);
- if (!matchedFilePath.isEmpty()
- && checkPath(matchedFilePath, matchLength, fileHandler, directoryHandler)) {
- return handleSuccess(originalPath, matchedFilePath, matchLength,
- "when matching project files");
+ const QStringList matchedFilePaths = bestMatches(matches, originalPath);
+ if (!matchedFilePaths.empty()) {
+ const int matchLength = commonPostFixLength(matchedFilePaths.first(), originalPath);
+ QStringList hits;
+ for (const QString &matchedFilePath : matchedFilePaths) {
+ if (checkPath(matchedFilePath, matchLength, fileHandler, directoryHandler))
+ hits << matchedFilePath;
+ }
+ if (!hits.empty())
+ return handleSuccess(originalPath, hits, matchLength, "when matching project files");
}
CacheEntry foundPath = findInSearchPaths(originalPath, fileHandler, directoryHandler);
- if (!foundPath.path.isEmpty())
- return handleSuccess(originalPath, foundPath.path, foundPath.matchLength, "in search path");
+ if (!foundPath.paths.isEmpty()) {
+ return handleSuccess(originalPath, foundPath.paths, foundPath.matchLength,
+ "in search path");
+ }
qCDebug(finderLog) << "FileInProjectFinder: checking absolute path in sysroot ...";
// check if absolute path is found in sysroot
if (!m_sysroot.isEmpty()) {
- FileName sysrootPath = m_sysroot;
- sysrootPath.appendPath(originalPath);
- if (checkPath(sysrootPath.toString(), origLength, fileHandler, directoryHandler))
- return handleSuccess(originalPath, sysrootPath.toString(), origLength, "in sysroot");
+ const FilePath sysrootPath = m_sysroot.pathAppended(originalPath);
+ if (checkPath(sysrootPath.toString(), origLength, fileHandler, directoryHandler)) {
+ return handleSuccess(originalPath, QStringList(sysrootPath.toString()), origLength,
+ "in sysroot");
+ }
}
qCDebug(finderLog) << "FileInProjectFinder: couldn't find file!";
@@ -299,10 +333,10 @@ bool FileInProjectFinder::findFileOrDirectory(const QString &originalPath, FileH
FileInProjectFinder::CacheEntry FileInProjectFinder::findInSearchPaths(
const QString &filePath, FileHandler fileHandler, DirectoryHandler directoryHandler) const
{
- for (const FileName &dirPath : m_searchDirectories) {
+ for (const FilePath &dirPath : m_searchDirectories) {
const CacheEntry found = findInSearchPath(dirPath.toString(), filePath,
fileHandler, directoryHandler);
- if (!found.path.isEmpty())
+ if (!found.paths.isEmpty())
return found;
}
@@ -327,17 +361,17 @@ FileInProjectFinder::CacheEntry FileInProjectFinder::findInSearchPath(
QString s = filePath;
while (!s.isEmpty()) {
CacheEntry result;
- result.path = searchPath + QLatin1Char('/') + s;
+ result.paths << searchPath + '/' + s;
result.matchLength = s.length() + 1;
- qCDebug(finderLog) << "FileInProjectFinder: trying" << result.path;
+ qCDebug(finderLog) << "FileInProjectFinder: trying" << result.paths.first();
- if (checkPath(result.path, result.matchLength, fileHandler, directoryHandler))
+ if (checkPath(result.paths.first(), result.matchLength, fileHandler, directoryHandler))
return result;
QString next = chopFirstDir(s);
if (next.isEmpty()) {
if (directoryHandler && QFileInfo(searchPath).fileName() == s) {
- result.path = searchPath;
+ result.paths = QStringList{searchPath};
directoryHandler(QDir(searchPath).entryList(), result.matchLength);
return result;
}
@@ -352,7 +386,7 @@ FileInProjectFinder::CacheEntry FileInProjectFinder::findInSearchPath(
QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName) const
{
QStringList result;
- foreach (const FileName &f, m_projectFiles) {
+ foreach (const FilePath &f, m_projectFiles) {
if (f.fileName() == fileName)
result << f.toString();
}
@@ -362,8 +396,8 @@ QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName)
QStringList FileInProjectFinder::pathSegmentsWithSameName(const QString &pathSegment) const
{
QStringList result;
- for (const FileName &f : m_projectFiles) {
- FileName currentPath = f.parentDir();
+ for (const FilePath &f : m_projectFiles) {
+ FilePath currentPath = f.parentDir();
do {
if (currentPath.fileName() == pathSegment) {
if (result.isEmpty() || result.last() != currentPath.toString())
@@ -386,32 +420,38 @@ int FileInProjectFinder::commonPostFixLength(const QString &candidatePath,
return rank;
}
-QString FileInProjectFinder::bestMatch(const QStringList &filePaths, const QString &filePathToFind)
+QStringList FileInProjectFinder::bestMatches(const QStringList &filePaths,
+ const QString &filePathToFind)
{
if (filePaths.isEmpty())
- return QString();
+ return {};
if (filePaths.length() == 1) {
qCDebug(finderLog) << "FileInProjectFinder: found" << filePaths.first()
<< "in project files";
- return filePaths.first();
+ return filePaths;
}
- auto it = std::max_element(filePaths.constBegin(), filePaths.constEnd(),
- [&filePathToFind] (const QString &a, const QString &b) -> bool {
- return commonPostFixLength(a, filePathToFind) < commonPostFixLength(b, filePathToFind);
- });
- if (it != filePaths.cend()) {
- qCDebug(finderLog) << "FileInProjectFinder: found best match" << *it << "in project files";
- return *it;
+ int bestRank = -1;
+ QStringList bestFilePaths;
+ for (const QString &fp : filePaths) {
+ const int currentRank = commonPostFixLength(fp, filePathToFind);
+ if (currentRank < bestRank)
+ continue;
+ if (currentRank > bestRank) {
+ bestRank = currentRank;
+ bestFilePaths.clear();
+ }
+ bestFilePaths << fp;
}
- return QString();
+ QTC_CHECK(!bestFilePaths.empty());
+ return bestFilePaths;
}
-FileNameList FileInProjectFinder::searchDirectories() const
+FilePathList FileInProjectFinder::searchDirectories() const
{
return m_searchDirectories;
}
-void FileInProjectFinder::setAdditionalSearchDirectories(const FileNameList &searchDirectories)
+void FileInProjectFinder::setAdditionalSearchDirectories(const FilePathList &searchDirectories)
{
m_searchDirectories = searchDirectories;
}
@@ -421,4 +461,43 @@ FileInProjectFinder::PathMappingNode::~PathMappingNode()
qDeleteAll(children);
}
+FilePathList FileInProjectFinder::QrcUrlFinder::find(const QUrl &fileUrl) const
+{
+ const auto fileIt = m_fileCache.constFind(fileUrl);
+ if (fileIt != m_fileCache.cend())
+ return fileIt.value();
+ QStringList hits;
+ for (const FilePath &f : m_allQrcFiles) {
+ QrcParser::Ptr &qrcParser = m_parserCache[f];
+ if (!qrcParser)
+ qrcParser = QrcParser::parseQrcFile(f.toString(), QString());
+ if (!qrcParser->isValid())
+ continue;
+ qrcParser->collectFilesAtPath(QrcParser::normalizedQrcFilePath(fileUrl.toString()), &hits);
+ }
+ hits.removeDuplicates();
+ const FilePathList result = transform(hits, &FilePath::fromString);
+ m_fileCache.insert(fileUrl, result);
+ return result;
+}
+
+void FileInProjectFinder::QrcUrlFinder::setProjectFiles(const FilePathList &projectFiles)
+{
+ m_allQrcFiles = filtered(projectFiles, [](const FilePath &f) { return f.endsWith(".qrc"); });
+ m_fileCache.clear();
+ m_parserCache.clear();
+}
+
+FilePath chooseFileFromList(const FilePathList &candidates)
+{
+ if (candidates.length() == 1)
+ return candidates.first();
+ QMenu filesMenu;
+ for (const FilePath &candidate : candidates)
+ filesMenu.addAction(candidate.toUserOutput());
+ if (const QAction * const action = filesMenu.exec(QCursor::pos()))
+ return FilePath::fromUserInput(action->text());
+ return FilePath();
+}
+
} // namespace Utils
diff --git a/src/libs/utils/fileinprojectfinder.h b/src/libs/utils/fileinprojectfinder.h
index 43a954ff93..66b5317235 100644
--- a/src/libs/utils/fileinprojectfinder.h
+++ b/src/libs/utils/fileinprojectfinder.h
@@ -29,11 +29,13 @@
#include <utils/fileutils.h>
#include <QHash>
+#include <QSharedPointer>
#include <QStringList>
QT_FORWARD_DECLARE_CLASS(QUrl)
namespace Utils {
+class QrcParser;
class QTCREATOR_UTILS_EXPORT FileInProjectFinder
{
@@ -45,34 +47,44 @@ public:
FileInProjectFinder();
~FileInProjectFinder();
- void setProjectDirectory(const FileName &absoluteProjectPath);
- FileName projectDirectory() const;
+ void setProjectDirectory(const FilePath &absoluteProjectPath);
+ FilePath projectDirectory() const;
- void setProjectFiles(const FileNameList &projectFiles);
- void setSysroot(const FileName &sysroot);
+ void setProjectFiles(const FilePathList &projectFiles);
+ void setSysroot(const FilePath &sysroot);
- void addMappedPath(const FileName &localFilePath, const QString &remoteFilePath);
+ void addMappedPath(const FilePath &localFilePath, const QString &remoteFilePath);
- QString findFile(const QUrl &fileUrl, bool *success = nullptr) const;
+ FilePathList findFile(const QUrl &fileUrl, bool *success = nullptr) const;
bool findFileOrDirectory(const QString &originalPath, FileHandler fileHandler = nullptr,
DirectoryHandler directoryHandler = nullptr) const;
- FileNameList searchDirectories() const;
- void setAdditionalSearchDirectories(const FileNameList &searchDirectories);
+ FilePathList searchDirectories() const;
+ void setAdditionalSearchDirectories(const FilePathList &searchDirectories);
private:
struct PathMappingNode
{
~PathMappingNode();
- FileName localPath;
+ FilePath localPath;
QHash<QString, PathMappingNode *> children;
};
struct CacheEntry {
- QString path;
+ QStringList paths;
int matchLength = 0;
};
+ class QrcUrlFinder {
+ public:
+ FilePathList find(const QUrl &fileUrl) const;
+ void setProjectFiles(const FilePathList &projectFiles);
+ private:
+ FilePathList m_allQrcFiles;
+ mutable QHash<QUrl, FilePathList> m_fileCache;
+ mutable QHash<FilePath, QSharedPointer<QrcParser>> m_parserCache;
+ };
+
CacheEntry findInSearchPaths(const QString &filePath, FileHandler fileHandler,
DirectoryHandler directoryHandler) const;
static CacheEntry findInSearchPath(const QString &searchPath, const QString &filePath,
@@ -80,19 +92,22 @@ private:
QStringList filesWithSameFileName(const QString &fileName) const;
QStringList pathSegmentsWithSameName(const QString &path) const;
- bool handleSuccess(const QString &originalPath, const QString &found, int confidence,
+ bool handleSuccess(const QString &originalPath, const QStringList &found, int confidence,
const char *where) const;
static int commonPostFixLength(const QString &candidatePath, const QString &filePathToFind);
- static QString bestMatch(const QStringList &filePaths, const QString &filePathToFind);
+ static QStringList bestMatches(const QStringList &filePaths, const QString &filePathToFind);
- FileName m_projectDir;
- FileName m_sysroot;
- FileNameList m_projectFiles;
- FileNameList m_searchDirectories;
+ FilePath m_projectDir;
+ FilePath m_sysroot;
+ FilePathList m_projectFiles;
+ FilePathList m_searchDirectories;
PathMappingNode m_pathMapRoot;
mutable QHash<QString, CacheEntry> m_cache;
+ QrcUrlFinder m_qrcUrlFinder;
};
+QTCREATOR_UTILS_EXPORT FilePath chooseFileFromList(const FilePathList &candidates);
+
} // namespace Utils
diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp
index c34532a1de..0bdf3991c5 100644
--- a/src/libs/utils/filesearch.cpp
+++ b/src/libs/utils/filesearch.cpp
@@ -482,7 +482,7 @@ static bool matches(const QList<QRegExp> &exprList, const QString &filePath)
{
return Utils::anyOf(exprList, [&filePath](QRegExp reg) {
return (reg.exactMatch(filePath)
- || reg.exactMatch(FileName::fromString(filePath).fileName()));
+ || reg.exactMatch(FilePath::fromString(filePath).fileName()));
});
}
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index a476cd8d89..acf9c6190d 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -28,20 +28,27 @@
#include "algorithm.h"
#include "qtcassert.h"
+#include "qtcprocess.h"
#include <QDataStream>
#include <QDir>
#include <QDebug>
#include <QDateTime>
+#include <QOperatingSystemVersion>
#include <QRegExp>
#include <QTimer>
#include <QUrl>
+#include <qplatformdefs.h>
#ifdef QT_GUI_LIB
#include <QMessageBox>
#endif
#ifdef Q_OS_WIN
+// We need defines for Windows 8
+#undef _WIN32_WINNT
+#define _WIN32_WINNT _WIN32_WINNT_WIN8
+
#include <qt_windows.h>
#include <shlobj.h>
#endif
@@ -51,7 +58,7 @@
#endif
QT_BEGIN_NAMESPACE
-QDebug operator<<(QDebug dbg, const Utils::FileName &c)
+QDebug operator<<(QDebug dbg, const Utils::FilePath &c)
{
return dbg << c.toString();
}
@@ -60,6 +67,34 @@ QT_END_NAMESPACE
namespace Utils {
+/*! \class Utils::CommandLine
+
+ \brief The CommandLine class represents a command line of a QProcess
+ or similar utility.
+
+*/
+
+void CommandLine::addArg(const QString &arg, OsType osType)
+{
+ QtcProcess::addArg(&m_arguments, arg, osType);
+}
+
+void CommandLine::addArgs(const QStringList &inArgs, OsType osType)
+{
+ for (const QString &arg : inArgs)
+ addArg(arg, osType);
+}
+
+void CommandLine::addArgs(const QString &inArgs)
+{
+ QtcProcess::addArgs(&m_arguments, inArgs);
+}
+
+QString CommandLine::toUserOutput() const
+{
+ return m_executable.toUserOutput() + ' ' + m_arguments;
+}
+
/*! \class Utils::FileUtils
\brief The FileUtils class contains file and directory related convenience
@@ -74,7 +109,7 @@ namespace Utils {
Returns whether the operation succeeded.
*/
-bool FileUtils::removeRecursively(const FileName &filePath, QString *error)
+bool FileUtils::removeRecursively(const FilePath &filePath, QString *error)
{
QFileInfo fileInfo = filePath.toFileInfo();
if (!fileInfo.exists() && !fileInfo.isSymLink())
@@ -101,7 +136,7 @@ bool FileUtils::removeRecursively(const FileName &filePath, QString *error)
QStringList fileNames = dir.entryList(QDir::Files | QDir::Hidden
| QDir::System | QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QString &fileName, fileNames) {
- if (!removeRecursively(FileName(filePath).appendPath(fileName), error))
+ if (!removeRecursively(filePath.pathAppended(fileName), error))
return false;
}
if (!QDir::root().rmdir(dir.path())) {
@@ -140,7 +175,7 @@ bool FileUtils::removeRecursively(const FileName &filePath, QString *error)
Returns whether the operation succeeded.
*/
-bool FileUtils::copyRecursively(const FileName &srcFilePath, const FileName &tgtFilePath,
+bool FileUtils::copyRecursively(const FilePath &srcFilePath, const FilePath &tgtFilePath,
QString *error, const std::function<bool (QFileInfo, QFileInfo, QString *)> &copyHelper)
{
QFileInfo srcFileInfo = srcFilePath.toFileInfo();
@@ -160,10 +195,8 @@ bool FileUtils::copyRecursively(const FileName &srcFilePath, const FileName &tgt
QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot
| QDir::Hidden | QDir::System);
foreach (const QString &fileName, fileNames) {
- FileName newSrcFilePath = srcFilePath;
- newSrcFilePath.appendPath(fileName);
- FileName newTgtFilePath = tgtFilePath;
- newTgtFilePath.appendPath(fileName);
+ const FilePath newSrcFilePath = srcFilePath.pathAppended(fileName);
+ const FilePath newTgtFilePath = tgtFilePath.pathAppended(fileName);
if (!copyRecursively(newSrcFilePath, newTgtFilePath, error, copyHelper))
return false;
}
@@ -185,23 +218,23 @@ bool FileUtils::copyRecursively(const FileName &srcFilePath, const FileName &tgt
}
/*!
- If \a filePath is a directory, the function will recursively check all files and return
- true if one of them is newer than \a timeStamp. If \a filePath is a single file, true will
+ If this is a directory, the function will recursively check all files and return
+ true if one of them is newer than \a timeStamp. If this is a single file, true will
be returned if the file is newer than \a timeStamp.
Returns whether at least one file in \a filePath has a newer date than
\a timeStamp.
*/
-bool FileUtils::isFileNewerThan(const FileName &filePath, const QDateTime &timeStamp)
+bool FilePath::isNewerThan(const QDateTime &timeStamp) const
{
- QFileInfo fileInfo = filePath.toFileInfo();
+ const QFileInfo fileInfo = toFileInfo();
if (!fileInfo.exists() || fileInfo.lastModified() >= timeStamp)
return true;
if (fileInfo.isDir()) {
- const QStringList dirContents = QDir(filePath.toString())
+ const QStringList dirContents = QDir(toString())
.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
- foreach (const QString &curFileName, dirContents) {
- if (isFileNewerThan(FileName(filePath).appendPath(curFileName), timeStamp))
+ for (const QString &curFileName : dirContents) {
+ if (pathAppended(curFileName).isNewerThan(timeStamp))
return true;
}
}
@@ -218,30 +251,30 @@ bool FileUtils::isFileNewerThan(const FileName &filePath, const QDateTime &timeS
Returns the symlink target file path.
*/
-FileName FileUtils::resolveSymlinks(const FileName &path)
+FilePath FileUtils::resolveSymlinks(const FilePath &path)
{
QFileInfo f = path.toFileInfo();
int links = 16;
while (links-- && f.isSymLink())
f.setFile(f.dir(), f.symLinkTarget());
if (links <= 0)
- return FileName();
- return FileName::fromString(f.filePath());
+ return FilePath();
+ return FilePath::fromString(f.filePath());
}
/*!
- Recursively resolves possibly present symlinks in \a filePath.
+ Recursively resolves possibly present symlinks in this file name.
Unlike QFileInfo::canonicalFilePath(), this function will not return an empty
string if path doesn't exist.
Returns the canonical path.
*/
-FileName FileUtils::canonicalPath(const FileName &path)
+FilePath FilePath::canonicalPath() const
{
- const QString result = path.toFileInfo().canonicalFilePath();
+ const QString result = toFileInfo().canonicalFilePath();
if (result.isEmpty())
- return path;
- return FileName::fromString(result);
+ return *this;
+ return FilePath::fromString(result);
}
/*!
@@ -250,16 +283,16 @@ FileName FileUtils::canonicalPath(const FileName &path)
Returns the possibly shortened path with native separators.
*/
-QString FileUtils::shortNativePath(const FileName &path)
+QString FilePath::shortNativePath() const
{
if (HostOsInfo::isAnyUnixHost()) {
- const FileName home = FileName::fromString(QDir::cleanPath(QDir::homePath()));
- if (path.isChildOf(home)) {
+ const FilePath home = FilePath::fromString(QDir::cleanPath(QDir::homePath()));
+ if (isChildOf(home)) {
return QLatin1Char('~') + QDir::separator()
- + QDir::toNativeSeparators(path.relativeChildPath(home).toString());
+ + QDir::toNativeSeparators(relativeChildPath(home).toString());
}
}
- return path.toUserOutput();
+ return toUserOutput();
}
QString FileUtils::fileSystemFriendlyName(const QString &name)
@@ -293,10 +326,10 @@ QString FileUtils::qmakeFriendlyName(const QString &name)
return fileSystemFriendlyName(result);
}
-bool FileUtils::makeWritable(const FileName &path)
+bool FileUtils::makeWritable(const FilePath &path)
{
- const QString fileName = path.toString();
- return QFile::setPermissions(fileName, QFile::permissions(fileName) | QFile::WriteUser);
+ const QString filePath = path.toString();
+ return QFile::setPermissions(filePath, QFile::permissions(filePath) | QFile::WriteUser);
}
// makes sure that capitalization of directories is canonical on Windows and OS X.
@@ -347,12 +380,80 @@ QString FileUtils::resolvePath(const QString &baseDir, const QString &fileName)
return QDir::cleanPath(baseDir + QLatin1Char('/') + fileName);
}
-FileName FileUtils::commonPath(const FileName &oldCommonPath, const FileName &fileName)
+FilePath FileUtils::commonPath(const FilePath &oldCommonPath, const FilePath &filePath)
{
- FileName newCommonPath = oldCommonPath;
- while (!newCommonPath.isEmpty() && !fileName.isChildOf(newCommonPath))
+ FilePath newCommonPath = oldCommonPath;
+ while (!newCommonPath.isEmpty() && !filePath.isChildOf(newCommonPath))
newCommonPath = newCommonPath.parentDir();
- return canonicalPath(newCommonPath);
+ return newCommonPath.canonicalPath();
+}
+
+// Copied from qfilesystemengine_win.cpp
+#ifdef Q_OS_WIN
+
+// File ID for Windows up to version 7.
+static inline QByteArray fileIdWin7(HANDLE handle)
+{
+ BY_HANDLE_FILE_INFORMATION info;
+ if (GetFileInformationByHandle(handle, &info)) {
+ char buffer[sizeof "01234567:0123456701234567\0"];
+ qsnprintf(buffer, sizeof(buffer), "%lx:%08lx%08lx",
+ info.dwVolumeSerialNumber,
+ info.nFileIndexHigh,
+ info.nFileIndexLow);
+ return QByteArray(buffer);
+ }
+ return QByteArray();
+}
+
+// File ID for Windows starting from version 8.
+static QByteArray fileIdWin8(HANDLE handle)
+{
+ QByteArray result;
+ FILE_ID_INFO infoEx;
+ if (GetFileInformationByHandleEx(handle,
+ static_cast<FILE_INFO_BY_HANDLE_CLASS>(18), // FileIdInfo in Windows 8
+ &infoEx, sizeof(FILE_ID_INFO))) {
+ result = QByteArray::number(infoEx.VolumeSerialNumber, 16);
+ result += ':';
+ // Note: MinGW-64's definition of FILE_ID_128 differs from the MSVC one.
+ result += QByteArray(reinterpret_cast<const char *>(&infoEx.FileId), int(sizeof(infoEx.FileId))).toHex();
+ }
+ return result;
+}
+
+static QByteArray fileIdWin(HANDLE fHandle)
+{
+ return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8 ?
+ fileIdWin8(HANDLE(fHandle)) : fileIdWin7(HANDLE(fHandle));
+}
+#endif
+
+QByteArray FileUtils::fileId(const FilePath &fileName)
+{
+ QByteArray result;
+
+#ifdef Q_OS_WIN
+ const HANDLE handle =
+ CreateFile((wchar_t*)fileName.toUserOutput().utf16(), 0,
+ FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (handle != INVALID_HANDLE_VALUE) {
+ result = fileIdWin(handle);
+ CloseHandle(handle);
+ }
+#else // Copied from qfilesystemengine_unix.cpp
+ if (Q_UNLIKELY(fileName.isEmpty()))
+ return result;
+
+ QT_STATBUF statResult;
+ if (QT_STAT(fileName.toString().toLocal8Bit().constData(), &statResult))
+ return result;
+ result = QByteArray::number(quint64(statResult.st_dev), 16);
+ result += ':';
+ result += QByteArray::number(quint64(statResult.st_ino));
+#endif
+ return result;
}
QByteArray FileReader::fetchQrc(const QString &fileName)
@@ -553,114 +654,131 @@ TempFileSaver::~TempFileSaver()
QFile::remove(m_fileName);
}
-/*! \class Utils::FileName
+/*! \class Utils::FilePath
- \brief The FileName class is a light-weight convenience class for filenames.
+ \brief The FilePath class is a light-weight convenience class for filenames.
On windows filenames are compared case insensitively.
*/
-FileName::FileName()
- : QString()
+FilePath::FilePath()
{
-
}
-/// Constructs a FileName from \a info
-FileName::FileName(const QFileInfo &info)
- : QString(info.absoluteFilePath())
+/// Constructs a FilePath from \a info
+FilePath FilePath::fromFileInfo(const QFileInfo &info)
{
+ return FilePath::fromString(info.absoluteFilePath());
}
/// \returns a QFileInfo
-QFileInfo FileName::toFileInfo() const
+QFileInfo FilePath::toFileInfo() const
{
- return QFileInfo(*this);
+ return QFileInfo(m_data);
+}
+
+FilePath FilePath::fromUrl(const QUrl &url)
+{
+ FilePath fn;
+ fn.m_url = url;
+ fn.m_data = url.path();
+ return fn;
}
/// \returns a QString for passing on to QString based APIs
-const QString &FileName::toString() const
+const QString &FilePath::toString() const
+{
+ return m_data;
+}
+
+QUrl FilePath::toUrl() const
{
- return *this;
+ return m_url;
}
/// \returns a QString to display to the user
/// Converts the separators to the native format
-QString FileName::toUserOutput() const
+QString FilePath::toUserOutput() const
{
- return QDir::toNativeSeparators(toString());
+ if (m_url.isEmpty())
+ return QDir::toNativeSeparators(toString());
+ return m_url.toString();
}
-QString FileName::fileName(int pathComponents) const
+QString FilePath::fileName(int pathComponents) const
{
if (pathComponents < 0)
- return *this;
+ return m_data;
const QChar slash = QLatin1Char('/');
- int i = lastIndexOf(slash);
+ int i = m_data.lastIndexOf(slash);
if (pathComponents == 0 || i == -1)
- return mid(i + 1);
+ return m_data.mid(i + 1);
int component = i + 1;
// skip adjacent slashes
- while (i > 0 && at(--i) == slash);
+ while (i > 0 && m_data.at(--i) == slash)
+ ;
while (i >= 0 && --pathComponents >= 0) {
- i = lastIndexOf(slash, i);
+ i = m_data.lastIndexOf(slash, i);
component = i + 1;
- while (i > 0 && at(--i) == slash);
+ while (i > 0 && m_data.at(--i) == slash)
+ ;
}
// If there are no more slashes before the found one, return the entire string
- if (i > 0 && lastIndexOf(slash, i) != -1)
- return mid(component);
- return *this;
+ if (i > 0 && m_data.lastIndexOf(slash, i) != -1)
+ return m_data.mid(component);
+ return m_data;
}
/// \returns a bool indicating whether a file with this
-/// FileName exists.
-bool FileName::exists() const
+/// FilePath exists.
+bool FilePath::exists() const
{
- return !isEmpty() && QFileInfo::exists(*this);
+ return !isEmpty() && QFileInfo::exists(m_data);
}
/// Find the parent directory of a given directory.
-/// Returns an empty FileName if the current directory is already
+/// Returns an empty FilePath if the current directory is already
/// a root level directory.
-/// \returns \a FileName with the last segment removed.
-FileName FileName::parentDir() const
+/// \returns \a FilePath with the last segment removed.
+FilePath FilePath::parentDir() const
{
const QString basePath = toString();
if (basePath.isEmpty())
- return FileName();
+ return FilePath();
const QDir base(basePath);
if (base.isRoot())
- return FileName();
+ return FilePath();
const QString path = basePath + QLatin1String("/..");
const QString parent = QDir::cleanPath(path);
- QTC_ASSERT(parent != path, return FileName());
+ QTC_ASSERT(parent != path, return FilePath());
- return FileName::fromString(parent);
+ return FilePath::fromString(parent);
}
-/// Constructs a FileName from \a filename
+/// Constructs a FilePath from \a filename
/// \a filename is not checked for validity.
-FileName FileName::fromString(const QString &filename)
+FilePath FilePath::fromString(const QString &filename)
{
- return FileName(filename);
+ FilePath fn;
+ fn.m_data = filename;
+ return fn;
}
-/// Constructs a FileName from \a fileName. The \a defaultExtension is appended
+/// Constructs a FilePath from \a filePath. The \a defaultExtension is appended
/// to \a filename if that does not have an extension already.
-/// \a fileName is not checked for validity.
-FileName FileName::fromString(const QString &filename, const QString &defaultExtension)
+/// \a filePath is not checked for validity.
+FilePath FilePath::fromStringWithExtension(const QString &filepath, const QString &defaultExtension)
{
- if (filename.isEmpty() || defaultExtension.isEmpty())
- return filename;
+ if (filepath.isEmpty() || defaultExtension.isEmpty())
+ return FilePath::fromString(filepath);
- QString rc = filename;
- QFileInfo fi(filename);
+ QString rc = filepath;
+ QFileInfo fi(filepath);
// Add extension unless user specified something else
const QChar dot = QLatin1Char('.');
if (!fi.fileName().contains(dot)) {
@@ -668,138 +786,148 @@ FileName FileName::fromString(const QString &filename, const QString &defaultExt
rc += dot;
rc += defaultExtension;
}
- return rc;
-}
-
-/// Constructs a FileName from \a fileName
-/// \a fileName is not checked for validity.
-FileName FileName::fromLatin1(const QByteArray &filename)
-{
- return FileName(QString::fromLatin1(filename));
+ return FilePath::fromString(rc);
}
-/// Constructs a FileName from \a fileName
-/// \a fileName is only passed through QDir::cleanPath
-FileName FileName::fromUserInput(const QString &filename)
+/// Constructs a FilePath from \a filePath
+/// \a filePath is only passed through QDir::cleanPath
+FilePath FilePath::fromUserInput(const QString &filePath)
{
- QString clean = QDir::cleanPath(filename);
+ QString clean = QDir::cleanPath(filePath);
if (clean.startsWith(QLatin1String("~/")))
clean = QDir::homePath() + clean.mid(1);
- return FileName(clean);
+ return FilePath::fromString(clean);
}
-/// Constructs a FileName from \a fileName, which is encoded as UTF-8.
-/// \a fileName is not checked for validity.
-FileName FileName::fromUtf8(const char *filename, int filenameSize)
+/// Constructs a FilePath from \a filePath, which is encoded as UTF-8.
+/// \a filePath is not checked for validity.
+FilePath FilePath::fromUtf8(const char *filename, int filenameSize)
{
- return FileName(QString::fromUtf8(filename, filenameSize));
+ return FilePath::fromString(QString::fromUtf8(filename, filenameSize));
}
-FileName::FileName(const QString &string)
- : QString(string)
+FilePath FilePath::fromVariant(const QVariant &variant)
{
+ if (variant.type() == QVariant::Url)
+ return FilePath::fromUrl(variant.toUrl());
+ return FilePath::fromString(variant.toString());
+}
+QVariant FilePath::toVariant() const
+{
+ if (!m_url.isEmpty())
+ return m_url;
+ return m_data;
}
-bool FileName::operator==(const FileName &other) const
+bool FilePath::operator==(const FilePath &other) const
{
- return QString::compare(*this, other, HostOsInfo::fileNameCaseSensitivity()) == 0;
+ if (!m_url.isEmpty())
+ return m_url == other.m_url;
+ return QString::compare(m_data, other.m_data, HostOsInfo::fileNameCaseSensitivity()) == 0;
}
-bool FileName::operator!=(const FileName &other) const
+bool FilePath::operator!=(const FilePath &other) const
{
return !(*this == other);
}
-bool FileName::operator<(const FileName &other) const
+bool FilePath::operator<(const FilePath &other) const
{
- return QString::compare(*this, other, HostOsInfo::fileNameCaseSensitivity()) < 0;
+ if (!m_url.isEmpty())
+ return m_url < other.m_url;
+ return QString::compare(m_data, other.m_data, HostOsInfo::fileNameCaseSensitivity()) < 0;
}
-bool FileName::operator<=(const FileName &other) const
+bool FilePath::operator<=(const FilePath &other) const
{
- return QString::compare(*this, other, HostOsInfo::fileNameCaseSensitivity()) <= 0;
+ return !(other < *this);
}
-bool FileName::operator>(const FileName &other) const
+bool FilePath::operator>(const FilePath &other) const
{
return other < *this;
}
-bool FileName::operator>=(const FileName &other) const
+bool FilePath::operator>=(const FilePath &other) const
{
- return other <= *this;
+ return !(*this < other);
}
-FileName FileName::operator+(const QString &s) const
+FilePath FilePath::operator+(const QString &s) const
{
- FileName result(*this);
- result.appendString(s);
- return result;
+ return FilePath::fromString(m_data + s);
}
-/// \returns whether FileName is a child of \a s
-bool FileName::isChildOf(const FileName &s) const
+/// \returns whether FilePath is a child of \a s
+bool FilePath::isChildOf(const FilePath &s) const
{
if (s.isEmpty())
return false;
- if (!QString::startsWith(s, HostOsInfo::fileNameCaseSensitivity()))
+ if (!m_data.startsWith(s.m_data, HostOsInfo::fileNameCaseSensitivity()))
return false;
- if (size() <= s.size())
+ if (m_data.size() <= s.m_data.size())
return false;
// s is root, '/' was already tested in startsWith
- if (s.QString::endsWith(QLatin1Char('/')))
+ if (s.m_data.endsWith(QLatin1Char('/')))
return true;
// s is a directory, next character should be '/' (/tmpdir is NOT a child of /tmp)
- return at(s.size()) == QLatin1Char('/');
+ return m_data.at(s.m_data.size()) == QLatin1Char('/');
}
/// \overload
-bool FileName::isChildOf(const QDir &dir) const
+bool FilePath::isChildOf(const QDir &dir) const
{
- return isChildOf(FileName::fromString(dir.absolutePath()));
+ return isChildOf(FilePath::fromString(dir.absolutePath()));
}
-/// \returns whether FileName endsWith \a s
-bool FileName::endsWith(const QString &s) const
+/// \returns whether FilePath endsWith \a s
+bool FilePath::endsWith(const QString &s) const
{
- return QString::endsWith(s, HostOsInfo::fileNameCaseSensitivity());
+ return m_data.endsWith(s, HostOsInfo::fileNameCaseSensitivity());
}
-/// \returns the relativeChildPath of FileName to parent if FileName is a child of parent
-/// \note returns a empty FileName if FileName is not a child of parent
+bool FilePath::isLocal() const
+{
+ return m_url.isEmpty() || m_url.isLocalFile();
+}
+
+/// \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 "../"
-FileName FileName::relativeChildPath(const FileName &parent) const
+FilePath FilePath::relativeChildPath(const FilePath &parent) const
{
if (!isChildOf(parent))
- return FileName();
- return FileName(QString::mid(parent.size() + 1, -1));
+ return FilePath();
+ return FilePath::fromString(m_data.mid(parent.m_data.size() + 1, -1));
}
-/// Appends \a s, ensuring a / between the parts
-FileName &FileName::appendPath(const QString &s)
+FilePath FilePath::pathAppended(const QString &str) const
{
- if (s.isEmpty())
- return *this;
- if (!isEmpty() && !QString::endsWith(QLatin1Char('/')))
- appendString(QLatin1Char('/'));
- appendString(s);
- return *this;
+ FilePath fn = *this;
+ if (str.isEmpty())
+ return fn;
+ if (!isEmpty() && !m_data.endsWith(QLatin1Char('/')))
+ fn.m_data.append('/');
+ fn.m_data.append(str);
+ return fn;
}
-FileName &FileName::appendString(const QString &str)
+FilePath FilePath::stringAppended(const QString &str) const
{
- QString::append(str);
- return *this;
+ FilePath fn = *this;
+ fn.m_data.append(str);
+ return fn;
}
-FileName &FileName::appendString(QChar str)
+uint FilePath::hash(uint seed) const
{
- QString::append(str);
- return *this;
+ if (Utils::HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
+ return qHash(m_data.toUpper(), seed);
+ return qHash(m_data, seed);
}
-QTextStream &operator<<(QTextStream &s, const FileName &fn)
+QTextStream &operator<<(QTextStream &s, const FilePath &fn)
{
return s << fn.toString();
}
@@ -813,14 +941,4 @@ void withNtfsPermissions(const std::function<void()> &task)
qt_ntfs_permission_lookup--;
}
#endif
-
} // namespace Utils
-
-QT_BEGIN_NAMESPACE
-uint qHash(const Utils::FileName &a)
-{
- if (Utils::HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
- return qHash(a.toString().toUpper());
- return qHash(a.toString());
-}
-QT_END_NAMESPACE
diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h
index aa6310c760..ec018b9c3b 100644
--- a/src/libs/utils/fileutils.h
+++ b/src/libs/utils/fileutils.h
@@ -33,11 +33,12 @@
#include <QXmlStreamWriter> // Mac.
#include <QMetaType>
#include <QStringList>
+#include <QUrl>
#include <functional>
#include <memory>
-namespace Utils {class FileName; }
+namespace Utils { class FilePath; }
QT_BEGIN_NAMESPACE
class QDataStream;
@@ -49,7 +50,7 @@ class QTemporaryFile;
class QTextStream;
class QWidget;
-QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug dbg, const Utils::FileName &c);
+QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug dbg, const Utils::FilePath &c);
// for withNtfsPermissions
#ifdef Q_OS_WIN
@@ -60,76 +61,114 @@ QT_END_NAMESPACE
namespace Utils {
-class QTCREATOR_UTILS_EXPORT FileName : private QString
+class QTCREATOR_UTILS_EXPORT FilePath
{
public:
- FileName();
- explicit FileName(const QFileInfo &info);
- QFileInfo toFileInfo() const;
- static FileName fromString(const QString &filename);
- static FileName fromString(const QString &filename, const QString &defaultExtension);
- static FileName fromLatin1(const QByteArray &filename);
- static FileName fromUserInput(const QString &filename);
- static FileName fromUtf8(const char *filename, int filenameSize = -1);
+ FilePath();
+
+ static FilePath fromString(const QString &filepath);
+ static FilePath fromFileInfo(const QFileInfo &info);
+ static FilePath fromStringWithExtension(const QString &filepath, const QString &defaultExtension);
+ static FilePath fromUserInput(const QString &filepath);
+ static FilePath fromUtf8(const char *filepath, int filepathSize = -1);
+ static FilePath fromVariant(const QVariant &variant);
+
const QString &toString() const;
+ QFileInfo toFileInfo() const;
+ QVariant toVariant() const;
+
QString toUserOutput() const;
+ QString shortNativePath() const;
+
QString fileName(int pathComponents = 0) const;
bool exists() const;
- FileName parentDir() const;
+ FilePath parentDir() const;
- bool operator==(const FileName &other) const;
- bool operator!=(const FileName &other) const;
- bool operator<(const FileName &other) const;
- bool operator<=(const FileName &other) const;
- bool operator>(const FileName &other) const;
- bool operator>=(const FileName &other) const;
- FileName operator+(const QString &s) const;
+ bool operator==(const FilePath &other) const;
+ bool operator!=(const FilePath &other) const;
+ bool operator<(const FilePath &other) const;
+ bool operator<=(const FilePath &other) const;
+ bool operator>(const FilePath &other) const;
+ bool operator>=(const FilePath &other) const;
+ FilePath operator+(const QString &s) const;
- bool isChildOf(const FileName &s) const;
+ bool isChildOf(const FilePath &s) const;
bool isChildOf(const QDir &dir) const;
bool endsWith(const QString &s) const;
+ bool isLocal() const;
+
+ bool isNewerThan(const QDateTime &timeStamp) const;
+
+ FilePath relativeChildPath(const FilePath &parent) const;
+ FilePath pathAppended(const QString &str) const;
+ FilePath stringAppended(const QString &str) const;
+
+ FilePath canonicalPath() const;
+
+ void clear() { m_data.clear(); }
+ bool isEmpty() const { return m_data.isEmpty(); }
+
+ uint hash(uint seed) const;
+
+ // NOTE: FileName operations on FilePath created from URL currenly
+ // do not work except for .toVariant() and .toUrl().
+ static FilePath fromUrl(const QUrl &url);
+ QUrl toUrl() const;
- FileName relativeChildPath(const FileName &parent) const;
- FileName &appendPath(const QString &s);
- FileName &appendString(const QString &str);
- FileName &appendString(QChar str);
-
- using QString::chop;
- using QString::clear;
- using QString::count;
- using QString::isEmpty;
- using QString::isNull;
- using QString::length;
- using QString::size;
private:
- FileName(const QString &string);
+ QString m_data;
+ QUrl m_url;
};
-QTCREATOR_UTILS_EXPORT QTextStream &operator<<(QTextStream &s, const FileName &fn);
+QTCREATOR_UTILS_EXPORT QTextStream &operator<<(QTextStream &s, const FilePath &fn);
+
+using FilePathList = QList<FilePath>;
+
+using FileName = FilePath;
+using FileNameList = FilePathList;
-using FileNameList = QList<FileName>;
+class QTCREATOR_UTILS_EXPORT CommandLine
+{
+public:
+ CommandLine() {}
+
+ CommandLine(const FilePath &executable, const QString &arguments)
+ : m_executable(executable), m_arguments(arguments)
+ {}
+
+ void addArg(const QString &arg, OsType osType = HostOsInfo::hostOs());
+ void addArgs(const QStringList &inArgs, OsType osType = HostOsInfo::hostOs());
+ void addArgs(const QString &inArgs);
+
+ QString toUserOutput() const;
+
+ FilePath executable() const { return m_executable; }
+ QString arguments() const { return m_arguments; }
+
+private:
+ FilePath m_executable;
+ QString m_arguments;
+};
class QTCREATOR_UTILS_EXPORT FileUtils {
public:
- static bool removeRecursively(const FileName &filePath, QString *error = nullptr);
+ static bool removeRecursively(const FilePath &filePath, QString *error = nullptr);
static bool copyRecursively(
- const FileName &srcFilePath, const FileName &tgtFilePath, QString *error = nullptr,
+ const FilePath &srcFilePath, const FilePath &tgtFilePath, QString *error = nullptr,
const std::function<bool (QFileInfo, QFileInfo, QString *)> &copyHelper = nullptr);
- static bool isFileNewerThan(const FileName &filePath, const QDateTime &timeStamp);
- static FileName resolveSymlinks(const FileName &path);
- static FileName canonicalPath(const FileName &path);
- static QString shortNativePath(const FileName &path);
+ static FilePath resolveSymlinks(const FilePath &path);
static QString fileSystemFriendlyName(const QString &name);
static int indexOfQmakeUnfriendly(const QString &name, int startpos = 0);
static QString qmakeFriendlyName(const QString &name);
- static bool makeWritable(const FileName &path);
+ static bool makeWritable(const FilePath &path);
static QString normalizePathName(const QString &name);
static bool isRelativePath(const QString &fileName);
static bool isAbsolutePath(const QString &fileName) { return !isRelativePath(fileName); }
static QString resolvePath(const QString &baseDir, const QString &fileName);
- static FileName commonPath(const FileName &oldCommonPath, const FileName &fileName);
+ static FilePath commonPath(const FilePath &oldCommonPath, const FilePath &fileName);
+ static QByteArray fileId(const FilePath &fileName);
};
// for actually finding out if e.g. directories are writable on Windows
@@ -240,16 +279,14 @@ private:
bool m_autoRemove = true;
};
-} // namespace Utils
+inline uint qHash(const Utils::FilePath &a, uint seed = 0) { return a.hash(seed); }
-QT_BEGIN_NAMESPACE
-QTCREATOR_UTILS_EXPORT uint qHash(const Utils::FileName &a);
-QT_END_NAMESPACE
+} // namespace Utils
namespace std {
-template<> struct hash<Utils::FileName>
+template<> struct hash<Utils::FilePath>
{
- using argument_type = Utils::FileName;
+ using argument_type = Utils::FilePath;
using result_type = size_t;
result_type operator()(const argument_type &fn) const
{
@@ -260,4 +297,4 @@ template<> struct hash<Utils::FileName>
};
} // namespace std
-Q_DECLARE_METATYPE(Utils::FileName)
+Q_DECLARE_METATYPE(Utils::FilePath)
diff --git a/src/libs/sqlite/sqlitetable.cpp b/src/libs/utils/genericconstants.h
index 99b0e95938..a380fc15ba 100644
--- a/src/libs/sqlite/sqlitetable.cpp
+++ b/src/libs/utils/genericconstants.h
@@ -23,10 +23,15 @@
**
****************************************************************************/
-#include "sqlitetable.h"
+#pragma once
-namespace Sqlite {
+namespace Utils {
+namespace Constants {
+const char BEAUTIFIER_SETTINGS_GROUP[] = "Beautifier";
+const char BEAUTIFIER_GENERAL_GROUP[] = "General";
+const char BEAUTIFIER_AUTO_FORMAT_ON_SAVE[] = "autoFormatOnSave";
-} // namespace Sqlite
+} // namespace Constants
+} // namespace Utils
diff --git a/src/libs/utils/highlightingitemdelegate.cpp b/src/libs/utils/highlightingitemdelegate.cpp
index e253689843..4874200e86 100644
--- a/src/libs/utils/highlightingitemdelegate.cpp
+++ b/src/libs/utils/highlightingitemdelegate.cpp
@@ -114,7 +114,8 @@ int HighlightingItemDelegate::drawLineNumber(QPainter *painter, const QStyleOpti
const bool isSelected = option.state & QStyle::State_Selected;
const QString lineText = QString::number(lineNumber);
const int minimumLineNumberDigits = qMax(kMinimumLineNumberDigits, lineText.count());
- const int fontWidth = painter->fontMetrics().width(QString(minimumLineNumberDigits, '0'));
+ const int fontWidth =
+ painter->fontMetrics().horizontalAdvance(QString(minimumLineNumberDigits, '0'));
const int lineNumberAreaWidth = lineNumberAreaHorizontalPadding + fontWidth
+ lineNumberAreaHorizontalPadding;
QRect lineNumberAreaRect(rect);
diff --git a/src/libs/ssh/images/dir.png b/src/libs/utils/images/dir.png
index 57cec6bcd3..57cec6bcd3 100644
--- a/src/libs/ssh/images/dir.png
+++ b/src/libs/utils/images/dir.png
Binary files differ
diff --git a/src/libs/utils/images/pinned.png b/src/libs/utils/images/pinned.png
new file mode 100644
index 0000000000..dc96231ca4
--- /dev/null
+++ b/src/libs/utils/images/pinned.png
Binary files differ
diff --git a/src/libs/utils/images/pinned@2x.png b/src/libs/utils/images/pinned@2x.png
new file mode 100644
index 0000000000..d7c59e83ce
--- /dev/null
+++ b/src/libs/utils/images/pinned@2x.png
Binary files differ
diff --git a/src/libs/utils/images/settings.png b/src/libs/utils/images/settings.png
new file mode 100644
index 0000000000..2621923499
--- /dev/null
+++ b/src/libs/utils/images/settings.png
Binary files differ
diff --git a/src/libs/utils/images/settings@2x.png b/src/libs/utils/images/settings@2x.png
new file mode 100644
index 0000000000..456f0cc56b
--- /dev/null
+++ b/src/libs/utils/images/settings@2x.png
Binary files differ
diff --git a/src/libs/utils/images/sort_alphabetically.png b/src/libs/utils/images/sort_alphabetically.png
new file mode 100644
index 0000000000..c15eb56d50
--- /dev/null
+++ b/src/libs/utils/images/sort_alphabetically.png
Binary files differ
diff --git a/src/libs/utils/images/sort_alphabetically@2x.png b/src/libs/utils/images/sort_alphabetically@2x.png
new file mode 100644
index 0000000000..1a2e5d9520
--- /dev/null
+++ b/src/libs/utils/images/sort_alphabetically@2x.png
Binary files differ
diff --git a/src/libs/utils/images/toggleprogressdetails.png b/src/libs/utils/images/toggleprogressdetails.png
new file mode 100644
index 0000000000..b2353cd9d0
--- /dev/null
+++ b/src/libs/utils/images/toggleprogressdetails.png
Binary files differ
diff --git a/src/libs/utils/images/toggleprogressdetails@2x.png b/src/libs/utils/images/toggleprogressdetails@2x.png
new file mode 100644
index 0000000000..28a212491e
--- /dev/null
+++ b/src/libs/utils/images/toggleprogressdetails@2x.png
Binary files differ
diff --git a/src/libs/ssh/images/unknownfile.png b/src/libs/utils/images/unknownfile.png
index 88f77592d1..88f77592d1 100644
--- a/src/libs/ssh/images/unknownfile.png
+++ b/src/libs/utils/images/unknownfile.png
Binary files differ
diff --git a/src/libs/utils/listmodel.h b/src/libs/utils/listmodel.h
new file mode 100644
index 0000000000..5f4de811e6
--- /dev/null
+++ b/src/libs/utils/listmodel.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 "utils_global.h"
+#include "treemodel.h"
+
+namespace Utils {
+
+template <class ChildType>
+class BaseListModel : public TreeModel<TypedTreeItem<ChildType>, ChildType>
+{
+public:
+ using BaseModel = TreeModel<TypedTreeItem<ChildType>, ChildType>;
+ using BaseModel::rootItem;
+
+ explicit BaseListModel(QObject *parent = nullptr) : BaseModel(parent) {}
+
+ int itemCount() const { return rootItem()->childCount(); }
+ ChildType *itemAt(int row) const { return rootItem()->childAt(row); }
+
+ void appendItem(ChildType *item) { rootItem()->appendChild(item); }
+
+ template <class Predicate>
+ void forItems(const Predicate &pred) const
+ {
+ rootItem()->forFirstLevelChildren(pred);
+ }
+
+ template <class Predicate>
+ ChildType *findItem(const Predicate &pred) const
+ {
+ return rootItem()->findFirstLevelChild(pred);
+ }
+
+ void sortItems(const std::function<bool(const ChildType *, const ChildType *)> &lessThan)
+ {
+ return rootItem()->sortChildren([lessThan](const TreeItem *a, const TreeItem *b) {
+ return lessThan(static_cast<const ChildType *>(a), static_cast<const ChildType *>(b));
+ });
+ }
+
+ int indexOf(const ChildType *item) const { return rootItem()->indexOf(item); }
+
+ 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(); }
+
+};
+
+template <class ItemData>
+class ListItem : public TreeItem
+{
+public:
+ ItemData itemData;
+};
+
+template <class ItemData>
+class ListModel : public BaseListModel<ListItem<ItemData>>
+{
+public:
+ using ChildType = ListItem<ItemData>;
+ using BaseModel = BaseListModel<ChildType>;
+
+ explicit ListModel(QObject *parent = nullptr) : BaseModel(parent) {}
+
+ const ItemData &dataAt(int row) const
+ {
+ static const ItemData dummyData = {};
+ auto item = BaseModel::itemAt(row);
+ return item ? item->itemData : dummyData;
+ }
+
+ ChildType *findItemByData(const std::function<bool(const ItemData &)> &pred) const
+ {
+ return BaseModel::rootItem()->findFirstLevelChild([pred](ChildType *child) {
+ return pred(child->itemData);
+ });
+ }
+
+ void destroyItems(const std::function<bool(const ItemData &)> &pred)
+ {
+ QList<ChildType *> toDestroy;
+ BaseModel::rootItem()->forFirstLevelChildren([pred, &toDestroy](ChildType *item) {
+ if (pred(item->itemData))
+ toDestroy.append(item);
+ });
+ for (ChildType *item : toDestroy)
+ this->destroyItem(item);
+ }
+
+ ItemData *findData(const std::function<bool(const ItemData &)> &pred) const
+ {
+ ChildType *item = findItemByData(pred);
+ return item ? &item->itemData : nullptr;
+ }
+
+ void forItems(const std::function<void(ItemData &)> &func) const
+ {
+ BaseModel::rootItem()->forFirstLevelChildren([func](ChildType *child) {
+ func(child->itemData);
+ });
+ }
+
+ ChildType *appendItem(const ItemData &data)
+ {
+ auto item = new ChildType;
+ item->itemData = data;
+ BaseModel::rootItem()->appendChild(item);
+ return item;
+ }
+
+ QVariant data(const QModelIndex &idx, int role) const override
+ {
+ TreeItem *item = BaseModel::itemForIndex(idx);
+ if (item && item->parent() == BaseModel::rootItem())
+ return itemData(static_cast<ChildType *>(item)->itemData, idx.column(), role);
+ return {};
+ }
+
+ Qt::ItemFlags flags(const QModelIndex &idx) const override
+ {
+ TreeItem *item = BaseModel::itemForIndex(idx);
+ if (item && item->parent() == BaseModel::rootItem())
+ return itemFlags(static_cast<ChildType *>(item)->itemData, idx.column());
+ return {};
+ }
+
+ virtual QVariant itemData(const ItemData &idata, int column, int role) const
+ {
+ if (m_dataAccessor)
+ return m_dataAccessor(idata, column, role);
+ return {};
+ }
+
+ virtual Qt::ItemFlags itemFlags(const ItemData &idata, int column) const
+ {
+ if (m_flagsAccessor)
+ return m_flagsAccessor(idata, column);
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ }
+
+ void setDataAccessor(const std::function<QVariant(const ItemData &, int, int)> &accessor)
+ {
+ m_dataAccessor = accessor;
+ }
+
+ void setFlagsAccessor(const std::function<Qt::ItemFlags(const ItemData &, int)> &accessor)
+ {
+ m_flagsAccessor = accessor;
+ }
+
+private:
+ std::function<QVariant(const ItemData &, int, int)> m_dataAccessor;
+ std::function<Qt::ItemFlags(const ItemData &, int)> m_flagsAccessor;
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/macroexpander.cpp b/src/libs/utils/macroexpander.cpp
index eb3f05e175..a41fbde31d 100644
--- a/src/libs/utils/macroexpander.cpp
+++ b/src/libs/utils/macroexpander.cpp
@@ -290,11 +290,39 @@ QString MacroExpander::expand(const QString &stringWithVariables) const
return res;
}
+FilePath MacroExpander::expand(const FilePath &fileNameWithVariables) const
+{
+ return FilePath::fromString(expand(fileNameWithVariables.toString()));
+}
+
QByteArray MacroExpander::expand(const QByteArray &stringWithVariables) const
{
return expand(QString::fromLatin1(stringWithVariables)).toLatin1();
}
+QVariant MacroExpander::expandVariant(const QVariant &v) const
+{
+ const auto type = QMetaType::Type(v.type());
+ if (type == QMetaType::QString) {
+ return expand(v.toString());
+ } else if (type == QMetaType::QStringList) {
+ return Utils::transform(v.toStringList(),
+ [this](const QString &s) -> QVariant { return expand(s); });
+ } else if (type == QMetaType::QVariantList) {
+ return Utils::transform(v.toList(), [this](const QVariant &v) { return expandVariant(v); });
+ } else if (type == QMetaType::QVariantMap) {
+ const auto map = v.toMap();
+ QVariantMap result;
+ QMapIterator<QString, QVariant> it(map);
+ while (it.hasNext()) {
+ it.next();
+ result.insert(it.key(), expandVariant(it.value()));
+ }
+ return result;
+ }
+ return v;
+}
+
QString MacroExpander::expandProcessArgs(const QString &argsWithVariables) const
{
return QtcProcess::expandMacros(argsWithVariables, d);
@@ -394,7 +422,7 @@ void MacroExpander::registerFileVariables(const QByteArray &prefix,
registerVariable(prefix + kFileNamePostfix,
tr("%1: File name without path.").arg(heading),
- [base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : FileName::fromString(tmp).fileName(); },
+ [base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : FilePath::fromString(tmp).fileName(); },
visibleInChooser);
registerVariable(prefix + kFileBaseNamePostfix,
diff --git a/src/libs/utils/macroexpander.h b/src/libs/utils/macroexpander.h
index f17ae86b8c..70448069c5 100644
--- a/src/libs/utils/macroexpander.h
+++ b/src/libs/utils/macroexpander.h
@@ -37,6 +37,7 @@ namespace Utils {
namespace Internal { class MacroExpanderPrivate; }
+class FilePath;
class MacroExpander;
using MacroExpanderProvider = std::function<MacroExpander *()>;
using MacroExpanderProviders = QVector<MacroExpanderProvider>;
@@ -55,7 +56,9 @@ public:
QString value(const QByteArray &variable, bool *found = nullptr) const;
QString expand(const QString &stringWithVariables) const;
+ FilePath expand(const FilePath &fileNameWithVariables) const;
QByteArray expand(const QByteArray &stringWithVariables) const;
+ QVariant expandVariant(const QVariant &v) const;
QString expandProcessArgs(const QString &argsWithVariables) const;
diff --git a/src/libs/utils/mimetypes/mimeprovider.cpp b/src/libs/utils/mimetypes/mimeprovider.cpp
index d444aa899c..46d3eb71bd 100644
--- a/src/libs/utils/mimetypes/mimeprovider.cpp
+++ b/src/libs/utils/mimetypes/mimeprovider.cpp
@@ -803,11 +803,7 @@ void MimeXMLProvider::ensureLoaded()
// if (!fdoXmlFound) {
// // We could instead install the file as part of installing Qt?
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
const char freedesktopOrgXml[] = ":/qt-project.org/qmime/packages/freedesktop.org.xml";
-#else
- const char freedesktopOrgXml[] = ":/qt-project.org/qmime/freedesktop.org.xml";
-#endif
allFiles.prepend(QLatin1String(freedesktopOrgXml));
// }
diff --git a/src/libs/utils/newclasswidget.cpp b/src/libs/utils/newclasswidget.cpp
index 8700b8204c..9205d435dc 100644
--- a/src/libs/utils/newclasswidget.cpp
+++ b/src/libs/utils/newclasswidget.cpp
@@ -88,7 +88,7 @@ NewClassWidget::NewClassWidget(QWidget *parent) :
connect(d->m_ui.classLineEdit, &QLineEdit::textEdited,
this, &NewClassWidget::classNameEdited);
connect(d->m_ui.baseClassComboBox,
- static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &NewClassWidget::suggestClassNameFromBase);
connect(d->m_ui.baseClassComboBox, &QComboBox::editTextChanged,
this, &NewClassWidget::slotValidChanged);
diff --git a/src/libs/utils/outputformatter.cpp b/src/libs/utils/outputformatter.cpp
index ec85a748a6..7926422da6 100644
--- a/src/libs/utils/outputformatter.cpp
+++ b/src/libs/utils/outputformatter.cpp
@@ -78,7 +78,8 @@ void OutputFormatter::appendMessage(const QString &text, OutputFormat format)
void OutputFormatter::appendMessage(const QString &text, const QTextCharFormat &format)
{
- foreach (const FormattedText &output, parseAnsi(text, format))
+ const QList<FormattedText> formattedTextList = parseAnsi(text, format);
+ for (const FormattedText &output : formattedTextList)
append(output.text, output.format);
}
diff --git a/src/libs/utils/outputformatter.h b/src/libs/utils/outputformatter.h
index c516ca14e2..1db42453d5 100644
--- a/src/libs/utils/outputformatter.h
+++ b/src/libs/utils/outputformatter.h
@@ -62,6 +62,9 @@ public:
virtual void clear() {}
void setBoldFontEnabled(bool enabled);
+signals:
+ void contentChanged();
+
protected:
void initFormats();
virtual void clearLastLine();
diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
index e29b0c7663..f08391d6a6 100644
--- a/src/libs/utils/pathchooser.cpp
+++ b/src/libs/utils/pathchooser.cpp
@@ -193,14 +193,14 @@ QString PathChooserPrivate::expandedPath(const QString &input) const
if (m_macroExpander)
expandedInput = m_macroExpander->expand(expandedInput);
- const QString path = FileName::fromUserInput(expandedInput).toString();
+ const QString path = FilePath::fromUserInput(expandedInput).toString();
if (path.isEmpty())
return path;
switch (m_acceptingKind) {
case PathChooser::Command:
case PathChooser::ExistingCommand: {
- const FileName expanded = m_environment.searchInPath(path, {FileName::fromString(m_baseDirectory)});
+ const FilePath expanded = m_environment.searchInPath(path, {FilePath::fromString(m_baseDirectory)});
return expanded.isEmpty() ? path : expanded.toString();
}
case PathChooser::Any:
@@ -293,12 +293,12 @@ void PathChooser::setBaseDirectory(const QString &directory)
triggerChanged();
}
-FileName PathChooser::baseFileName() const
+FilePath PathChooser::baseFileName() const
{
- return FileName::fromString(d->m_baseDirectory);
+ return FilePath::fromString(d->m_baseDirectory);
}
-void PathChooser::setBaseFileName(const FileName &base)
+void PathChooser::setBaseFileName(const FilePath &base)
{
setBaseDirectory(base.toString());
}
@@ -323,14 +323,14 @@ QString PathChooser::path() const
return fileName().toString();
}
-FileName PathChooser::rawFileName() const
+FilePath PathChooser::rawFileName() const
{
- return FileName::fromString(QDir::fromNativeSeparators(d->m_lineEdit->text()));
+ return FilePath::fromString(QDir::fromNativeSeparators(d->m_lineEdit->text()));
}
-FileName PathChooser::fileName() const
+FilePath PathChooser::fileName() const
{
- return FileName::fromUserInput(d->expandedPath(rawFileName().toString()));
+ return FilePath::fromUserInput(d->expandedPath(rawFileName().toString()));
}
// FIXME: try to remove again
@@ -352,7 +352,7 @@ void PathChooser::setPath(const QString &path)
d->m_lineEdit->setTextKeepingActiveCursor(QDir::toNativeSeparators(path));
}
-void PathChooser::setFileName(const FileName &fn)
+void PathChooser::setFileName(const FilePath &fn)
{
d->m_lineEdit->setTextKeepingActiveCursor(fn.toUserOutput());
}
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
index 73939e1bf4..09d98e71c8 100644
--- a/src/libs/utils/pathchooser.h
+++ b/src/libs/utils/pathchooser.h
@@ -55,8 +55,8 @@ class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget
Q_PROPERTY(QStringList commandVersionArguments READ commandVersionArguments WRITE setCommandVersionArguments)
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE true)
// Designer does not know this type, so force designable to false:
- Q_PROPERTY(Utils::FileName fileName READ fileName WRITE setFileName DESIGNABLE false)
- Q_PROPERTY(Utils::FileName baseFileName READ baseFileName WRITE setBaseFileName DESIGNABLE false)
+ Q_PROPERTY(Utils::FilePath fileName READ fileName WRITE setFileName DESIGNABLE false)
+ Q_PROPERTY(Utils::FilePath baseFileName READ baseFileName WRITE setBaseFileName DESIGNABLE false)
Q_PROPERTY(QColor errorColor READ errorColor WRITE setErrorColor DESIGNABLE true)
Q_PROPERTY(QColor okColor READ okColor WRITE setOkColor DESIGNABLE true)
@@ -93,8 +93,8 @@ public:
QString path() const;
QString rawPath() const; // The raw unexpanded input.
- FileName rawFileName() const; // The raw unexpanded input.
- FileName fileName() const;
+ FilePath rawFileName() const; // The raw unexpanded input.
+ FilePath fileName() const;
static QString expandedDirectory(const QString &input, const Environment &env,
const QString &baseDir);
@@ -102,8 +102,8 @@ public:
QString baseDirectory() const;
void setBaseDirectory(const QString &directory);
- FileName baseFileName() const;
- void setBaseFileName(const FileName &base);
+ FilePath baseFileName() const;
+ void setBaseFileName(const FilePath &base);
void setEnvironment(const Environment &env);
@@ -172,7 +172,7 @@ signals:
public slots:
void setPath(const QString &);
- void setFileName(const FileName &);
+ void setFileName(const FilePath &);
void setErrorColor(const QColor &errorColor);
void setOkColor(const QColor &okColor);
diff --git a/src/libs/utils/persistentsettings.cpp b/src/libs/utils/persistentsettings.cpp
index db0f8d0db5..92d32109ea 100644
--- a/src/libs/utils/persistentsettings.cpp
+++ b/src/libs/utils/persistentsettings.cpp
@@ -341,7 +341,7 @@ QVariantMap PersistentSettingsReader::restoreValues() const
return m_valueMap;
}
-bool PersistentSettingsReader::load(const FileName &fileName)
+bool PersistentSettingsReader::load(const FilePath &fileName)
{
m_valueMap.clear();
@@ -409,7 +409,7 @@ static void writeVariantValue(QXmlStreamWriter &w, const Context &ctx,
}
}
-PersistentSettingsWriter::PersistentSettingsWriter(const FileName &fileName, const QString &docType) :
+PersistentSettingsWriter::PersistentSettingsWriter(const FilePath &fileName, const QString &docType) :
m_fileName(fileName), m_docType(docType)
{ }
@@ -438,7 +438,7 @@ bool PersistentSettingsWriter::save(const QVariantMap &data, QWidget *parent) co
}
#endif // QT_GUI_LIB
-FileName PersistentSettingsWriter::fileName() const
+FilePath PersistentSettingsWriter::fileName() const
{ return m_fileName; }
//** * @brief Set contents of file (e.g. from data read from it). */
diff --git a/src/libs/utils/persistentsettings.h b/src/libs/utils/persistentsettings.h
index a7255dcb8a..92dbf0d8c9 100644
--- a/src/libs/utils/persistentsettings.h
+++ b/src/libs/utils/persistentsettings.h
@@ -42,7 +42,7 @@ public:
PersistentSettingsReader();
QVariant restoreValue(const QString &variable, const QVariant &defaultValue = QVariant()) const;
QVariantMap restoreValues() const;
- bool load(const FileName &fileName);
+ bool load(const FilePath &fileName);
private:
QMap<QString, QVariant> m_valueMap;
@@ -51,7 +51,7 @@ private:
class QTCREATOR_UTILS_EXPORT PersistentSettingsWriter
{
public:
- PersistentSettingsWriter(const FileName &fileName, const QString &docType);
+ PersistentSettingsWriter(const FilePath &fileName, const QString &docType);
~PersistentSettingsWriter();
bool save(const QVariantMap &data, QString *errorString) const;
@@ -59,14 +59,14 @@ public:
bool save(const QVariantMap &data, QWidget *parent) const;
#endif
- FileName fileName() const;
+ FilePath fileName() const;
void setContents(const QVariantMap &data);
private:
bool write(const QVariantMap &data, QString *errorString) const;
- const FileName m_fileName;
+ const FilePath m_fileName;
const QString m_docType;
mutable QMap<QString, QVariant> m_savedData;
};
diff --git a/src/libs/utils/projectintropage.cpp b/src/libs/utils/projectintropage.cpp
index a449fe1285..56127ac479 100644
--- a/src/libs/utils/projectintropage.cpp
+++ b/src/libs/utils/projectintropage.cpp
@@ -101,7 +101,7 @@ ProjectIntroPage::ProjectIntroPage(QWidget *parent) :
connect(d->m_ui.nameLineEdit, &FancyLineEdit::validReturnPressed,
this, &ProjectIntroPage::slotActivated);
connect(d->m_ui.projectComboBox,
- static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &ProjectIntroPage::slotChanged);
setProperty(SHORT_TITLE_PROPERTY, tr("Location"));
diff --git a/src/libs/qmljs/qmljsqrcparser.cpp b/src/libs/utils/qrcparser.cpp
index 0a68ebe2fb..21904d3716 100644
--- a/src/libs/qmljs/qmljsqrcparser.cpp
+++ b/src/libs/utils/qrcparser.cpp
@@ -23,22 +23,26 @@
**
****************************************************************************/
-#include "qmljsqrcparser.h"
-#include "qmljsconstants.h"
-#include <QFile>
+#include "qrcparser.h"
+
+#include <utils/qtcassert.h>
+
+#include <QCoreApplication>
#include <QDir>
-#include <QFileInfo>
-#include <QStringList>
#include <QDomDocument>
+#include <QFile>
+#include <QFileInfo>
#include <QLocale>
+#include <QLoggingCategory>
+#include <QMultiHash>
#include <QMutex>
-#include <QSet>
#include <QMutexLocker>
-#include <QMultiHash>
-#include <QCoreApplication>
-#include <utils/qtcassert.h>
+#include <QSet>
+#include <QStringList>
+
+Q_LOGGING_CATEGORY(qrcParserLog, "qtc.qrcParser", QtWarningMsg)
-namespace QmlJS {
+namespace Utils {
namespace Internal {
/*!
@@ -81,7 +85,7 @@ public:
QStringList languages() const;
private:
static QString fixPrefix(const QString &prefix);
- QStringList allUiLanguages(const QLocale *locale) const;
+ const QStringList allUiLanguages(const QLocale *locale) const;
SMap m_resources;
SMap m_files;
@@ -339,8 +343,7 @@ bool QrcParserPrivate::parseFile(const QString &path, const QString &contents)
QString QrcParserPrivate::firstFileAtPath(const QString &path, const QLocale &locale) const
{
QTC_CHECK(path.startsWith(QLatin1Char('/')));
- QStringList langs = allUiLanguages(&locale);
- foreach (const QString &language, langs) {
+ for (const QString &language : allUiLanguages(&locale)) {
if (m_languages.contains(language)) {
SMap::const_iterator res = m_resources.find(language + path);
if (res != m_resources.end())
@@ -354,8 +357,7 @@ void QrcParserPrivate::collectFilesAtPath(const QString &path, QStringList *file
const QLocale *locale) const
{
QTC_CHECK(path.startsWith(QLatin1Char('/')));
- QStringList langs = allUiLanguages(locale);
- foreach (const QString &language, langs) {
+ for (const QString &language : allUiLanguages(locale)) {
if (m_languages.contains(language)) {
SMap::const_iterator res = m_resources.find(language + path);
if (res != m_resources.end())
@@ -369,8 +371,7 @@ bool QrcParserPrivate::hasDirAtPath(const QString &path, const QLocale *locale)
{
QTC_CHECK(path.startsWith(QLatin1Char('/')));
QTC_CHECK(path.endsWith(QLatin1Char('/')));
- QStringList langs = allUiLanguages(locale);
- foreach (const QString &language, langs) {
+ for (const QString &language : allUiLanguages(locale)) {
if (m_languages.contains(language)) {
QString key = language + path;
SMap::const_iterator res = m_resources.lowerBound(key);
@@ -387,8 +388,7 @@ void QrcParserPrivate::collectFilesInPath(const QString &path, QMap<QString,QStr
QTC_CHECK(path.startsWith(QLatin1Char('/')));
QTC_CHECK(path.endsWith(QLatin1Char('/')));
SMap::const_iterator end = m_resources.end();
- QStringList langs = allUiLanguages(locale);
- foreach (const QString &language, langs) {
+ for (const QString &language : allUiLanguages(locale)) {
QString key = language + path;
SMap::const_iterator res = m_resources.lowerBound(key);
while (res != end && res.key().startsWith(key)) {
@@ -397,7 +397,7 @@ void QrcParserPrivate::collectFilesInPath(const QString &path, QMap<QString,QStr
if (endDir == -1) {
QString fileName = res.key().right(res.key().size()-key.size());
QStringList &els = (*contents)[fileName];
- foreach (const QString &val, res.value())
+ for (const QString &val : res.value())
if (!els.contains(val))
els << val;
++res;
@@ -420,12 +420,12 @@ void QrcParserPrivate::collectResourceFilesForSourceFile(const QString &sourceFi
{
// TODO: use FileName from fileutils for file paths
- QStringList langs = allUiLanguages(locale);
+ const QStringList langs = allUiLanguages(locale);
SMap::const_iterator file = m_files.find(sourceFile);
if (file == m_files.end())
return;
- foreach (const QString &resource, file.value()) {
- foreach (const QString &language, langs) {
+ for (const QString &resource : file.value()) {
+ for (const QString &language : langs) {
if (resource.startsWith(language) && !results->contains(resource))
results->append(resource);
}
@@ -459,7 +459,7 @@ QString QrcParserPrivate::fixPrefix(const QString &prefix)
return result;
}
-QStringList QrcParserPrivate::allUiLanguages(const QLocale *locale) const
+const QStringList QrcParserPrivate::allUiLanguages(const QLocale *locale) const
{
if (!locale)
return languages();
@@ -496,7 +496,7 @@ QrcParser::Ptr QrcCachePrivate::addPath(const QString &path, const QString &cont
}
QrcParser::Ptr newParser = QrcParser::parseQrcFile(path, contents);
if (!newParser->isValid())
- qCWarning(qmljsLog) << "adding invalid qrc " << path << " to the cache:" << newParser->errorMessages();
+ 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});
diff --git a/src/libs/qmljs/qmljsqrcparser.h b/src/libs/utils/qrcparser.h
index 6973fa6d39..b5a7be761b 100644
--- a/src/libs/qmljs/qmljsqrcparser.h
+++ b/src/libs/utils/qrcparser.h
@@ -24,7 +24,7 @@
****************************************************************************/
#pragma once
-#include "qmljs_global.h"
+#include "utils_global.h"
#include <QMap>
#include <QSharedPointer>
@@ -33,14 +33,14 @@
QT_FORWARD_DECLARE_CLASS(QLocale)
-namespace QmlJS {
+namespace Utils {
namespace Internal {
class QrcParserPrivate;
class QrcCachePrivate;
}
-class QMLJS_EXPORT QrcParser
+class QTCREATOR_UTILS_EXPORT QrcParser
{
public:
typedef QSharedPointer<QrcParser> Ptr;
@@ -69,7 +69,7 @@ private:
Internal::QrcParserPrivate *d;
};
-class QMLJS_EXPORT QrcCache
+class QTCREATOR_UTILS_EXPORT QrcCache
{
public:
QrcCache();
diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp
index dd4fe16f49..992e1817c0 100644
--- a/src/libs/utils/qtcprocess.cpp
+++ b/src/libs/utils/qtcprocess.cpp
@@ -595,12 +595,12 @@ static QString quoteArgWin(const QString &arg)
}
QtcProcess::Arguments QtcProcess::prepareArgs(const QString &cmd, SplitError *err, OsType osType,
- const Environment *env, const QString *pwd)
+ const Environment *env, const QString *pwd, bool abortOnMeta)
{
if (osType == OsTypeWindows)
return prepareArgsWin(cmd, err, env, pwd);
else
- return Arguments::createUnixArgs(splitArgs(cmd, osType, true, err, env, pwd));
+ return Arguments::createUnixArgs(splitArgs(cmd, osType, abortOnMeta, err, env, pwd));
}
@@ -694,7 +694,8 @@ void QtcProcess::start()
const OsType osType = HostOsInfo::hostOs();
if (m_haveEnv) {
if (m_environment.size() == 0)
- qWarning("QtcProcess::start: Empty environment set when running '%s'.", qPrintable(m_command));
+ qWarning("QtcProcess::start: Empty environment set when running '%s'.",
+ qPrintable(m_commandLine.executable().toString()));
env = m_environment;
QProcess::setEnvironment(env.toStringList());
@@ -705,7 +706,9 @@ void QtcProcess::start()
const QString &workDir = workingDirectory();
QString command;
QtcProcess::Arguments arguments;
- bool success = prepareCommand(m_command, m_arguments, &command, &arguments, osType, &env, &workDir);
+ bool success = prepareCommand(m_commandLine.executable().toString(),
+ m_commandLine.arguments(),
+ &command, &arguments, osType, &env, &workDir);
if (osType == OsTypeWindows) {
QString args;
if (m_useCtrlCStub) {
diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h
index 44c5786661..5eeacf666e 100644
--- a/src/libs/utils/qtcprocess.h
+++ b/src/libs/utils/qtcprocess.h
@@ -38,10 +38,9 @@ class QTCREATOR_UTILS_EXPORT QtcProcess : public QProcess
public:
QtcProcess(QObject *parent = nullptr);
- void setEnvironment(const Environment &env)
- { m_environment = env; m_haveEnv = true; }
- void setCommand(const QString &command, const QString &arguments)
- { m_command = command; m_arguments = arguments; }
+
+ void setEnvironment(const Environment &env) { m_environment = env; m_haveEnv = true; }
+ void setCommand(const CommandLine &cmdLine) { m_commandLine = cmdLine; }
void setUseCtrlCStub(bool enabled);
void start();
void terminate();
@@ -80,7 +79,8 @@ public:
//! Prepare argument of a shell command for feeding into QProcess
static Arguments prepareArgs(const QString &cmd, SplitError *err,
OsType osType = HostOsInfo::hostOs(),
- const Environment *env = nullptr, const QString *pwd = nullptr);
+ const Environment *env = nullptr, const QString *pwd = nullptr,
+ bool abortOnMeta = true);
//! Prepare a shell command for feeding into QProcess
static bool prepareCommand(const QString &command, const QString &arguments,
QString *outCmd, Arguments *outArgs, OsType osType = HostOsInfo::hostOs(),
@@ -141,8 +141,7 @@ public:
};
private:
- QString m_command;
- QString m_arguments;
+ CommandLine m_commandLine;
Environment m_environment;
bool m_haveEnv = false;
bool m_useCtrlCStub = false;
diff --git a/src/libs/utils/reloadpromptutils.cpp b/src/libs/utils/reloadpromptutils.cpp
index 2270053be0..09a9855784 100644
--- a/src/libs/utils/reloadpromptutils.cpp
+++ b/src/libs/utils/reloadpromptutils.cpp
@@ -33,7 +33,7 @@
namespace Utils {
-QTCREATOR_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const FileName &fileName,
+QTCREATOR_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const FilePath &fileName,
bool modified,
bool enableDiffOption,
QWidget *parent)
@@ -50,7 +50,10 @@ QTCREATOR_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const FileName &fileName,
msg = QCoreApplication::translate("Utils::reloadPrompt",
"The file <i>%1</i> has been changed on disk. Do you want to reload it?");
}
- msg = msg.arg(fileName.fileName());
+ msg = "<p>" + msg.arg(fileName.fileName()) + "</p><p>" +
+ QCoreApplication::translate("Utils::reloadPrompt",
+ "The default behavior can be set in Tools > Options > Environment > System.")
+ + "</p>";
return reloadPrompt(title, msg, fileName.toUserOutput(), enableDiffOption, parent);
}
diff --git a/src/libs/utils/reloadpromptutils.h b/src/libs/utils/reloadpromptutils.h
index 8991d52b59..82aa409cf5 100644
--- a/src/libs/utils/reloadpromptutils.h
+++ b/src/libs/utils/reloadpromptutils.h
@@ -33,7 +33,7 @@ class QWidget;
QT_END_NAMESPACE
namespace Utils {
-class FileName;
+class FilePath;
enum ReloadPromptAnswer {
ReloadCurrent,
@@ -44,7 +44,7 @@ enum ReloadPromptAnswer {
CloseCurrent
};
-QTCREATOR_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const FileName &fileName,
+QTCREATOR_UTILS_EXPORT ReloadPromptAnswer reloadPrompt(const FilePath &fileName,
bool modified,
bool enableDiffOption,
QWidget *parent);
diff --git a/src/libs/utils/runextensions.h b/src/libs/utils/runextensions.h
index 6925504693..eacbd8dc4c 100644
--- a/src/libs/utils/runextensions.h
+++ b/src/libs/utils/runextensions.h
@@ -600,4 +600,59 @@ const QFuture<T> &onResultReady(const QFuture<T> &future, Function f)
return future;
}
-} // Utils
+/*!
+ Adds a handler for when the future is finished.
+ This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
+ or create a QFutureWatcher already for other reasons.
+*/
+template<typename R, typename T>
+const QFuture<T> &onFinished(const QFuture<T> &future,
+ R *receiver,
+ void (R::*member)(const QFuture<T> &))
+{
+ auto watcher = new QFutureWatcher<T>();
+ QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
+ QObject::connect(watcher,
+ &QFutureWatcherBase::finished,
+ receiver,
+ [receiver, member, watcher]() { (receiver->*member)(watcher->future()); });
+ watcher->setFuture(future);
+ return future;
+}
+
+/*!
+ Adds a handler for when the future is finished. The guard object determines the lifetime of
+ the connection.
+ This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
+ or create a QFutureWatcher already for other reasons.
+*/
+template<typename T, typename Function>
+const QFuture<T> &onFinished(const QFuture<T> &future, QObject *guard, Function f)
+{
+ auto watcher = new QFutureWatcher<T>();
+ QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
+ QObject::connect(watcher, &QFutureWatcherBase::finished, guard, [f, watcher]() {
+ f(watcher->future());
+ });
+ watcher->setFuture(future);
+ return future;
+}
+
+/*!
+ Adds a handler for when the future is finished.
+ This creates a new QFutureWatcher. Do not use if you intend to react on multiple conditions
+ or create a QFutureWatcher already for other reasons.
+*/
+template<typename T, typename Function>
+const QFuture<T> &onFinished(const QFuture<T> &future, Function f)
+{
+ auto watcher = new QFutureWatcher<T>();
+ QObject::connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
+ QObject::connect(watcher, &QFutureWatcherBase::finished, [f, watcher]() {
+ f(watcher->future());
+ });
+ watcher->setFuture(future);
+ return future;
+}
+
+} // namespace Utils
diff --git a/src/libs/utils/savedaction.cpp b/src/libs/utils/savedaction.cpp
index 0000e54d31..87a785f6db 100644
--- a/src/libs/utils/savedaction.cpp
+++ b/src/libs/utils/savedaction.cpp
@@ -235,7 +235,7 @@ void SavedAction::connectWidget(QWidget *widget, ApplyMode applyMode)
} else if (auto spinBox = qobject_cast<QSpinBox *>(widget)) {
spinBox->setValue(m_value.toInt());
if (applyMode == ImmediateApply) {
- connect(spinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged),
this, [this, spinBox]() { setValue(spinBox->value()); });
}
} else if (auto lineEdit = qobject_cast<QLineEdit *>(widget)) {
diff --git a/src/libs/utils/savefile.cpp b/src/libs/utils/savefile.cpp
index cac25546db..b25432a280 100644
--- a/src/libs/utils/savefile.cpp
+++ b/src/libs/utils/savefile.cpp
@@ -119,7 +119,7 @@ bool SaveFile::commit()
}
QString finalFileName
- = FileUtils::resolveSymlinks(FileName::fromString(m_finalFileName)).toString();
+ = FileUtils::resolveSymlinks(FilePath::fromString(m_finalFileName)).toString();
#ifdef Q_OS_WIN
// Release the file lock
diff --git a/src/libs/utils/settingsaccessor.cpp b/src/libs/utils/settingsaccessor.cpp
index 662ad4bd43..f6d90df7e0 100644
--- a/src/libs/utils/settingsaccessor.cpp
+++ b/src/libs/utils/settingsaccessor.cpp
@@ -98,7 +98,7 @@ bool SettingsAccessor::saveSettings(const QVariantMap &data, QWidget *parent) co
/*!
* Read data from \a path. Do all the necessary postprocessing of the data.
*/
-SettingsAccessor::RestoreData SettingsAccessor::readData(const FileName &path, QWidget *parent) const
+SettingsAccessor::RestoreData SettingsAccessor::readData(const FilePath &path, QWidget *parent) const
{
Q_UNUSED(parent);
RestoreData result = readFile(path);
@@ -111,13 +111,13 @@ SettingsAccessor::RestoreData SettingsAccessor::readData(const FileName &path, Q
* Store the \a data in \a path on disk. Do all the necessary preprocessing of the data.
*/
optional<SettingsAccessor::Issue>
-SettingsAccessor::writeData(const FileName &path, const QVariantMap &data, QWidget *parent) const
+SettingsAccessor::writeData(const FilePath &path, const QVariantMap &data, QWidget *parent) const
{
Q_UNUSED(parent);
return writeFile(path, prepareToWriteSettings(data));
}
-QVariantMap SettingsAccessor::restoreSettings(const FileName &settingsPath, QWidget *parent) const
+QVariantMap SettingsAccessor::restoreSettings(const FilePath &settingsPath, QWidget *parent) const
{
const RestoreData result = readData(settingsPath, parent);
@@ -131,7 +131,7 @@ QVariantMap SettingsAccessor::restoreSettings(const FileName &settingsPath, QWid
*
* This method does not do *any* processing of the file contents.
*/
-SettingsAccessor::RestoreData SettingsAccessor::readFile(const FileName &path) const
+SettingsAccessor::RestoreData SettingsAccessor::readFile(const FilePath &path) const
{
PersistentSettingsReader reader;
if (!reader.load(path)) {
@@ -156,7 +156,7 @@ SettingsAccessor::RestoreData SettingsAccessor::readFile(const FileName &path) c
* This method does not do *any* processing of the file contents.
*/
optional<SettingsAccessor::Issue>
-SettingsAccessor::writeFile(const FileName &path, const QVariantMap &data) const
+SettingsAccessor::writeFile(const FilePath &path, const QVariantMap &data) const
{
if (data.isEmpty()) {
return Issue(QCoreApplication::translate("Utils::SettingsAccessor", "Failed to Write File"),
@@ -176,7 +176,7 @@ SettingsAccessor::writeFile(const FileName &path, const QVariantMap &data) const
}
SettingsAccessor::ProceedInfo
-SettingsAccessor::reportIssues(const SettingsAccessor::Issue &issue, const FileName &path,
+SettingsAccessor::reportIssues(const SettingsAccessor::Issue &issue, const FilePath &path,
QWidget *parent) const
{
if (!path.exists())
@@ -217,14 +217,14 @@ QVariantMap SettingsAccessor::prepareToWriteSettings(const QVariantMap &data) co
// BackingUpSettingsAccessor:
// --------------------------------------------------------------------
-FileNameList BackUpStrategy::readFileCandidates(const FileName &baseFileName) const
+FilePathList BackUpStrategy::readFileCandidates(const FilePath &baseFileName) const
{
const QFileInfo pfi = baseFileName.toFileInfo();
const QStringList filter(pfi.fileName() + '*');
const QFileInfoList list = QDir(pfi.dir()).entryInfoList(filter, QDir::Files | QDir::Hidden | QDir::System);
- return Utils::transform(list, [](const QFileInfo &fi) { return FileName::fromString(fi.absoluteFilePath()); });
+ return Utils::transform(list, [](const QFileInfo &fi) { return FilePath::fromString(fi.absoluteFilePath()); });
}
int BackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,
@@ -239,14 +239,12 @@ int BackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,
return 0;
}
-optional<FileName>
-BackUpStrategy::backupName(const QVariantMap &oldData, const FileName &path, const QVariantMap &data) const
+optional<FilePath>
+BackUpStrategy::backupName(const QVariantMap &oldData, const FilePath &path, const QVariantMap &data) const
{
if (oldData == data)
return nullopt;
- FileName backup = path;
- backup.appendString(".bak");
- return backup;
+ return path.stringAppended(".bak");
}
BackingUpSettingsAccessor::BackingUpSettingsAccessor(const QString &docType,
@@ -264,9 +262,9 @@ BackingUpSettingsAccessor::BackingUpSettingsAccessor(std::unique_ptr<BackUpStrat
{ }
SettingsAccessor::RestoreData
-BackingUpSettingsAccessor::readData(const FileName &path, QWidget *parent) const
+BackingUpSettingsAccessor::readData(const FilePath &path, QWidget *parent) const
{
- const FileNameList fileList = readFileCandidates(path);
+ const FilePathList fileList = readFileCandidates(path);
if (fileList.isEmpty()) // No settings found at all.
return RestoreData(path, QVariantMap());
@@ -289,7 +287,7 @@ BackingUpSettingsAccessor::readData(const FileName &path, QWidget *parent) const
}
optional<SettingsAccessor::Issue>
-BackingUpSettingsAccessor::writeData(const FileName &path, const QVariantMap &data,
+BackingUpSettingsAccessor::writeData(const FilePath &path, const QVariantMap &data,
QWidget *parent) const
{
if (data.isEmpty())
@@ -300,9 +298,9 @@ BackingUpSettingsAccessor::writeData(const FileName &path, const QVariantMap &da
return SettingsAccessor::writeData(path, data, parent);
}
-FileNameList BackingUpSettingsAccessor::readFileCandidates(const FileName &path) const
+FilePathList BackingUpSettingsAccessor::readFileCandidates(const FilePath &path) const
{
- FileNameList result = Utils::filteredUnique(m_strategy->readFileCandidates(path));
+ FilePathList result = Utils::filteredUnique(m_strategy->readFileCandidates(path));
if (result.removeOne(baseFilePath()))
result.prepend(baseFilePath());
@@ -310,10 +308,10 @@ FileNameList BackingUpSettingsAccessor::readFileCandidates(const FileName &path)
}
SettingsAccessor::RestoreData
-BackingUpSettingsAccessor::bestReadFileData(const FileNameList &candidates, QWidget *parent) const
+BackingUpSettingsAccessor::bestReadFileData(const FilePathList &candidates, QWidget *parent) const
{
SettingsAccessor::RestoreData bestMatch;
- for (const FileName &c : candidates) {
+ for (const FilePath &c : candidates) {
RestoreData cData = SettingsAccessor::readData(c, parent);
if (m_strategy->compare(bestMatch, cData) > 0)
bestMatch = cData;
@@ -321,7 +319,7 @@ BackingUpSettingsAccessor::bestReadFileData(const FileNameList &candidates, QWid
return bestMatch;
}
-void BackingUpSettingsAccessor::backupFile(const FileName &path, const QVariantMap &data,
+void BackingUpSettingsAccessor::backupFile(const FilePath &path, const QVariantMap &data,
QWidget *parent) const
{
RestoreData oldSettings = SettingsAccessor::readData(path, parent);
@@ -330,7 +328,7 @@ void BackingUpSettingsAccessor::backupFile(const FileName &path, const QVariantM
// Do we need to do a backup?
const QString origName = path.toString();
- optional<FileName> backupFileName = m_strategy->backupName(oldSettings.data, path, data);
+ optional<FilePath> backupFileName = m_strategy->backupName(oldSettings.data, path, data);
if (backupFileName)
QFile::copy(origName, backupFileName.value().toString());
}
@@ -361,22 +359,23 @@ int VersionedBackUpStrategy::compare(const SettingsAccessor::RestoreData &data1,
return -1;
}
-optional<FileName>
-VersionedBackUpStrategy::backupName(const QVariantMap &oldData, const FileName &path, const QVariantMap &data) const
+optional<FilePath>
+VersionedBackUpStrategy::backupName(const QVariantMap &oldData, const FilePath &path, const QVariantMap &data) const
{
Q_UNUSED(data);
- FileName backupName = path;
+ FilePath backupName = path;
const QByteArray oldEnvironmentId = settingsIdFromMap(oldData);
const int oldVersion = versionFromMap(oldData);
if (!oldEnvironmentId.isEmpty() && oldEnvironmentId != m_accessor->settingsId())
- backupName.appendString('.' + QString::fromLatin1(oldEnvironmentId).mid(1, 7));
+ backupName = backupName.stringAppended
+ ('.' + QString::fromLatin1(oldEnvironmentId).mid(1, 7));
if (oldVersion != m_accessor->currentVersion()) {
VersionUpgrader *upgrader = m_accessor->upgrader(oldVersion);
if (upgrader)
- backupName.appendString('.' + upgrader->backupExtension());
+ backupName = backupName.stringAppended('.' + upgrader->backupExtension());
else
- backupName.appendString('.' + QString::number(oldVersion));
+ backupName = backupName.stringAppended('.' + QString::number(oldVersion));
}
if (backupName == path)
return nullopt;
@@ -464,7 +463,7 @@ bool UpgradingSettingsAccessor::isValidVersionAndId(const int version, const QBy
&& (id.isEmpty() || id == m_id || m_id.isEmpty());
}
-SettingsAccessor::RestoreData UpgradingSettingsAccessor::readData(const FileName &path,
+SettingsAccessor::RestoreData UpgradingSettingsAccessor::readData(const FilePath &path,
QWidget *parent) const
{
return upgradeSettings(BackingUpSettingsAccessor::readData(path, parent), currentVersion());
@@ -606,7 +605,7 @@ MergingSettingsAccessor::MergingSettingsAccessor(std::unique_ptr<BackUpStrategy>
UpgradingSettingsAccessor(std::move(strategy), docType, displayName, applicationDisplayName)
{ }
-SettingsAccessor::RestoreData MergingSettingsAccessor::readData(const FileName &path,
+SettingsAccessor::RestoreData MergingSettingsAccessor::readData(const FilePath &path,
QWidget *parent) const
{
RestoreData mainData = UpgradingSettingsAccessor::readData(path, parent); // FULLY upgraded!
diff --git a/src/libs/utils/settingsaccessor.h b/src/libs/utils/settingsaccessor.h
index 10675cbf4c..fd5cf87ef7 100644
--- a/src/libs/utils/settingsaccessor.h
+++ b/src/libs/utils/settingsaccessor.h
@@ -99,7 +99,7 @@ public:
class RestoreData {
public:
RestoreData() = default;
- RestoreData(const FileName &path, const QVariantMap &data) : path{path}, data{data} { }
+ RestoreData(const FilePath &path, const QVariantMap &data) : path{path}, data{data} { }
RestoreData(const QString &title, const QString &message, const Issue::Type type) :
RestoreData(Issue(title, message, type))
{ }
@@ -109,7 +109,7 @@ public:
bool hasError() const { return hasIssue() && issue.value().type == Issue::Type::ERROR; }
bool hasWarning() const { return hasIssue() && issue.value().type == Issue::Type::WARNING; }
- FileName path;
+ FilePath path;
QVariantMap data;
optional<Issue> issue;
};
@@ -121,26 +121,26 @@ public:
const QString displayName;
const QString applicationDisplayName;
- void setBaseFilePath(const FileName &baseFilePath) { m_baseFilePath = baseFilePath; }
+ void setBaseFilePath(const FilePath &baseFilePath) { m_baseFilePath = baseFilePath; }
void setReadOnly() { m_readOnly = true; }
- FileName baseFilePath() const { return m_baseFilePath; }
+ FilePath baseFilePath() const { return m_baseFilePath; }
- virtual RestoreData readData(const FileName &path, QWidget *parent) const;
- virtual optional<Issue> writeData(const FileName &path, const QVariantMap &data, QWidget *parent) const;
+ virtual RestoreData readData(const FilePath &path, QWidget *parent) const;
+ virtual optional<Issue> writeData(const FilePath &path, const QVariantMap &data, QWidget *parent) const;
protected:
// Report errors:
- QVariantMap restoreSettings(const FileName &settingsPath, QWidget *parent) const;
- ProceedInfo reportIssues(const Issue &issue, const FileName &path, QWidget *parent) const;
+ QVariantMap restoreSettings(const FilePath &settingsPath, QWidget *parent) const;
+ ProceedInfo reportIssues(const Issue &issue, const FilePath &path, QWidget *parent) const;
virtual QVariantMap preprocessReadSettings(const QVariantMap &data) const;
virtual QVariantMap prepareToWriteSettings(const QVariantMap &data) const;
- virtual RestoreData readFile(const FileName &path) const;
- virtual optional<Issue> writeFile(const FileName &path, const QVariantMap &data) const;
+ virtual RestoreData readFile(const FilePath &path) const;
+ virtual optional<Issue> writeFile(const FilePath &path, const QVariantMap &data) const;
private:
- FileName m_baseFilePath;
+ FilePath m_baseFilePath;
mutable std::unique_ptr<PersistentSettingsWriter> m_writer;
bool m_readOnly = false;
};
@@ -154,14 +154,14 @@ class QTCREATOR_UTILS_EXPORT BackUpStrategy
public:
virtual ~BackUpStrategy() = default;
- virtual FileNameList readFileCandidates(const FileName &baseFileName) const;
+ virtual FilePathList readFileCandidates(const FilePath &baseFileName) const;
// Return -1 if data1 is better that data2, 0 if both are equally worthwhile
// and 1 if data2 is better than data1
virtual int compare(const SettingsAccessor::RestoreData &data1,
const SettingsAccessor::RestoreData &data2) const;
- virtual optional<FileName>
- backupName(const QVariantMap &oldData, const FileName &path, const QVariantMap &data) const;
+ virtual optional<FilePath>
+ backupName(const QVariantMap &oldData, const FilePath &path, const QVariantMap &data) const;
};
class QTCREATOR_UTILS_EXPORT BackingUpSettingsAccessor : public SettingsAccessor
@@ -172,16 +172,16 @@ public:
BackingUpSettingsAccessor(std::unique_ptr<BackUpStrategy> &&strategy, const QString &docType,
const QString &displayName, const QString &applicationDisplayName);
- RestoreData readData(const FileName &path, QWidget *parent) const override;
- optional<Issue> writeData(const FileName &path, const QVariantMap &data,
+ RestoreData readData(const FilePath &path, QWidget *parent) const override;
+ optional<Issue> writeData(const FilePath &path, const QVariantMap &data,
QWidget *parent) const override;
BackUpStrategy *strategy() const { return m_strategy.get(); }
private:
- FileNameList readFileCandidates(const FileName &path) const;
- RestoreData bestReadFileData(const FileNameList &candidates, QWidget *parent) const;
- void backupFile(const FileName &path, const QVariantMap &data, QWidget *parent) const;
+ FilePathList readFileCandidates(const FilePath &path) const;
+ RestoreData bestReadFileData(const FilePathList &candidates, QWidget *parent) const;
+ void backupFile(const FilePath &path, const QVariantMap &data, QWidget *parent) const;
std::unique_ptr<BackUpStrategy> m_strategy;
};
@@ -202,8 +202,8 @@ public:
int compare(const SettingsAccessor::RestoreData &data1,
const SettingsAccessor::RestoreData &data2) const override;
- optional<FileName>
- backupName(const QVariantMap &oldData, const FileName &path, const QVariantMap &data) const override;
+ optional<FilePath>
+ backupName(const QVariantMap &oldData, const FilePath &path, const QVariantMap &data) const override;
const UpgradingSettingsAccessor *accessor() const { return m_accessor; }
@@ -251,7 +251,7 @@ public:
bool isValidVersionAndId(const int version, const QByteArray &id) const;
VersionUpgrader *upgrader(const int version) const;
- RestoreData readData(const FileName &path, QWidget *parent) const override;
+ RestoreData readData(const FilePath &path, QWidget *parent) const override;
protected:
QVariantMap prepareToWriteSettings(const QVariantMap &data) const override;
@@ -284,7 +284,7 @@ public:
const QString &docType, const QString &displayName,
const QString &applicationDisplayName);
- RestoreData readData(const FileName &path, QWidget *parent) const final;
+ RestoreData readData(const FilePath &path, QWidget *parent) const final;
void setSecondaryAccessor(std::unique_ptr<SettingsAccessor> &&secondary);
diff --git a/src/libs/utils/settingsselector.cpp b/src/libs/utils/settingsselector.cpp
index ddfa7a137c..6ae5bff43c 100644
--- a/src/libs/utils/settingsselector.cpp
+++ b/src/libs/utils/settingsselector.cpp
@@ -73,7 +73,7 @@ SettingsSelector::SettingsSelector(QWidget *parent) :
connect(m_renameButton, &QAbstractButton::clicked,
this, &SettingsSelector::renameButtonClicked);
connect(m_configurationCombo,
- static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &SettingsSelector::currentChanged);
}
diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp
index 14f52d2539..5a84c92f15 100644
--- a/src/libs/utils/shellcommand.cpp
+++ b/src/libs/utils/shellcommand.cpp
@@ -68,11 +68,11 @@ class ShellCommandPrivate
{
public:
struct Job {
- explicit Job(const QString &wd, const FileName &b, const QStringList &a, int t,
+ explicit Job(const QString &wd, const FilePath &b, const QStringList &a, int t,
const ExitCodeInterpreter &interpreter);
QString workingDirectory;
- FileName binary;
+ FilePath binary;
QStringList arguments;
ExitCodeInterpreter exitCodeInterpreter;
int timeoutS;
@@ -113,7 +113,7 @@ ShellCommandPrivate::~ShellCommandPrivate()
delete m_progressParser;
}
-ShellCommandPrivate::Job::Job(const QString &wd, const FileName &b, const QStringList &a,
+ShellCommandPrivate::Job::Job(const QString &wd, const FilePath &b, const QStringList &a,
int t, const ExitCodeInterpreter &interpreter) :
workingDirectory(wd),
binary(b),
@@ -195,13 +195,13 @@ void ShellCommand::addFlags(unsigned f)
d->m_flags |= f;
}
-void ShellCommand::addJob(const FileName &binary, const QStringList &arguments,
+void ShellCommand::addJob(const FilePath &binary, const QStringList &arguments,
const QString &workingDirectory, const ExitCodeInterpreter &interpreter)
{
addJob(binary, arguments, defaultTimeoutS(), workingDirectory, interpreter);
}
-void ShellCommand::addJob(const FileName &binary, const QStringList &arguments, int timeoutS,
+void ShellCommand::addJob(const FilePath &binary, const QStringList &arguments, int timeoutS,
const QString &workingDirectory, const ExitCodeInterpreter &interpreter)
{
d->m_jobs.push_back(Internal::ShellCommandPrivate::Job(workDirectory(workingDirectory), binary,
@@ -319,7 +319,7 @@ void ShellCommand::run(QFutureInterface<void> &future)
this->deleteLater();
}
-SynchronousProcessResponse ShellCommand::runCommand(const FileName &binary,
+SynchronousProcessResponse ShellCommand::runCommand(const FilePath &binary,
const QStringList &arguments, int timeoutS,
const QString &workingDirectory,
const ExitCodeInterpreter &interpreter)
@@ -359,7 +359,7 @@ SynchronousProcessResponse ShellCommand::runCommand(const FileName &binary,
return response;
}
-SynchronousProcessResponse ShellCommand::runFullySynchronous(const FileName &binary,
+SynchronousProcessResponse ShellCommand::runFullySynchronous(const FilePath &binary,
const QStringList &arguments,
QSharedPointer<OutputProxy> proxy,
int timeoutS,
@@ -399,7 +399,7 @@ SynchronousProcessResponse ShellCommand::runFullySynchronous(const FileName &bin
return resp;
}
-SynchronousProcessResponse ShellCommand::runSynchronous(const FileName &binary,
+SynchronousProcessResponse ShellCommand::runSynchronous(const FilePath &binary,
const QStringList &arguments,
QSharedPointer<OutputProxy> proxy,
int timeoutS,
diff --git a/src/libs/utils/shellcommand.h b/src/libs/utils/shellcommand.h
index 22ff4a8df2..f0c427ef53 100644
--- a/src/libs/utils/shellcommand.h
+++ b/src/libs/utils/shellcommand.h
@@ -46,7 +46,7 @@ QT_END_NAMESPACE
namespace Utils {
-class FileName;
+class FilePath;
namespace Internal { class ShellCommandPrivate; }
class QTCREATOR_UTILS_EXPORT ProgressParser
@@ -79,7 +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::FileName &binary,
+ void appendCommand(const QString &workingDirectory, const Utils::FilePath &binary,
const QStringList &args);
void appendMessage(const QString &text);
};
@@ -112,9 +112,9 @@ public:
QString displayName() const;
void setDisplayName(const QString &name);
- void addJob(const FileName &binary, const QStringList &arguments,
+ void addJob(const FilePath &binary, const QStringList &arguments,
const QString &workingDirectory = QString(), const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
- void addJob(const FileName &binary, const QStringList &arguments, int timeoutS,
+ void addJob(const FilePath &binary, const QStringList &arguments, int timeoutS,
const QString &workingDirectory = QString(), const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
void execute(); // Execute tasks asynchronously!
void abort();
@@ -145,7 +145,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 FileName &binary, const QStringList &arguments,
+ virtual SynchronousProcessResponse runCommand(const FilePath &binary, const QStringList &arguments,
int timeoutS,
const QString &workingDirectory = QString(),
const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
@@ -171,12 +171,12 @@ private:
void run(QFutureInterface<void> &future);
// Run without a event loop in fully blocking mode. No signals will be delivered.
- SynchronousProcessResponse runFullySynchronous(const FileName &binary, const QStringList &arguments,
+ SynchronousProcessResponse runFullySynchronous(const FilePath &binary, const QStringList &arguments,
QSharedPointer<OutputProxy> proxy,
int timeoutS, const QString &workingDirectory,
const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
// Run with an event loop. Signals will be delivered.
- SynchronousProcessResponse runSynchronous(const FileName &binary, const QStringList &arguments,
+ SynchronousProcessResponse runSynchronous(const FilePath &binary, const QStringList &arguments,
QSharedPointer<OutputProxy> proxy,
int timeoutS, const QString &workingDirectory,
const ExitCodeInterpreter &interpreter = defaultExitCodeInterpreter);
diff --git a/src/libs/utils/smallstringlayout.h b/src/libs/utils/smallstringlayout.h
index dc6867af5d..c381fbd44b 100644
--- a/src/libs/utils/smallstringlayout.h
+++ b/src/libs/utils/smallstringlayout.h
@@ -198,13 +198,6 @@ struct StringDataLayout {
shortString.string[0] = '\0';
}
- StringDataLayout &operator=(const StringDataLayout &other)
- {
- this->shortString = other.shortString;
-
- return *this;
- }
-
union {
AllocatedLayout<MaximumShortStringDataAreaSize> allocated;
ReferenceLayout<MaximumShortStringDataAreaSize> reference;
diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp
index b39af367d5..161cf44e74 100644
--- a/src/libs/utils/stringutils.cpp
+++ b/src/libs/utils/stringutils.cpp
@@ -143,7 +143,7 @@ bool AbstractMacroExpander::expandNestedMacros(const QString &str, int *pos, QSt
varName.reserve(strLen - i);
for (; i < strLen; prev = c) {
c = str.at(i++);
- if (c == '\\' && i < strLen && validateVarName(varName)) {
+ if (c == '\\' && i < strLen) {
c = str.at(i++);
// For the replacement, do not skip the escape sequence when followed by a digit.
// This is needed for enabling convenient capture group replacement,
diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp
index e44037f5a1..388da7eeba 100644
--- a/src/libs/utils/stylehelper.cpp
+++ b/src/libs/utils/stylehelper.cpp
@@ -209,9 +209,9 @@ static void verticalGradientHelper(QPainter *p, const QRect &spanRect, const QRe
void StyleHelper::verticalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
{
if (StyleHelper::usePixmapCache()) {
- QString key;
+
QColor keyColor = baseColor(lightColored);
- key.sprintf("mh_vertical %d %d %d %d %d",
+ const QString key = QString::asprintf("mh_vertical %d %d %d %d %d",
spanRect.width(), spanRect.height(), clipRect.width(),
clipRect.height(), keyColor.rgb());
@@ -267,9 +267,9 @@ QRect &rect, bool lightColored)
void StyleHelper::horizontalGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect, bool lightColored)
{
if (StyleHelper::usePixmapCache()) {
- QString key;
+
QColor keyColor = baseColor(lightColored);
- key.sprintf("mh_horizontal %d %d %d %d %d %d",
+ const QString key = QString::asprintf("mh_horizontal %d %d %d %d %d %d",
spanRect.width(), spanRect.height(), clipRect.width(),
clipRect.height(), keyColor.rgb(), spanRect.x());
@@ -309,8 +309,7 @@ void StyleHelper::drawArrow(QStyle::PrimitiveElement element, QPainter *painter,
QRect r = option->rect;
int size = qMin(r.height(), r.width());
QPixmap pixmap;
- QString pixmapName;
- pixmapName.sprintf("StyleHelper::drawArrow-%d-%d-%d-%f",
+ const QString pixmapName = QString::asprintf("StyleHelper::drawArrow-%d-%d-%d-%f",
element, size, enabled, devicePixelRatio);
if (!QPixmapCache::find(pixmapName, &pixmap)) {
QImage image(size * devicePixelRatio, size * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
@@ -351,8 +350,7 @@ void StyleHelper::drawArrow(QStyle::PrimitiveElement element, QPainter *painter,
void StyleHelper::menuGradient(QPainter *painter, const QRect &spanRect, const QRect &clipRect)
{
if (StyleHelper::usePixmapCache()) {
- QString key;
- key.sprintf("mh_menu %d %d %d %d %d",
+ const QString key = QString::asprintf("mh_menu %d %d %d %d %d",
spanRect.width(), spanRect.height(), clipRect.width(),
clipRect.height(), StyleHelper::baseColor().rgb());
diff --git a/src/libs/utils/synchronousprocess.cpp b/src/libs/utils/synchronousprocess.cpp
index a153e6ac91..bfb9d0d296 100644
--- a/src/libs/utils/synchronousprocess.cpp
+++ b/src/libs/utils/synchronousprocess.cpp
@@ -297,8 +297,7 @@ SynchronousProcess::SynchronousProcess() :
{
d->m_timer.setInterval(1000);
connect(&d->m_timer, &QTimer::timeout, this, &SynchronousProcess::slotTimeout);
- connect(&d->m_process,
- static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
+ connect(&d->m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &SynchronousProcess::finished);
connect(&d->m_process, &QProcess::errorOccurred, this, &SynchronousProcess::error);
connect(&d->m_process, &QProcess::readyReadStandardOutput,
diff --git a/src/libs/utils/textfieldcombobox.cpp b/src/libs/utils/textfieldcombobox.cpp
index db940ad53a..aad64d2e7d 100644
--- a/src/libs/utils/textfieldcombobox.cpp
+++ b/src/libs/utils/textfieldcombobox.cpp
@@ -43,7 +43,7 @@ TextFieldComboBox::TextFieldComboBox(QWidget *parent) :
QComboBox(parent)
{
setEditable(false);
- connect(this, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ connect(this, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &TextFieldComboBox::slotCurrentIndexChanged);
}
diff --git a/src/libs/utils/touchbar/touchbar.pri b/src/libs/utils/touchbar/touchbar.pri
index 8d60ee423b..5f18595785 100644
--- a/src/libs/utils/touchbar/touchbar.pri
+++ b/src/libs/utils/touchbar/touchbar.pri
@@ -9,7 +9,6 @@ macos {
$$PWD/touchbar_mac.mm \
$$PWD/touchbar_appdelegate_mac.mm
- QT += macextras
LIBS += -framework Foundation -framework AppKit
} else {
SOURCES += $$PWD/touchbar.cpp
diff --git a/src/libs/utils/touchbar/touchbar_mac.mm b/src/libs/utils/touchbar/touchbar_mac.mm
index 67c83aec0c..ee5a45bf72 100644
--- a/src/libs/utils/touchbar/touchbar_mac.mm
+++ b/src/libs/utils/touchbar/touchbar_mac.mm
@@ -29,8 +29,6 @@
#include <utils/utilsicons.h>
-#include <QtMac>
-
#import <AppKit/NSButton.h>
#import <AppKit/NSCustomTouchBarItem.h>
#import <AppKit/NSImage.h>
@@ -145,8 +143,12 @@ static NSImage *iconToTemplateNSImage(const QIcon &icon)
{
// touch bar icons are max 18-22 pts big. our are always 22 pts big.
const QPixmap pixmap = icon.pixmap(22);
- NSImage *image = QtMac::toNSImage(pixmap);
- // toNSImage ignores devicePixelRatio, so fixup after the fact
+
+ CGImageRef cgImage = pixmap.toImage().toCGImage();
+ NSImage *image = [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize];
+ CFRelease(cgImage);
+
+ // The above code ignores devicePixelRatio, so fixup after the fact
const CGFloat userWidth = pixmap.width() / pixmap.devicePixelRatio();
const CGFloat userHeight = pixmap.height() / pixmap.devicePixelRatio();
image.size = CGSizeMake(userWidth, userHeight); // scales the image
diff --git a/src/libs/utils/unixutils.cpp b/src/libs/utils/unixutils.cpp
index 7db05c22ea..77daae645c 100644
--- a/src/libs/utils/unixutils.cpp
+++ b/src/libs/utils/unixutils.cpp
@@ -77,7 +77,7 @@ QString UnixUtils::substituteFileBrowserParameters(const QString &pre, const QSt
} else if (c == QLatin1Char('f')) {
s = QLatin1Char('"') + file + QLatin1Char('"');
} else if (c == QLatin1Char('n')) {
- s = QLatin1Char('"') + FileName::fromString(file).fileName() + QLatin1Char('"');
+ s = QLatin1Char('"') + FilePath::fromString(file).fileName() + QLatin1Char('"');
} else if (c == QLatin1Char('%')) {
s = c;
} else {
diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri
index 5a2712cc3f..c7fef47c97 100644
--- a/src/libs/utils/utils-lib.pri
+++ b/src/libs/utils/utils-lib.pri
@@ -13,7 +13,7 @@ shared {
}
}
-QT += widgets gui network qml
+QT += widgets gui network qml xml
CONFIG += exceptions # used by portlist.cpp, textfileformat.cpp, and ssh/*
@@ -27,6 +27,7 @@ SOURCES += \
$$PWD/environment.cpp \
$$PWD/environmentmodel.cpp \
$$PWD/environmentdialog.cpp \
+ $$PWD/qrcparser.cpp \
$$PWD/qtcprocess.cpp \
$$PWD/reloadpromptutils.cpp \
$$PWD/settingsaccessor.cpp \
@@ -131,12 +132,14 @@ win32:SOURCES += $$PWD/consoleprocess_win.cpp
else:SOURCES += $$PWD/consoleprocess_unix.cpp
HEADERS += \
+ $$PWD/genericconstants.h \
$$PWD/globalfilechangeblocker.h \
$$PWD/benchmarker.h \
$$PWD/environment.h \
$$PWD/environmentmodel.h \
$$PWD/environmentdialog.h \
$$PWD/pointeralgorithm.h \
+ $$PWD/qrcparser.h \
$$PWD/qtcprocess.h \
$$PWD/utils_global.h \
$$PWD/reloadpromptutils.h \
@@ -266,7 +269,8 @@ HEADERS += \
$$PWD/removefiledialog.h \
$$PWD/differ.h \
$$PWD/cpplanguage_details.h \
- $$PWD/jsontreeitem.h
+ $$PWD/jsontreeitem.h \
+ $$PWD/listmodel.h
FORMS += $$PWD/filewizardpage.ui \
$$PWD/newclasswidget.ui \
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index d50f7f41f6..694045e290 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -33,7 +33,7 @@ Project {
cpp.frameworks: ["Foundation", "AppKit"]
}
- Depends { name: "Qt"; submodules: ["concurrent", "network", "qml", "widgets"] }
+ Depends { name: "Qt"; submodules: ["concurrent", "network", "qml", "widgets", "xml"] }
Depends { name: "Qt.macextras"; condition: qbs.targetOS.contains("macos") }
Depends { name: "app_version_header" }
@@ -146,6 +146,7 @@ Project {
"jsontreeitem.h",
"linecolumn.h",
"link.h",
+ "listmodel.h",
"listutils.h",
"macroexpander.cpp",
"macroexpander.h",
@@ -191,6 +192,8 @@ Project {
"proxycredentialsdialog.cpp",
"proxycredentialsdialog.h",
"proxycredentialsdialog.ui",
+ "qrcparser.cpp",
+ "qrcparser.h",
"qtcassert.cpp",
"qtcassert.h",
"qtcolorbutton.cpp",
diff --git a/src/libs/utils/utils.qrc b/src/libs/utils/utils.qrc
index 6ad7dd3196..a8731b6b20 100644
--- a/src/libs/utils/utils.qrc
+++ b/src/libs/utils/utils.qrc
@@ -34,6 +34,8 @@
<file>images/locked@2x.png</file>
<file>images/unlocked.png</file>
<file>images/unlocked@2x.png</file>
+ <file>images/pinned.png</file>
+ <file>images/pinned@2x.png</file>
<file>images/broken.png</file>
<file>images/broken@2x.png</file>
<file>images/notloaded.png</file>
@@ -213,6 +215,14 @@
<file>images/macos_touchbar_bookmark@2x.png</file>
<file>images/macos_touchbar_clear.png</file>
<file>images/macos_touchbar_clear@2x.png</file>
+ <file>images/settings.png</file>
+ <file>images/settings@2x.png</file>
+ <file>images/sort_alphabetically.png</file>
+ <file>images/sort_alphabetically@2x.png</file>
+ <file>images/toggleprogressdetails.png</file>
+ <file>images/toggleprogressdetails@2x.png</file>
+ <file>images/unknownfile.png</file>
+ <file>images/dir.png</file>
</qresource>
<qresource prefix="/codemodel">
<file>images/enum.png</file>
diff --git a/src/libs/utils/utilsicons.cpp b/src/libs/utils/utilsicons.cpp
index 9855165c3e..2227f530c6 100644
--- a/src/libs/utils/utilsicons.cpp
+++ b/src/libs/utils/utilsicons.cpp
@@ -28,7 +28,6 @@
namespace Utils {
namespace Icons {
-
const Icon HOME({
{QLatin1String(":/utils/images/home.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon HOME_TOOLBAR({
@@ -43,6 +42,8 @@ const Icon LOCKED({
{QLatin1String(":/utils/images/locked.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon UNLOCKED_TOOLBAR({
{QLatin1String(":/utils/images/unlocked.png"), Theme::IconsBaseColor}});
+const Icon PINNED({
+ {QLatin1String(":/utils/images/pinned.png"), Theme::PanelTextColorDark}}, Icon::Tint);
const Icon NEXT({
{QLatin1String(":/utils/images/next.png"), Theme::IconsWarningColor}}, Icon::MenuTintedStyle);
const Icon NEXT_TOOLBAR({
@@ -85,6 +86,8 @@ const Icon SNAPSHOT_TOOLBAR({
const Icon NEWSEARCH_TOOLBAR({
{QLatin1String(":/utils/images/zoom.png"), Theme::IconsBaseColor},
{QLatin1String(":/utils/images/iconoverlay_add_small.png"), Theme::IconsRunColor}});
+const Icon SETTINGS_TOOLBAR({
+ {QLatin1String(":/utils/images/settings.png"), Theme::IconsBaseColor}});
const Icon NEWFILE({
{QLatin1String(":/utils/images/filenew.png"), Theme::PanelTextColorMid}}, Icon::Tint);
@@ -102,6 +105,11 @@ const Icon EXPORTFILE_TOOLBAR({
const Icon MULTIEXPORTFILE_TOOLBAR({
{QLatin1String(":/utils/images/filemultiexport.png"), Theme::IconsBaseColor}});
+const Icon UNKNOWN_FILE({
+ {QLatin1String(":/utils/images/unknownfile.png"), Theme::IconsBaseColor}});
+const Icon DIR({
+ {QLatin1String(":/utils/images/dir.png"), Theme::IconsBaseColor}});
+
const Icon UNDO({
{QLatin1String(":/utils/images/undo.png"), Theme::PanelTextColorMid}}, Icon::Tint);
const Icon UNDO_TOOLBAR({
@@ -182,6 +190,11 @@ const Icon LINK({
{QLatin1String(":/utils/images/linkicon.png"), Theme::PanelTextColorMid}}, Icon::Tint);
const Icon LINK_TOOLBAR({
{QLatin1String(":/utils/images/linkicon.png"), Theme::IconsBaseColor}});
+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 WARNING({
{QLatin1String(":/utils/images/warningfill.png"), Theme::BackgroundColorNormal},
{QLatin1String(":/utils/images/warning.png"), Theme::IconsWarningColor}}, Icon::Tint);
@@ -444,6 +457,10 @@ QIcon CodeModelIcon::iconForType(CodeModelIcon::Type type)
}, Icon::Tint).icon());
return icon;
}
+ case Unknown: {
+ const static QIcon icon(Icons::EMPTY16.icon());
+ return icon;
+ }
default:
break;
}
diff --git a/src/libs/utils/utilsicons.h b/src/libs/utils/utilsicons.h
index b229523911..ae6cd4d1dc 100644
--- a/src/libs/utils/utilsicons.h
+++ b/src/libs/utils/utilsicons.h
@@ -38,6 +38,7 @@ QTCREATOR_UTILS_EXPORT extern const Icon EDIT_CLEAR_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon LOCKED_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon LOCKED;
QTCREATOR_UTILS_EXPORT extern const Icon UNLOCKED_TOOLBAR;
+QTCREATOR_UTILS_EXPORT extern const Icon PINNED;
QTCREATOR_UTILS_EXPORT extern const Icon NEXT;
QTCREATOR_UTILS_EXPORT extern const Icon NEXT_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon PREV;
@@ -56,6 +57,7 @@ QTCREATOR_UTILS_EXPORT extern const Icon BOOKMARK_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon BOOKMARK_TEXTEDITOR;
QTCREATOR_UTILS_EXPORT extern const Icon SNAPSHOT_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon NEWSEARCH_TOOLBAR;
+QTCREATOR_UTILS_EXPORT extern const Icon SETTINGS_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon NEWFILE;
QTCREATOR_UTILS_EXPORT extern const Icon OPENFILE;
@@ -66,6 +68,9 @@ QTCREATOR_UTILS_EXPORT extern const Icon SAVEFILE_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon EXPORTFILE_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon MULTIEXPORTFILE_TOOLBAR;
+QTCREATOR_UTILS_EXPORT extern const Icon UNKNOWN_FILE;
+QTCREATOR_UTILS_EXPORT extern const Icon DIR;
+
QTCREATOR_UTILS_EXPORT extern const Icon UNDO;
QTCREATOR_UTILS_EXPORT extern const Icon UNDO_TOOLBAR;
QTCREATOR_UTILS_EXPORT extern const Icon REDO;
@@ -106,6 +111,8 @@ QTCREATOR_UTILS_EXPORT extern const Icon CLOSE_SPLIT_RIGHT;
QTCREATOR_UTILS_EXPORT extern const Icon FILTER;
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 INFO;
QTCREATOR_UTILS_EXPORT extern const Icon INFO_TOOLBAR;
diff --git a/src/libs/utils/variant.h b/src/libs/utils/variant.h
index 00e9eaf252..371b9312d3 100644
--- a/src/libs/utils/variant.h
+++ b/src/libs/utils/variant.h
@@ -30,10 +30,25 @@
*/
// TODO: replace by #include <(experimental/)variant> depending on compiler and C++ version
-#include <3rdparty/variant/variant.hpp>
+#if __cplusplus >= 201703L
+#error Please delete variant.hpp and the #else section below, then remove this error
+#include <variant>
namespace Utils {
+using std::get;
+using std::get_if;
+using std::holds_alternative;
+using std::variant;
+} // namespace Utils
-using namespace mpark;
+#else
+#include <3rdparty/variant/variant.hpp>
+namespace Utils {
+using mpark::get;
+using mpark::get_if;
+using mpark::holds_alternative;
+using mpark::variant;
} // namespace Utils
+
+#endif
diff --git a/src/libs/utils/wizardpage.h b/src/libs/utils/wizardpage.h
index fa8c60b052..abeccfce13 100644
--- a/src/libs/utils/wizardpage.h
+++ b/src/libs/utils/wizardpage.h
@@ -29,6 +29,7 @@
#include <QSet>
#include <QString>
+#include <QVariant>
#include <QWizardPage>
#include <functional>
@@ -41,30 +42,30 @@ namespace Internal {
class QTCREATOR_UTILS_EXPORT ObjectToFieldWidgetConverter : public QWidget
{
Q_OBJECT
- Q_PROPERTY(QString text READ text NOTIFY textChanged)
+ Q_PROPERTY(QVariant value READ value NOTIFY valueChanged)
public:
- template <class T, typename... Arguments>
- static ObjectToFieldWidgetConverter *create(T *sender, void (T::*member)(Arguments...), const std::function<QString()> &toTextFunction)
+ template<class T, typename... Arguments>
+ static ObjectToFieldWidgetConverter *create(T *sender,
+ void (T::*member)(Arguments...),
+ const std::function<QVariant()> &toVariantFunction)
{
auto widget = new ObjectToFieldWidgetConverter();
- widget->toTextFunction = toTextFunction;
+ widget->toVariantFunction = toVariantFunction;
connect(sender, &QObject::destroyed, widget, &QObject::deleteLater);
- connect(sender, member, widget, [widget] () {
- emit widget->textChanged(widget->text());
- });
+ connect(sender, member, widget, [widget]() { emit widget->valueChanged(widget->value()); });
return widget;
}
signals:
- void textChanged(const QString&);
+ void valueChanged(const QVariant &);
private:
ObjectToFieldWidgetConverter () = default;
- // is used by the property text
- QString text() {return toTextFunction();}
- std::function<QString()> toTextFunction;
+ // is used by the property value
+ QVariant value() { return toVariantFunction(); }
+ std::function<QVariant()> toVariantFunction;
};
} // Internal
@@ -79,10 +80,17 @@ public:
virtual void pageWasAdded(); // called when this page was added to a Utils::Wizard
template<class T, typename... Arguments>
- void registerObjectAsFieldWithName(const QString &name, T *sender, void (T::*changeSignal)(Arguments...),
- const std::function<QString()> &senderToString)
+ void registerObjectAsFieldWithName(const QString &name,
+ T *sender,
+ void (T::*changeSignal)(Arguments...),
+ const std::function<QVariant()> &senderToVariant)
{
- registerFieldWithName(name, Internal::ObjectToFieldWidgetConverter::create(sender, changeSignal, senderToString), "text", SIGNAL(textChanged(QString)));
+ registerFieldWithName(name,
+ Internal::ObjectToFieldWidgetConverter::create(sender,
+ changeSignal,
+ senderToVariant),
+ "value",
+ SIGNAL(valueChanged(QValue)));
}
void registerFieldWithName(const QString &name, QWidget *widget,