summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2019-06-28 12:50:03 +0200
committerEike Ziller <eike.ziller@qt.io>2019-06-28 12:50:03 +0200
commit10098b2508abe6e8df59b7e27ea64e9483f1f8be (patch)
treeb73815f1e8ca7aa12c347706b410050e3eb22caa
parent5dbfd46bcfe177b8308c70a66f7d404429249f6b (diff)
parenta111f251261159b50e92d6866f2058c66b43e390 (diff)
downloadqt-creator-10098b2508abe6e8df59b7e27ea64e9483f1f8be.tar.gz
Merge remote-tracking branch 'origin/4.10'
Conflicts: CMakeLists.txt tests/unit/unittest/unittest.pro Change-Id: I64296ad31502d9b35012da129a28e9277e9fcf8e
-rw-r--r--CMakeLists.txt47
-rw-r--r--cmake/QtCreatorIDEBranding.cmake14
-rw-r--r--dist/changes-4.10.0.md20
-rw-r--r--dist/changes-4.9.2.md56
-rw-r--r--doc/images/qtcreator-autotests-options-boost.pngbin0 -> 5636 bytes
-rw-r--r--doc/images/qtcreator-autotests-options-google.pngbin15199 -> 7267 bytes
-rw-r--r--doc/images/qtcreator-autotests-options-qt.pngbin17817 -> 7429 bytes
-rw-r--r--doc/images/qtcreator-autotests-options.pngbin7194 -> 12098 bytes
-rw-r--r--doc/images/qtcreator-autotests.pngbin69724 -> 44003 bytes
-rw-r--r--doc/images/qtcreator-cmakeexecutable.pngbin28996 -> 11541 bytes
-rw-r--r--doc/images/qtcreator-tests-view.pngbin30506 -> 8796 bytes
-rw-r--r--doc/src/cmake/creator-projects-cmake.qdoc7
-rw-r--r--doc/src/howto/creator-only/creator-autotest.qdoc97
-rw-r--r--doc/src/overview/creator-only/creator-overview.qdoc6
-rw-r--r--doc/src/overview/creator-only/creator-testing.qdoc7
-rw-r--r--share/qtcreator/debugger/gdbbridge.py2
-rw-r--r--share/qtcreator/debugger/stdtypes.py61
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml32
-rw-r--r--share/qtcreator/templates/wizards/files/java/wizard.json2
-rw-r--r--share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs2
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json2
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/git/wizard.json4
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json2
-rw-r--r--share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json4
-rw-r--r--share/qtcreator/translations/qtcreator_fr.ts6
-rw-r--r--src/libs/clangsupport/clangpathwatcher.h214
-rw-r--r--src/libs/clangsupport/clangsupport-lib.pri11
-rw-r--r--src/libs/clangsupport/directoryandfilepathid.h90
-rw-r--r--src/libs/clangsupport/directorypathcompressor.h (renamed from src/libs/clangsupport/changedfilepathcompressor.h)48
-rw-r--r--src/libs/clangsupport/directorypathid.h81
-rw-r--r--src/libs/clangsupport/filepathcache.h48
-rw-r--r--src/libs/clangsupport/filepathcaching.cpp15
-rw-r--r--src/libs/clangsupport/filepathcaching.h3
-rw-r--r--src/libs/clangsupport/filepathcachinginterface.h6
-rw-r--r--src/libs/clangsupport/filepathexceptions.h9
-rw-r--r--src/libs/clangsupport/filepathstorage.h22
-rw-r--r--src/libs/clangsupport/filepathstoragesqlitestatementfactory.h2
-rw-r--r--src/libs/clangsupport/filestatus.h (renamed from src/tools/clangrefactoringbackend/source/filestatus.h)0
-rw-r--r--src/libs/clangsupport/filestatuscache.cpp137
-rw-r--r--src/libs/clangsupport/filestatuscache.h (renamed from src/tools/clangrefactoringbackend/source/filestatuscache.h)36
-rw-r--r--src/libs/clangsupport/filesystem.cpp61
-rw-r--r--src/libs/clangsupport/filesystem.h48
-rw-r--r--src/libs/clangsupport/filesysteminterface.h43
-rw-r--r--src/libs/clangsupport/modifiedtimechecker.h184
-rw-r--r--src/libs/clangsupport/modifiedtimecheckerinterface.h1
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h4
-rw-r--r--src/libs/clangsupport/set_algorithm.h101
-rw-r--r--src/libs/clangsupport/sourceentry.h4
-rw-r--r--src/libs/languageserverprotocol/icontent.h5
-rw-r--r--src/libs/qmljs/qmljscheck.cpp2
-rw-r--r--src/libs/utils/smallstringview.h4
-rw-r--r--src/plugins/autotest/autotestunittests.cpp5
-rw-r--r--src/plugins/autotest/boost/boosttestoutputreader.h1
-rw-r--r--src/plugins/baremetal/iarewtoolchain.cpp6
-rw-r--r--src/plugins/clangcodemodel/clangcodemodelplugin.cpp2
-rw-r--r--src/plugins/clangtools/clangselectablefilesdialog.cpp3
-rw-r--r--src/plugins/clangtools/clangtoolruncontrol.cpp10
-rw-r--r--src/plugins/clangtools/clangtoolsconfigwidget.cpp3
-rw-r--r--src/plugins/clangtools/clangtoolsprojectsettings.cpp4
-rw-r--r--src/plugins/clangtools/clangtoolsutils.cpp23
-rw-r--r--src/plugins/clangtools/clangtoolsutils.h3
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager.cpp8
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager.h4
-rw-r--r--src/plugins/coreplugin/idocument.cpp1
-rw-r--r--src/plugins/coreplugin/ioutputpane.h10
-rw-r--r--src/plugins/coreplugin/messageoutputwindow.cpp2
-rw-r--r--src/plugins/coreplugin/outputpanemanager.cpp32
-rw-r--r--src/plugins/coreplugin/outputwindow.h1
-rw-r--r--src/plugins/cppeditor/cppparsecontext.cpp6
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp11
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp2
-rw-r--r--src/plugins/languageclient/languageclientsettings.cpp10
-rw-r--r--src/plugins/perfprofiler/perfprofilertool.cpp6
-rw-r--r--src/plugins/projectexplorer/appoutputpane.cpp8
-rw-r--r--src/plugins/projectexplorer/appoutputpane.h1
-rw-r--r--src/plugins/projectexplorer/compileoutputwindow.cpp2
-rw-r--r--src/plugins/projectexplorer/environmentwidget.cpp2
-rw-r--r--src/plugins/projectexplorer/filterkitaspectsdialog.cpp2
-rw-r--r--src/plugins/projectexplorer/filterkitaspectsdialog.h1
-rw-r--r--src/plugins/projectexplorer/importwidget.cpp10
-rw-r--r--src/plugins/projectexplorer/importwidget.h3
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp4
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp2
-rw-r--r--src/plugins/projectexplorer/parseissuesdialog.cpp8
-rw-r--r--src/plugins/projectexplorer/project.cpp4
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp14
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp10
-rw-r--r--src/plugins/projectexplorer/targetsetuppage.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakekitinformation.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakesettings.cpp2
-rw-r--r--src/plugins/qmldesigner/components/componentcore/componentcore_constants.h1
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp7
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp32
-rw-r--r--src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h1
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h1
-rw-r--r--src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp9
-rw-r--r--src/plugins/remotelinux/makeinstallstep.cpp4
-rw-r--r--src/plugins/texteditor/highlighter.cpp28
-rw-r--r--src/plugins/valgrind/memchecktool.cpp46
-rw-r--r--src/plugins/vcsbase/vcsoutputwindow.cpp11
-rw-r--r--src/shared/proparser/qmakeevaluator.cpp2
m---------src/shared/qbs0
-rw-r--r--src/shared/registryaccess/registryaccess.h1
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp11
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h11
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h2
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.cpp9
-rw-r--r--src/tools/clangpchmanagerbackend/source/usedmacrofilter.h5
-rw-r--r--src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri5
-rw-r--r--src/tools/clangrefactoringbackend/source/filestatuscache.cpp93
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.cpp8
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.h2
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.h13
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.cpp6
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolscollector.h2
-rw-r--r--src/tools/qtcdebugger/main.cpp9
-rw-r--r--tests/system/objects.map29
-rw-r--r--tests/system/shared/project.py11
-rw-r--r--tests/system/suite_debugger/tst_qml_locals/test.py3
-rw-r--r--tests/system/suite_editors/tst_edit_externally/test.py3
-rw-r--r--tests/system/suite_general/tst_default_settings/test.py10
-rw-r--r--tests/system/suite_tools/tst_designer_goto_slot/test.py10
-rw-r--r--tests/system/suite_tools/tst_git_clone/test.py2
-rw-r--r--tests/system/suite_tools/tst_git_local/test.py6
-rw-r--r--tests/unit/unittest/builddependenciesstorage-test.cpp4
-rw-r--r--tests/unit/unittest/changedfilepathcompressor-test.cpp112
-rw-r--r--tests/unit/unittest/clangpathwatcher-test.cpp281
-rw-r--r--tests/unit/unittest/directorypathcompressor-test.cpp99
-rw-r--r--tests/unit/unittest/filepathcache-test.cpp150
-rw-r--r--tests/unit/unittest/filepathstorage-test.cpp82
-rw-r--r--tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp8
-rw-r--r--tests/unit/unittest/filestatuscache-test.cpp180
-rw-r--r--tests/unit/unittest/gtest-creator-printing.cpp2
-rw-r--r--tests/unit/unittest/gtest-creator-printing.h2
-rw-r--r--tests/unit/unittest/mockbuilddependenciesstorage.h2
-rw-r--r--tests/unit/unittest/mockfilepathcaching.h6
-rw-r--r--tests/unit/unittest/mockfilesystem.h37
-rw-r--r--tests/unit/unittest/mockmodifiedtimechecker.h2
-rw-r--r--tests/unit/unittest/mockqfilesystemwatcher.h1
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.cpp6
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.h11
-rw-r--r--tests/unit/unittest/modifiedtimechecker-test.cpp127
-rw-r--r--tests/unit/unittest/pchcreator-test.cpp24
-rw-r--r--tests/unit/unittest/pchtaskgenerator-test.cpp2
-rw-r--r--tests/unit/unittest/refactoringdatabaseinitializer-test.cpp12
-rw-r--r--tests/unit/unittest/symbolindexer-test.cpp28
-rw-r--r--tests/unit/unittest/symbolscollector-test.cpp23
-rw-r--r--tests/unit/unittest/unittest.pro7
-rw-r--r--tests/unit/unittest/usedmacrofilter-test.cpp7
149 files changed, 2381 insertions, 1007 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4e4cdb41dc..46ab6b8da7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,33 +1,18 @@
cmake_minimum_required(VERSION 3.9)
-include(FeatureSummary)
-
-#BINARY_ARTIFACTS_BRANCH = master
-#PROJECT_USER_FILE_EXTENSION = .user
+## Add paths to check for cmake modules:
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
-set(IDE_VERSION "4.10.82" CACHE STRING "The IDE version.")
-set(IDE_VERSION_COMPAT "4.10.82" CACHE STRING "The IDE Compatibility version.")
-set(IDE_VERSION_DISPLAY "4.11.0-beta1" CACHE STRING "The IDE display version.")
-set(IDE_COPYRIGHT_YEAR "2019" CACHE STRING "The IDE copyright year.")
+include(FeatureSummary)
+include(QtCreatorIDEBranding)
set(IDE_REVISION FALSE CACHE BOOL "Marks the presence of IDE revision string.")
set(IDE_REVISION_STR "" CACHE STRING "The IDE revision string.")
-set(IDE_SETTINGSVARIANT "QtProject" CACHE STRING "The IDE settings variation.")
-set(IDE_COPY_SETTINGSVARIANT "Nokia" CACHE STRING "The IDE settings to initially import.")
-set(IDE_DISPLAY_NAME "Qt Creator" CACHE STRING "The IDE display name.")
-set(IDE_ID "qtcreator" CACHE STRING "The IDE id (no spaces, lowercase!)")
-set(IDE_CASED_ID "QtCreator" CACHE STRING "The cased IDE id (no spaces!)")
-set(IDE_BUNDLE_IDENTIFIER "org.qt-project.${IDE_ID}" CACHE STRING "The macOS application bundle identifier.")
-mark_as_advanced(IDE_VERSION_COMPAT IDE_VERSION_DISPLAY IDE_COPYRIGHT_YEAR
- IDE_REVISION IDE_REVISION_STR IDE_SETTINGSVARIANT IDE_COPY_SETTINGSVARIANT
- IDE_DISPLAY_NAME IDE_ID IDE_CASED_ID IDE_BUNDLE_IDENTIFIER)
+mark_as_advanced(IDE_REVISION IDE_REVISION_STR)
project(QtCreator VERSION ${IDE_VERSION})
-## Add paths to check for cmake modules:
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
-
# Force C++ standard, do not fall back, do not use compiler extensions
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -127,7 +112,7 @@ endif()
set(_IDE_APP_PATH "bin")
if (APPLE)
- set(_IDE_APP_TARGET "Qt Creator")
+ set(_IDE_APP_TARGET "${IDE_DISPLAY_NAME}")
set(_IDE_OUTPUT_PATH "${_IDE_APP_PATH}/${_IDE_APP_TARGET}.app/Contents")
@@ -139,7 +124,7 @@ if (APPLE)
set(_IDE_DOC_PATH "${_IDE_OUTPUT_PATH}/Resources/doc")
set(_IDE_BIN_PATH "${_IDE_OUTPUT_PATH}/MacOS")
else ()
- set(_IDE_APP_TARGET "qtcreator")
+ set(_IDE_APP_TARGET "${IDE_ID}")
set(_IDE_LIBRARY_BASE_PATH "lib")
set(_IDE_LIBRARY_PATH "lib/qtcreator")
@@ -154,15 +139,15 @@ else ()
set(_IDE_BIN_PATH "bin")
endif ()
-set(IDE_APP_PATH "${_IDE_APP_PATH}" CACHE PATH "The target path of the IDE application (relative to CMAKE_INSTALL_PREFIX).")
-set(IDE_APP_TARGET "${_IDE_APP_TARGET}" CACHE PATH "The IDE application name.")
-set(IDE_PLUGIN_PATH "${_IDE_PLUGIN_PATH}" CACHE PATH "The IDE plugin path (relative to CMAKE_INSTALL_PREFIX).")
-set(IDE_LIBRARY_BASE_PATH "${_IDE_LIBRARY_BASE_PATH}" CACHE PATH "The IDE library base path (relative to CMAKE_INSTALL_PREFIX).")
-set(IDE_LIBRARY_PATH "${_IDE_LIBRARY_PATH}" CACHE PATH "The IDE library path (relative to CMAKE_INSTALL_PREFIX).")
-set(IDE_LIBEXEC_PATH "${_IDE_LIBEXEC_PATH}" CACHE PATH "The IDE libexec path (relative to CMAKE_INSTALL_PREFIX).")
-set(IDE_DATA_PATH "${_IDE_DATA_PATH}" CACHE PATH "The IDE data path (relative to CMAKE_INSTALL_PREFIX).")
-set(IDE_DOC_PATH "${_IDE_DOC_PATH}" CACHE PATH "The IDE documentation path (relative to CMAKE_INSTALL_PREFIX).")
-set(IDE_BIN_PATH "${_IDE_BIN_PATH}" CACHE PATH "The IDE bin path (relative to CMAKE_INSTALL_PREFIX).")
+set(IDE_APP_PATH "${_IDE_APP_PATH}") # The target path of the IDE application (relative to CMAKE_INSTALL_PREFIX).
+set(IDE_APP_TARGET "${_IDE_APP_TARGET}") # The IDE application name.
+set(IDE_PLUGIN_PATH "${_IDE_PLUGIN_PATH}") # The IDE plugin path (relative to CMAKE_INSTALL_PREFIX).
+set(IDE_LIBRARY_BASE_PATH "${_IDE_LIBRARY_BASE_PATH}") # The IDE library base path (relative to CMAKE_INSTALL_PREFIX).
+set(IDE_LIBRARY_PATH "${_IDE_LIBRARY_PATH}") # The IDE library path (relative to CMAKE_INSTALL_PREFIX).
+set(IDE_LIBEXEC_PATH "${_IDE_LIBEXEC_PATH}") # The IDE libexec path (relative to CMAKE_INSTALL_PREFIX).
+set(IDE_DATA_PATH "${_IDE_DATA_PATH}") # The IDE data path (relative to CMAKE_INSTALL_PREFIX).
+set(IDE_DOC_PATH "${_IDE_DOC_PATH}") # The IDE documentation path (relative to CMAKE_INSTALL_PREFIX).
+set(IDE_BIN_PATH "${_IDE_BIN_PATH}") # The IDE bin path (relative to CMAKE_INSTALL_PREFIX).
file(RELATIVE_PATH RELATIVE_PLUGIN_PATH "/${IDE_BIN_PATH}" "/${IDE_PLUGIN_PATH}")
file(RELATIVE_PATH RELATIVE_LIBEXEC_PATH "/${IDE_BIN_PATH}" "/${IDE_LIBEXEC_PATH}")
diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake
new file mode 100644
index 0000000000..f7327d19fa
--- /dev/null
+++ b/cmake/QtCreatorIDEBranding.cmake
@@ -0,0 +1,14 @@
+#BINARY_ARTIFACTS_BRANCH = master
+#PROJECT_USER_FILE_EXTENSION = .user
+
+set(IDE_VERSION "4.9.83") # The IDE version.
+set(IDE_VERSION_COMPAT "4.9.83") # The IDE Compatibility version.
+set(IDE_VERSION_DISPLAY "4.10.0-beta2") # The IDE display version.
+set(IDE_COPYRIGHT_YEAR "2019") # The IDE copyright year.
+
+set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation.
+set(IDE_COPY_SETTINGSVARIANT "Nokia") # The IDE settings to initially import.
+set(IDE_DISPLAY_NAME "Qt Creator") # The IDE display name.
+set(IDE_ID "qtcreator") # The IDE id (no spaces, lowercase!)
+set(IDE_CASED_ID "QtCreator") # The cased IDE id (no spaces!)
+set(IDE_BUNDLE_IDENTIFIER "org.qt-project.${IDE_ID}") # The macOS application bundle identifier.
diff --git a/dist/changes-4.10.0.md b/dist/changes-4.10.0.md
index baece64d4f..651c719a32 100644
--- a/dist/changes-4.10.0.md
+++ b/dist/changes-4.10.0.md
@@ -13,6 +13,12 @@ you can check out from the public Git repository. For example:
* Removed support for KDE code paster after removal of official API
* Added option for pinning files so they stay open when closing all files (QTCREATORBUG-21899)
+* Fixed low contrast of hovered folding markers (QTCREATORBUG-21702)
+
+### Generic Highlighter
+
+* Fixed that highlighting definition with MIME type `text/plain`
+ overrode better matching definitions (QTCREATORBUG-22540)
### Language Client
@@ -96,6 +102,9 @@ you can check out from the public Git repository. For example:
* Improved auto-insertion of closing curly brace (QTCREATORBUG-18872)
* Fixed that snippet completion could get in the way (QTCREATORBUG-21767)
+* Fixed crash because of small stack size (QTCREATORBUG-22496)
+* Fixed recognition of C++ version (QTCREATORBUG-22444)
+* Fixed `unknown argument: '-fno-keep-inline-dllexport'` (QTCREATORBUG-22452)
### Clang Format
@@ -105,6 +114,8 @@ you can check out from the public Git repository. For example:
## QML Support
* Fixed various formatting issues
+* Fixed incorrect syntax warning in JavaScript template literal
+ (QTCREATORBUG-22474)
## Debugging
@@ -127,6 +138,7 @@ you can check out from the public Git repository. For example:
* Added gradient picker that allows loading and saving of presets
* Added support for changing properties for multiple items at once (QDS-324)
* Added missing properties for `LineEdit` and `ComboBox`
+* Added all fonts from project directory to font selector (QDS-100)
* Updated properties of `Flickable`
* Improved handling of errors in state editor (QDS-695)
@@ -154,13 +166,12 @@ you can check out from the public Git repository. For example:
* Added `Clone` for MSVC toolchains (QTCREATORBUG-22163)
* Fixed that `mingw32-make`'s warnings were categorized as errors (QTCREATORBUG-22171)
* Fixed bitness detection for MinGW (QTCREATORBUG-22160)
+* Fixed registration as post mortem debugger on recent Windows versions
### Linux
* Improved auto-detection of toolchains (QTCREATORBUG-19179, QTCREATORBUG-20044, QTCREATORBUG-22081)
-### macOS
-
### Android
* Removed support for MIPS64
@@ -172,13 +183,12 @@ you can check out from the public Git repository. For example:
* Added support for opening remote terminal with run environment
* Added option for `rsync` flags for deployment (QTCREATORBUG-22352)
-### Boot to Qt
-
### Bare Metal
* Added include path detection and output parsers for `IAR`, `KEIL` and `SDCC` toolchains
## Credits for these changes go to:
+
Aleksei German
Alessandro Ambrosano
Alessandro Portale
@@ -208,10 +218,12 @@ Ivan Komissarov
Joel Smith
Jörg Bornemann
Kavindra Palaraja
+Knud Dollereder
Leena Miettinen
Luca Carlon
Marco Bubke
Martin Haase
+Michael Weghorn
Mitch Curtis
Nikolai Kosjar
Oliver Wolff
diff --git a/dist/changes-4.9.2.md b/dist/changes-4.9.2.md
new file mode 100644
index 0000000000..bc99860818
--- /dev/null
+++ b/dist/changes-4.9.2.md
@@ -0,0 +1,56 @@
+# Qt Creator 4.9.2
+
+Qt Creator version 4.9.2 contains bug fixes.
+
+The most important changes are listed in this document. For a complete
+list of changes, see the Git log for the Qt Creator sources that
+you can check out from the public Git repository. For example:
+
+ git clone git://code.qt.io/qt-creator/qt-creator.git
+ git log --cherry-pick --pretty=oneline origin/v4.9.1..v4.9.2
+
+## General
+
+* Fixed display of shortcuts in `Keyboard` preferences (QTCREATORBUG-22333)
+
+## Editing
+
+* Fixed disabled editor close button in Design mode (QTCREATORBUG-22553)
+
+### Syntax Highlighting
+
+* Fixed highlighting issue while editing (QTCREATORBUG-22290)
+
+## All Projects
+
+* Fixed saving state of `Hide Empty Directories`
+* Fixed crash that could happen after project parsing failed
+
+## C++ Support
+
+* Fixed expansion of `%DATE%` in license templates (QTCREATORBUG-22440)
+
+## Qt Quick Designer
+
+* Fixed crash on malformed QML (QDS-778)
+
+## Platform Specific
+
+### macOS
+
+* Re-enabled graphics card switching that was disabled as a workaround
+ for OpenGL issues on macOS 10.14.4 (QTCREATORBUG-22215)
+
+## Credits for these changes go to:
+
+Christian Kandeler
+Christian Stenger
+David Schulz
+Eike Ziller
+Leena Miettinen
+Michl Voznesensky
+Robert Löhning
+Thomas Hartmann
+Tim Jenssen
+Tobias Hunger
+Ulf Hermann
diff --git a/doc/images/qtcreator-autotests-options-boost.png b/doc/images/qtcreator-autotests-options-boost.png
new file mode 100644
index 0000000000..4e1f8c4361
--- /dev/null
+++ b/doc/images/qtcreator-autotests-options-boost.png
Binary files differ
diff --git a/doc/images/qtcreator-autotests-options-google.png b/doc/images/qtcreator-autotests-options-google.png
index ce5898e162..a32b5fcabb 100644
--- a/doc/images/qtcreator-autotests-options-google.png
+++ b/doc/images/qtcreator-autotests-options-google.png
Binary files differ
diff --git a/doc/images/qtcreator-autotests-options-qt.png b/doc/images/qtcreator-autotests-options-qt.png
index 84a2501717..ed93ac1280 100644
--- a/doc/images/qtcreator-autotests-options-qt.png
+++ b/doc/images/qtcreator-autotests-options-qt.png
Binary files differ
diff --git a/doc/images/qtcreator-autotests-options.png b/doc/images/qtcreator-autotests-options.png
index e880c8d616..3fd226939d 100644
--- a/doc/images/qtcreator-autotests-options.png
+++ b/doc/images/qtcreator-autotests-options.png
Binary files differ
diff --git a/doc/images/qtcreator-autotests.png b/doc/images/qtcreator-autotests.png
index a7e14d5292..48380a10eb 100644
--- a/doc/images/qtcreator-autotests.png
+++ b/doc/images/qtcreator-autotests.png
Binary files differ
diff --git a/doc/images/qtcreator-cmakeexecutable.png b/doc/images/qtcreator-cmakeexecutable.png
index 8b328b0fb9..a0475e0c04 100644
--- a/doc/images/qtcreator-cmakeexecutable.png
+++ b/doc/images/qtcreator-cmakeexecutable.png
Binary files differ
diff --git a/doc/images/qtcreator-tests-view.png b/doc/images/qtcreator-tests-view.png
index cb771e06cf..0faf49a5a4 100644
--- a/doc/images/qtcreator-tests-view.png
+++ b/doc/images/qtcreator-tests-view.png
Binary files differ
diff --git a/doc/src/cmake/creator-projects-cmake.qdoc b/doc/src/cmake/creator-projects-cmake.qdoc
index 2a29cac9c1..585031ded7 100644
--- a/doc/src/cmake/creator-projects-cmake.qdoc
+++ b/doc/src/cmake/creator-projects-cmake.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -43,6 +43,9 @@
native build configurations and workspaces that you can use in the compiler
environment of your choice.
+ You can use CMake from \QC to build applications for the desktop and
+ Android devices. You can also build single files to test your changes.
+
\QC automatically detects the CMake executable specified in the \c PATH.
You can add paths to other CMake executables and use them in different
build and run \l{glossary-buildandrun-kit}{kits}.
@@ -109,6 +112,8 @@
\li Code completion
+ \li Path completion
+
\li Auto-indentation
\li Matching parentheses and quotes
diff --git a/doc/src/howto/creator-only/creator-autotest.qdoc b/doc/src/howto/creator-only/creator-autotest.qdoc
index 4c0205eaa1..05edde5027 100644
--- a/doc/src/howto/creator-only/creator-autotest.qdoc
+++ b/doc/src/howto/creator-only/creator-autotest.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -31,27 +31,28 @@
\title Running Autotests
- \QC integrates the \l{Qt Test} framework and
- \l{https://github.com/google/googletest}{Google C++ Testing Framework} for
- unit testing applications and libraries. You can use \QC to build and run
- Qt tests, Qt Quick tests (QML-based Qt tests), and Google tests for your
- projects.
+ \QC integrates the \l{Qt Test} framework,
+ \l{https://github.com/google/googletest}{Google C++ Testing Framework}, and
+ \l{https://www.boost.org/doc/libs/1_70_0/libs/test/doc/html/index.html}
+ {Boost.Test} for unit testing applications and libraries. You can use \QC to
+ create, build, and run Qt tests, Qt Quick tests (QML-based Qt tests), Google
+ tests, and Boost tests for your projects.
\image qtcreator-autotests.png
\section1 Creating Tests
- You can use a wizard to create projects that contain Qt or Google tests.
+ You can use a wizard to create projects that contain tests.
- \section2 Creating Qt Tests
+ \section2 Creating Qt and Qt Quick Tests
- To create a Qt test:
+ To create a Qt or Qt Quick test:
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol {Other Project} > \uicontrol {Auto Test Project} >
\uicontrol Choose to create a project with boilerplate code for a
- Qt test.
+ Qt test or a Qt Quick test.
\li In the \uicontrol {Project and Test Information} dialog, specify
settings for the project and test:
@@ -59,17 +60,17 @@
\list 1
\li In the \uicontrol {Test framework} field, select
- \uicontrol {Qt Test}.
+ \uicontrol {Qt Test} or \uicontrol {Qt Quick Test}.
- \li Select the \uicontrol {GUI Application} check box to create
- a Qt application.
+ \li For a Qt test, select the \uicontrol {GUI Application} check
+ box to create a Qt application.
\li In the \uicontrol {Test case name} field, enter a name for
the test case.
- \li Select the \uicontrol {Requires QApplication} check box to
- add the include statement for QApplication to the main.cpp
- file of the project.
+ \li For a Qt test, select the \uicontrol {Requires \QApplication}
+ check box to add the include statement for QApplication to
+ the main.cpp file of the project.
\li Select the \uicontrol {Generate initialization and cleanup
code} checkbox to add functions to your test that are
@@ -135,6 +136,46 @@
\l{https://github.com/google/googletest/blob/master/googletest/docs/primer.md}
{Google Test Primer}.
+ \section2 Creating Boost Tests
+
+ To build and run Boost tests, you must have the Boost.Test installed on the
+ development host. Typically, it is installed when you install Boost. You can
+ download Boost from \l{https://www.boost.org/}{Boost.org}.
+
+ If Boost libraries can be found by the used compiler and build system, you
+ do not need to specify the include directory when creating the test.
+
+ To create a Boost test:
+
+ \list 1
+ \li Select \uicontrol File > \uicontrol {New File or Project} >
+ \uicontrol {Other Project} > \uicontrol {Auto Test Project} >
+ \uicontrol Choose to create a project with boilerplate code for a
+ Boost test.
+ \li In the \uicontrol {Project and Test Information} dialog, specify
+ settings for the project and test:
+ \list 1
+ \li In the \uicontrol {Test framework} field, select
+ \uicontrol {Boost Test}.
+ \li In the \uicontrol {Test suite name} field, enter a name for
+ the test suite.
+ \li In the \uicontrol {Test case name} field, enter a name for
+ the test case.
+ \li In the \uicontrol {Boost include dir (optional)} field,
+ enter the path to the directory that contains files needed
+ by Boost.Test, such as \e version.hpp and a subfolder called
+ \e test that contains the test header files.
+ \li In the \uicontrol {Build system} field, select the build
+ system to use for building the project: qmake, CMake, or
+ Qbs.
+ \endlist
+ \endlist
+
+ \QC creates the test in the specified project directory.
+ For more information about creating Boost tests, see
+ \l{https://www.boost.org/doc/libs/1_70_0/libs/test/doc/html/index.html}
+ {Boost.Test}.
+
\section1 Setting Up the Google C++ Testing Framework
To build and run Google tests, you must have the Google C++ Testing
@@ -310,6 +351,30 @@
failures into C++ exceptions, select the \uicontrol {Throw on failure} check
box.
+ \section2 Specifying Settings for Running Boost Tests
+
+ \list 1
+ \li To specify settings for running Boost tests, select \uicontrol Tools
+ > \uicontrol Options > \uicontrol {Testing} >
+ \uicontrol {Boost Test}.
+ \image qtcreator-autotests-options-boost.png
+ \li In the \uicontrol {Log format} field, select the error report
+ format to specify the type of events you want recorded in the
+ test report.
+ \li In the \uicontrol {Report level} field, select the verbosity level
+ of the test result report. Select \uicontrol No if you do not want
+ a report.
+ \li Select the \uicontrol Randomize check box to execute the tests in
+ a random order, using the seed specified in the \uicontrol Seed
+ field for initializing the randomizer.
+ \li Select the \uicontrol {Catch system errors} check box to catch
+ system errors.
+ \li Select the \uicontrol {Floating point exceptions} check box to
+ detect floating point exceptions.
+ \li Select the \uicontrol {Detect memory leaks} check box to detect
+ memory leaks.
+ \endlist
+
\section1 Viewing Test Output
The test results are displayed in the \uicontrol {Test Results} output pane
diff --git a/doc/src/overview/creator-only/creator-overview.qdoc b/doc/src/overview/creator-only/creator-overview.qdoc
index 790ed4bf0d..09ef2766e4 100644
--- a/doc/src/overview/creator-only/creator-overview.qdoc
+++ b/doc/src/overview/creator-only/creator-overview.qdoc
@@ -116,9 +116,9 @@
execution. In addition, the QML Profiler enables you to profile
Qt Quick applications.
- \QC is integrated to the \l{Qt Test} and Google C++ Testing
- frameworks for unit testing applications and libraries. You can
- use \QC to build and run autotests.
+ \QC is integrated to the \l{Qt Test}, Google C++ Testing, and
+ Boost.Test frameworks for unit testing applications and
+ libraries. You can use \QC to create, build, and run autotests.
For more information, see \l{Testing}.
\li \b {Publishing}
diff --git a/doc/src/overview/creator-only/creator-testing.qdoc b/doc/src/overview/creator-only/creator-testing.qdoc
index 39bae4ba17..10df1d7f31 100644
--- a/doc/src/overview/creator-only/creator-testing.qdoc
+++ b/doc/src/overview/creator-only/creator-testing.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -60,9 +60,8 @@
\li \l{Running Autotests}
- You can build and run Qt tests, Qt Quick tests, and Google tests
- using \QC. In addition, you can use a wizard to create projects that
- contain Qt or Google tests.
+ You can create, build and run Qt tests, Qt Quick tests, Google
+ tests, and Boost tests using \QC.
\endlist
diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py
index fdfb39746e..2f056c7a93 100644
--- a/share/qtcreator/debugger/gdbbridge.py
+++ b/share/qtcreator/debugger/gdbbridge.py
@@ -153,7 +153,7 @@ class PlainDumper:
if d.isExpanded():
with Children(d):
for child in children:
- d.putSubItem(child[0], d.fromNativeValue(child[1]))
+ d.putSubItem(child[0], d.fromNativeValue(gdb.Value(child[1])))
def importPlainDumpers(args):
if args == 'off':
diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py
index a14029fdc3..3dfbe5bd8b 100644
--- a/share/qtcreator/debugger/stdtypes.py
+++ b/share/qtcreator/debugger/stdtypes.py
@@ -953,43 +953,27 @@ def qdumpHelper__std__vector(d, value, isLibCpp):
innerType = value.type[0]
isBool = innerType.name == 'bool'
- try:
- allocator = value.type[1].name
- except:
- allocator = ''
-
- isStdAllocator = allocator == 'std::allocator<%s>' % innerType.name
-
if isBool:
if isLibCpp:
- if isStdAllocator:
- (start, size) = value.split("pp") # start is 'unsigned long *'
- else:
- start = value["__begin_"].pointer()
- size = value["__size_"]
+ start = value["__begin_"].pointer()
+ size = value["__size_"]
alloc = size
else:
- if isStdAllocator:
- (start, soffset, pad, finish, foffset, pad, alloc) = value.split("pI@pI@p")
- else:
- start = value["_M_start"]["_M_p"].pointer()
- soffset = value["_M_start"]["_M_offset"]
- finish = value["_M_finish"]["_M_p"].pointer()
- foffset = value["_M_finish"]["_M_offset"]
- alloc = value["_M_end_of_storage"].pointer()
+ start = value["_M_start"]["_M_p"].pointer()
+ soffset = value["_M_start"]["_M_offset"].integer()
+ finish = value["_M_finish"]["_M_p"].pointer()
+ foffset = value["_M_finish"]["_M_offset"].integer()
+ alloc = value["_M_end_of_storage"].pointer()
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
else:
- if isStdAllocator:
- (start, finish, alloc) = value.split("ppp")
+ if isLibCpp:
+ start = value["__begin_"].pointer()
+ finish = value["__end_"].pointer()
+ alloc = value["__end_cap_"].pointer()
else:
- if isLibCpp:
- start = value["__begin_"].pointer()
- finish = value["__end_"].pointer()
- alloc = value["__end_cap_"].pointer()
- else:
- start = value["_M_start"].pointer()
- finish = value["_M_finish"].pointer()
- alloc = value["_M_end_of_storage"].pointer()
+ start = value["_M_start"].pointer()
+ finish = value["_M_finish"].pointer()
+ alloc = value["_M_end_of_storage"].pointer()
size = int((finish - start) / innerType.size())
d.check(finish <= alloc)
if size > 0:
@@ -1088,19 +1072,12 @@ def qdump__std__basic_string(d, value):
def qdump__std____cxx11__basic_string(d, value):
innerType = value.type[0]
try:
- allocator = value.type[2].name
+ data = value["_M_dataplus"]["_M_p"].pointer()
+ size = int(value["_M_string_length"])
except:
- allocator = ''
- if allocator == 'std::allocator<%s>' % innerType.name:
- (data, size) = value.split("pI")
- else:
- try:
- data = value["_M_dataplus"]["_M_p"]
- size = int(value["_M_string_length"])
- except:
- d.putEmptyValue()
- d.putPlainChildren(value)
- return
+ d.putEmptyValue()
+ d.putPlainChildren(value)
+ return
d.check(0 <= size) #and size <= alloc and alloc <= 100*1000*1000)
d.putCharArrayHelper(data, size, innerType, d.currentItemFormat())
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml
index 16de1a90ef..5d9ae328d2 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontComboBox.qml
@@ -39,7 +39,35 @@ StudioControls.ComboBox {
onTextColorChanged: setColor()
editable: true
- model: ["Arial", "Times New Roman", "Courier", "Verdana", "Tahoma"]
+
+ property string fontFilter: "*.ttf *.otf"
+
+
+ FileResourcesModel {
+ modelNodeBackendProperty: modelNodeBackend
+ filter: comboBox.fontFilter
+ id: fileModel
+ }
+
+ function fontUrlToName(url) {
+ var fontLoader = Qt.createQmlObject('import QtQuick 2.0; FontLoader { source: \"' + url + '\"; }',
+ comboBox,
+ "dynamicFontLoader");
+ return fontLoader.name
+ }
+
+ function setupModel() {
+ var files = fileModel.fileModel
+ var familyNames = ["Arial", "Times New Roman", "Courier", "Verdana", "Tahoma"]
+
+ files.forEach(function (item, index) {
+ var name = fontUrlToName(fileModel.dirPath + "/" + item)
+ familyNames.push(name)
+ });
+
+ familyNames.sort()
+ comboBox.model = familyNames
+ }
onModelChanged: {
editText = comboBox.backendValue.valueToString
@@ -97,10 +125,12 @@ StudioControls.ComboBox {
target: modelNodeBackend
onSelectionChanged: {
comboBox.editText = backendValue.value
+ setupModel()
}
}
Component.onCompleted: {
+ setupModel()
//Hack to style the text input
for (var i = 0; i < comboBox.children.length; i++) {
if (comboBox.children[i].text !== undefined) {
diff --git a/share/qtcreator/templates/wizards/files/java/wizard.json b/share/qtcreator/templates/wizards/files/java/wizard.json
index 6341319c6b..5a8fae5dc1 100644
--- a/share/qtcreator/templates/wizards/files/java/wizard.json
+++ b/share/qtcreator/templates/wizards/files/java/wizard.json
@@ -9,7 +9,7 @@
"iconText": "java",
"enabled": "%{JS: value('Plugins').indexOf('Android') >= 0}",
- "options": [ { "key": "ClassName", "value": "%{JS: value('FileName').charAt(0).toUpperCase() + value('FileName').substr(1).replace(/\\.java$/,'')}" } ],
+ "options": [ { "key": "ClassName", "value": "%{JS: value('FileName').charAt(0).toUpperCase() + value('FileName').substr(1).replace(/[.]java$/,'')}" } ],
"pages" :
[
diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs
index d86ee9b454..27a8b66c3c 100644
--- a/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs
+++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/app.qbs
@@ -2,7 +2,7 @@ import qbs
Application {
@if "%{UseVirtualKeyboard}" == "true"
- Depends { name: "Qt"; submodules: "quick", "virtualkeyboard" }
+ Depends { name: "Qt"; submodules: ["quick", "virtualkeyboard"] }
@else
Depends { name: "Qt.quick" }
@endif
diff --git a/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json
index a8b4d041e7..f81509c4ed 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/bazaar/wizard.json
@@ -14,7 +14,7 @@
{ "key": "vcsId", "value": "B.Bazaar" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "key": "SR", "value": "%{JS: '%{Repo}'.substr('%{Repo}'.indexOf(':') + 1) }" },
- { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"},
+ { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "RevArg", "value": "%{JS: '%{Rev}' !== '' ? '-r' : ''}" },
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" }
],
diff --git a/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json
index c97698612b..0295468f6f 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/git/wizard.json
@@ -13,8 +13,8 @@
[
{ "key": "vcsId", "value": "G.Git" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
- { "key": "SR", "value": "%{JS: '%{Repo}'.replace(/\\.git$/, '') }"},
- { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"},
+ { "key": "SR", "value": "%{JS: '%{Repo}'.replace(/[.]git$/, '') }"},
+ { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "branchArg", "value": "%{JS: '%{Branch}' ? '--branch' : '' }" },
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" }
],
diff --git a/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json
index 75bd410861..8e655e1eb6 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/mercurial/wizard.json
@@ -14,7 +14,7 @@
{ "key": "vcsId", "value": "H.Mercurial" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
{ "key": "SR", "value": "%{JS: '%{Repo}'.substr('%{Repo}'.indexOf(':') + 1) }"},
- { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"},
+ { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" }
],
diff --git a/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json b/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json
index aef8a28b9a..cfeddbb532 100644
--- a/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/vcs/subversion/wizard.json
@@ -13,8 +13,8 @@
[
{ "key": "vcsId", "value": "J.Subversion" },
{ "key": "vcsName", "value": "%{JS: Vcs.displayName('%{vcsId}')}" },
- { "key": "SR", "value": "%{JS: '%{Repo}'.replace(/\\/trunk$/, '').replace(/\\/$/, '') }"},
- { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/\\./, '-') }"},
+ { "key": "SR", "value": "%{JS: '%{Repo}'.replace(/[/]trunk$/, '').replace(/[/]$/, '') }"},
+ { "key": "defaultDir", "value": "%{JS: '%{SR}'.substr('%{SR}'.lastIndexOf('/') + 1).replace(/[.]/g, '-') }"},
{ "key": "TargetPath", "value": "%{Path}/%{Dir}" }
],
diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts
index f1677fa36e..95808e6d7b 100644
--- a/share/qtcreator/translations/qtcreator_fr.ts
+++ b/share/qtcreator/translations/qtcreator_fr.ts
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
-<TS version="2.0" language="fr">
+<TS version="2.1" language="fr">
<context>
<name>Application</name>
<message>
@@ -42412,7 +42412,7 @@ au gestionnaire de version (%2)</translation>
</message>
<message>
<source>Set Message Tracepoint at Line %1...</source>
- <translation>Définir un message de traçace à la ligne %1...</translation>
+ <translation>Définir un message de traçage à la ligne %1...</translation>
</message>
<message>
<source>Disassemble Function &quot;%1&quot;</source>
@@ -70891,7 +70891,7 @@ réinitialisation du moniteur</translation>
<message>
<source>Get Started Now</source>
<translatorcomment>attention à la longueur du texte, doit reste petit</translatorcomment>
- <translation type="unfinished">Démarrer</translation>
+ <translation>Démarrer</translation>
</message>
<message>
<source>Online Community</source>
diff --git a/src/libs/clangsupport/clangpathwatcher.h b/src/libs/clangsupport/clangpathwatcher.h
index dab52996c2..7a7d6ccfcf 100644
--- a/src/libs/clangsupport/clangpathwatcher.h
+++ b/src/libs/clangsupport/clangpathwatcher.h
@@ -1,4 +1,4 @@
-/****************************************************************************
+; /****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
@@ -27,71 +27,94 @@
#include "clangpathwatcherinterface.h"
#include "clangpathwatchernotifier.h"
-#include "changedfilepathcompressor.h"
+#include "directorypathcompressor.h"
#include "filepathcachinginterface.h"
+#include "filesystem.h"
#include "stringcache.h"
+#include <utils/algorithm.h>
+
#include <QTimer>
namespace ClangBackEnd {
+template<class InputIt1, class InputIt2, class Callable>
+void set_greedy_intersection_call(
+ InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable callable)
+{
+ while (first1 != last1 && first2 != last2) {
+ if (*first1 < *first2) {
+ ++first1;
+ } else {
+ if (*first2 < *first1)
+ ++first2;
+ else
+ callable(*first1++);
+ }
+ }
+}
+
class WatcherEntry
{
public:
ProjectPartId id;
- FilePathId pathId;
+ DirectoryPathId directoryPathId;
+ FilePathId filePathId;
+ long long lastModified = -1;
friend bool operator==(WatcherEntry first, WatcherEntry second)
{
- return first.id == second.id && first.pathId == second.pathId;
+ return first.id == second.id && first.directoryPathId == second.directoryPathId
+ && first.filePathId == second.filePathId;
}
friend bool operator<(WatcherEntry first, WatcherEntry second)
{
- return std::tie(first.pathId, first.id) < std::tie(second.pathId, second.id);
+ return std::tie(first.directoryPathId, first.filePathId, first.id)
+ < std::tie(second.directoryPathId, second.filePathId, second.id);
}
- friend bool operator<(WatcherEntry entry, FilePathId pathId)
+ friend bool operator<(DirectoryPathId directoryPathId, WatcherEntry entry)
{
- return entry.pathId < pathId;
+ return directoryPathId < entry.directoryPathId;
}
- friend bool operator<(FilePathId pathId, WatcherEntry entry)
+ friend bool operator<(WatcherEntry entry, DirectoryPathId directoryPathId)
{
- return pathId < entry.pathId;
+ return entry.directoryPathId < directoryPathId;
}
- operator FilePathId() const
- {
- return pathId;
- }
+ operator FilePathId() const { return filePathId; }
+
+ operator DirectoryPathId() const { return directoryPathId; }
};
using WatcherEntries = std::vector<WatcherEntry>;
-template <typename FileSystemWatcher,
- typename Timer>
+template<typename FileSystemWatcher, typename Timer>
class CLANGSUPPORT_GCCEXPORT ClangPathWatcher : public ClangPathWatcherInterface
{
public:
ClangPathWatcher(FilePathCachingInterface &pathCache,
- ClangPathWatcherNotifier *notifier=nullptr)
- : m_changedFilePathCompressor(pathCache),
- m_pathCache(pathCache),
- m_notifier(notifier)
+ FileSystemInterface &fileSystem,
+ ClangPathWatcherNotifier *notifier = nullptr)
+ : m_pathCache(pathCache)
+ , m_fileStatusCache(fileSystem)
+ , m_fileSystem(fileSystem)
+ , m_notifier(notifier)
{
QObject::connect(&m_fileSystemWatcher,
- &FileSystemWatcher::fileChanged,
- [&] (const QString &filePath) { compressChangedFilePath(filePath); });
+ &FileSystemWatcher::directoryChanged,
+ [&](const QString &path) { compressChangedDirectoryPath(path); });
- m_changedFilePathCompressor.setCallback([&] (ClangBackEnd::FilePathIds &&filePathIds) {
- addChangedPathForFilePath(std::move(filePathIds));
+ m_directoryPathCompressor.setCallback([&](ClangBackEnd::DirectoryPathIds &&directoryPathIds) {
+ addChangedPathForFilePath(std::move(directoryPathIds));
});
}
~ClangPathWatcher()
{
- m_changedFilePathCompressor.setCallback([&] (FilePathIds &&) {});
+ m_directoryPathCompressor.setCallback([&](DirectoryPathIds &&) {});
}
void updateIdPaths(const std::vector<IdPaths> &idPaths) override
@@ -109,7 +132,7 @@ public:
auto filteredPaths = filterNotWatchedPaths(removedEntries);
if (!filteredPaths.empty())
- m_fileSystemWatcher.removePaths(convertWatcherEntriesToQStringList(filteredPaths));
+ m_fileSystemWatcher.removePaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
}
void setNotifier(ClangPathWatcherNotifier *notifier) override
@@ -164,7 +187,13 @@ public:
outputIterator = std::transform(idPath.filePathIds.begin(),
idPath.filePathIds.end(),
outputIterator,
- [&] (FilePathId pathId) { return WatcherEntry{id, pathId}; });
+ [&](FilePathId filePathId) {
+ return WatcherEntry{
+ id,
+ m_pathCache.directoryPathId(filePathId),
+ filePathId,
+ m_fileStatusCache.lastModifiedTime(filePathId)};
+ });
}
std::sort(entries.begin(), entries.end());
@@ -182,7 +211,7 @@ public:
mergeToWatchedEntries(newEntries);
if (!filteredPaths.empty())
- m_fileSystemWatcher.addPaths(convertWatcherEntriesToQStringList(filteredPaths));
+ m_fileSystemWatcher.addPaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
}
void removeUnusedEntries(const WatcherEntries &entries, const ProjectPartIds &ids)
@@ -194,33 +223,31 @@ public:
auto filteredPaths = filterNotWatchedPaths(oldEntries);
if (!filteredPaths.empty())
- m_fileSystemWatcher.removePaths(convertWatcherEntriesToQStringList(filteredPaths));
+ m_fileSystemWatcher.removePaths(convertWatcherEntriesToDirectoryPathList(filteredPaths));
}
- FileSystemWatcher &fileSystemWatcher()
+ FileSystemWatcher &fileSystemWatcher() { return m_fileSystemWatcher; }
+
+ QStringList convertWatcherEntriesToDirectoryPathList(const DirectoryPathIds &directoryPathIds) const
{
- return m_fileSystemWatcher;
+ return Utils::transform<QStringList>(directoryPathIds, [&](DirectoryPathId id) {
+ return QString(m_pathCache.directoryPath(id));
+ });
}
- QStringList convertWatcherEntriesToQStringList(
- const WatcherEntries &watcherEntries)
+ QStringList convertWatcherEntriesToDirectoryPathList(const WatcherEntries &watcherEntries) const
{
- QStringList paths;
- paths.reserve(int(watcherEntries.size()));
+ DirectoryPathIds directoryPathIds = Utils::transform<DirectoryPathIds>(
+ watcherEntries, [&](WatcherEntry entry) { return entry.directoryPathId; });
- std::transform(watcherEntries.begin(),
- watcherEntries.end(),
- std::back_inserter(paths),
- [&] (WatcherEntry entry) {
- return QString(m_pathCache.filePath(entry.pathId).path());
- });
+ std::sort(directoryPathIds.begin(), directoryPathIds.end());
+ directoryPathIds.erase(std::unique(directoryPathIds.begin(), directoryPathIds.end()),
+ directoryPathIds.end());
- return paths;
+ return convertWatcherEntriesToDirectoryPathList(directoryPathIds);
}
- template <typename Compare>
- WatcherEntries notWatchedEntries(const WatcherEntries &entries,
- Compare compare) const
+ WatcherEntries notWatchedEntries(const WatcherEntries &entries) const
{
WatcherEntries notWatchedEntries;
notWatchedEntries.reserve(entries.size());
@@ -229,24 +256,23 @@ public:
entries.end(),
m_watchedEntries.cbegin(),
m_watchedEntries.cend(),
- std::back_inserter(notWatchedEntries),
- compare);
+ std::back_inserter(notWatchedEntries));
return notWatchedEntries;
}
- WatcherEntries notWatchedEntries(const WatcherEntries &entries) const
+ DirectoryPathIds notWatchedPaths(const DirectoryPathIds &ids) const
{
- return notWatchedEntries(entries, std::less<WatcherEntry>());
- }
+ DirectoryPathIds notWatchedDirectoryIds;
+ notWatchedDirectoryIds.reserve(ids.size());
- WatcherEntries notWatchedPaths(const WatcherEntries &entries) const
- {
- auto compare = [] (WatcherEntry first, WatcherEntry second) {
- return first.pathId < second.pathId;
- };
+ std::set_difference(ids.begin(),
+ ids.end(),
+ m_watchedEntries.cbegin(),
+ m_watchedEntries.cend(),
+ std::back_inserter(notWatchedDirectoryIds));
- return notWatchedEntries(entries, compare);
+ return notWatchedDirectoryIds;
}
template <typename Compare>
@@ -297,25 +323,24 @@ public:
m_watchedEntries = std::move(newWatchedEntries);
}
- static
- WatcherEntries uniquePaths(const WatcherEntries &pathEntries)
+ static DirectoryPathIds uniquePaths(const WatcherEntries &pathEntries)
{
- WatcherEntries uniqueEntries;
- uniqueEntries.reserve(pathEntries.size());
+ DirectoryPathIds uniqueDirectoryIds;
+ uniqueDirectoryIds.reserve(pathEntries.size());
- auto compare = [] (WatcherEntry first, WatcherEntry second) {
- return first.pathId == second.pathId;
+ auto compare = [](WatcherEntry first, WatcherEntry second) {
+ return first.directoryPathId == second.directoryPathId;
};
std::unique_copy(pathEntries.begin(),
pathEntries.end(),
- std::back_inserter(uniqueEntries),
+ std::back_inserter(uniqueDirectoryIds),
compare);
- return uniqueEntries;
+ return uniqueDirectoryIds;
}
- WatcherEntries filterNotWatchedPaths(const WatcherEntries &entries)
+ DirectoryPathIds filterNotWatchedPaths(const WatcherEntries &entries) const
{
return notWatchedPaths(uniquePaths(entries));
}
@@ -351,40 +376,48 @@ public:
oldEntries.end(),
std::back_inserter(newWatchedEntries));
-
- m_watchedEntries = newWatchedEntries;
+ m_watchedEntries = std::move(newWatchedEntries);
}
- void compressChangedFilePath(const QString &filePath)
+ void compressChangedDirectoryPath(const QString &path)
{
- m_changedFilePathCompressor.addFilePath(filePath);
+ m_directoryPathCompressor.addDirectoryPathId(
+ m_pathCache.directoryPathId(Utils::PathString{path}));
}
- WatcherEntries watchedEntriesForPaths(ClangBackEnd::FilePathIds &&filePathIds)
+ WatcherEntries watchedEntriesForPaths(ClangBackEnd::DirectoryPathIds &&directoryPathIds)
{
WatcherEntries foundEntries;
- foundEntries.reserve(filePathIds.size());
-
- for (FilePathId pathId : filePathIds) {
- auto range = std::equal_range(m_watchedEntries.begin(), m_watchedEntries.end(), pathId);
- foundEntries.insert(foundEntries.end(), range.first, range.second);
- }
+ foundEntries.reserve(m_watchedEntries.size());
+
+ set_greedy_intersection_call(m_watchedEntries.begin(),
+ m_watchedEntries.end(),
+ directoryPathIds.begin(),
+ directoryPathIds.end(),
+ [&](WatcherEntry &entry) {
+ m_fileStatusCache.update(entry.filePathId);
+ auto currentLastModified = m_fileStatusCache.lastModifiedTime(
+ entry.filePathId);
+ if (entry.lastModified < currentLastModified) {
+ foundEntries.push_back(entry);
+ entry.lastModified = currentLastModified;
+ }
+ });
return foundEntries;
}
- FilePathIds watchedPaths(const FilePathIds &filePathIds) const
+ FilePathIds watchedPaths(const WatcherEntries &entries) const
{
- FilePathIds watchedFilePathIds;
- watchedFilePathIds.reserve(filePathIds.size());
+ auto filePathIds = Utils::transform<FilePathIds>(entries, [](WatcherEntry entry) {
+ return entry.filePathId;
+ });
+
+ std::sort(filePathIds.begin(), filePathIds.end());
- std::set_intersection(m_watchedEntries.begin(),
- m_watchedEntries.end(),
- filePathIds.begin(),
- filePathIds.end(),
- std::back_inserter(watchedFilePathIds));
+ filePathIds.erase(std::unique(filePathIds.begin(), filePathIds.end()), filePathIds.end());
- return watchedFilePathIds;
+ return filePathIds;
}
ProjectPartIds idsForWatcherEntries(const WatcherEntries &foundEntries)
@@ -403,21 +436,20 @@ public:
ProjectPartIds uniqueIds(ProjectPartIds &&ids)
{
std::sort(ids.begin(), ids.end());
- auto newEnd = std::unique(ids.begin(), ids.end());
- ids.erase(newEnd, ids.end());
+ ids.erase(std::unique(ids.begin(), ids.end()), ids.end());
return std::move(ids);
}
- void addChangedPathForFilePath(FilePathIds &&filePathIds)
+ void addChangedPathForFilePath(DirectoryPathIds &&directoryPathIds)
{
if (m_notifier) {
- WatcherEntries foundEntries = watchedEntriesForPaths(std::move(filePathIds));
+ WatcherEntries foundEntries = watchedEntriesForPaths(std::move(directoryPathIds));
ProjectPartIds changedIds = idsForWatcherEntries(foundEntries);
m_notifier->pathsWithIdsChanged(uniqueIds(std::move(changedIds)));
- m_notifier->pathsChanged(watchedPaths(filePathIds));
+ m_notifier->pathsChanged(watchedPaths(foundEntries));
}
}
@@ -428,10 +460,12 @@ public:
private:
WatcherEntries m_watchedEntries;
- ChangedFilePathCompressor<Timer> m_changedFilePathCompressor;
FileSystemWatcher m_fileSystemWatcher;
+ FileStatusCache m_fileStatusCache;
+ FileSystemInterface &m_fileSystem;
FilePathCachingInterface &m_pathCache;
ClangPathWatcherNotifier *m_notifier;
+ DirectoryPathCompressor<Timer> m_directoryPathCompressor;
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index df537f5848..dc66408e58 100644
--- a/src/libs/clangsupport/clangsupport-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -18,6 +18,7 @@ SOURCES += \
$$PWD/clangcodemodelserverproxy.cpp \
$$PWD/alivemessage.cpp \
$$PWD/completionsmessage.cpp \
+ $$PWD/filesystem.cpp \
$$PWD/requestcompletionsmessage.cpp \
$$PWD/echomessage.cpp \
$$PWD/endmessage.cpp \
@@ -87,7 +88,8 @@ SOURCES += \
$$PWD/removegeneratedfilesmessage.cpp \
$$PWD/generatedfiles.cpp \
$$PWD/projectpartartefact.cpp \
- $$PWD/projectpartcontainer.cpp
+ $$PWD/projectpartcontainer.cpp \
+ $$PWD/filestatuscache.cpp
HEADERS += \
$$PWD/cancelmessage.h \
@@ -109,7 +111,11 @@ HEADERS += \
$$PWD/alivemessage.h \
$$PWD/clangsupportexceptions.h \
$$PWD/completionsmessage.h \
+ $$PWD/directoryandfilepathid.h \
+ $$PWD/directorypathid.h \
$$PWD/executeinloop.h \
+ $$PWD/filesystem.h \
+ $$PWD/filesysteminterface.h \
$$PWD/pchpaths.h \
$$PWD/projectpartid.h \
$$PWD/projectpartsstorage.h \
@@ -151,6 +157,7 @@ HEADERS += \
$$PWD/refactoringserverinterface.h \
$$PWD/refactoringserverproxy.h \
$$PWD/referencesmessage.h \
+ $$PWD/set_algorithm.h \
$$PWD/unsavedfilesupdatedmessage.h \
$$PWD/removeprojectpartsmessage.h \
$$PWD/requestannotationsmessage.h \
@@ -217,6 +224,8 @@ HEADERS += \
$$PWD/sourceentry.h \
$$PWD/modifiedtimecheckerinterface.h \
$$PWD/environment.h \
+ $$PWD/filestatus.h \
+ $$PWD/filestatuscache.h \
$$PWD/modifiedtimechecker.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangsupport/directoryandfilepathid.h b/src/libs/clangsupport/directoryandfilepathid.h
new file mode 100644
index 0000000000..8969372919
--- /dev/null
+++ b/src/libs/clangsupport/directoryandfilepathid.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 "directorypathid.h"
+#include "filepathid.h"
+
+#include <QDataStream>
+
+#include <vector>
+
+namespace ClangBackEnd {
+class DirectoryAndFilePathId
+{
+public:
+ constexpr DirectoryAndFilePathId() = default;
+
+ DirectoryAndFilePathId(const char *) = delete;
+
+ DirectoryAndFilePathId(int directoryPathId, int filePathId)
+ : directoryPathId(directoryPathId)
+ , filePathId(filePathId)
+ {}
+
+ bool isValid() const { return directoryPathId.isValid() && filePathId.isValid(); }
+
+ friend bool operator==(DirectoryAndFilePathId first, DirectoryAndFilePathId second)
+ {
+ return first.isValid() && first.directoryPathId == second.directoryPathId
+ && first.filePathId == second.filePathId;
+ }
+
+ friend bool operator!=(DirectoryAndFilePathId first, DirectoryAndFilePathId second)
+ {
+ return !(first == second);
+ }
+
+ friend bool operator<(DirectoryAndFilePathId first, DirectoryAndFilePathId second)
+ {
+ return std::tie(first.directoryPathId, first.filePathId)
+ < std::tie(second.directoryPathId, second.filePathId);
+ }
+
+ friend QDataStream &operator<<(QDataStream &out,
+ const DirectoryAndFilePathId &directoryAndFilePathId)
+ {
+ out << directoryAndFilePathId.directoryPathId;
+ out << directoryAndFilePathId.filePathId;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, DirectoryAndFilePathId &directoryAndFilePathId)
+ {
+ in >> directoryAndFilePathId.directoryPathId;
+ in >> directoryAndFilePathId.filePathId;
+ return in;
+ }
+
+public:
+ DirectoryPathId directoryPathId;
+ FilePathId filePathId;
+};
+
+using DirectoryAndFilePathIds = std::vector<DirectoryAndFilePathId>;
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/changedfilepathcompressor.h b/src/libs/clangsupport/directorypathcompressor.h
index aa8e1ec71a..cd02948e83 100644
--- a/src/libs/clangsupport/changedfilepathcompressor.h
+++ b/src/libs/clangsupport/directorypathcompressor.h
@@ -27,53 +27,44 @@
#include "clangsupport_global.h"
-#include <filepathid.h>
-#include <filepathcache.h>
+#include "filepathcachinginterface.h"
+#include <QDir>
#include <QTimer>
-#include <filepathcachinginterface.h>
+#include <utils/algorithm.h>
#include <functional>
namespace ClangBackEnd {
-template <typename Timer>
-class ChangedFilePathCompressor
+template<typename Timer>
+class DirectoryPathCompressor
{
public:
- ChangedFilePathCompressor(FilePathCachingInterface &filePathCache)
- : m_filePathCache(filePathCache)
- {
- m_timer.setSingleShot(true);
- }
+ DirectoryPathCompressor() { m_timer.setSingleShot(true); }
- virtual ~ChangedFilePathCompressor()
- {
- }
+ virtual ~DirectoryPathCompressor() = default;
- void addFilePath(const QString &filePath)
+ void addDirectoryPathId(DirectoryPathId directoryPathIdId)
{
- FilePathId filePathId = m_filePathCache.filePathId(FilePath(filePath));
+ auto found = std::lower_bound(m_directoryPathIds.begin(),
+ m_directoryPathIds.end(),
+ directoryPathIdId);
- auto found = std::lower_bound(m_filePaths.begin(), m_filePaths.end(), filePathId);
-
- if (found == m_filePaths.end() || *found != filePathId)
- m_filePaths.insert(found, filePathId);
+ if (found == m_directoryPathIds.end() || *found != directoryPathIdId)
+ m_directoryPathIds.insert(found, directoryPathIdId);
restartTimer();
}
- FilePathIds takeFilePathIds()
- {
- return std::move(m_filePaths);
- }
+ DirectoryPathIds takeDirectoryPathIds() { return std::move(m_directoryPathIds); }
- virtual void setCallback(std::function<void(ClangBackEnd::FilePathIds &&)> &&callback)
+ virtual void setCallback(std::function<void(ClangBackEnd::DirectoryPathIds &&)> &&callback)
{
- QObject::connect(&m_timer,
- &Timer::timeout,
- [this, callback=std::move(callback)] { callback(takeFilePathIds()); });
+ QObject::connect(&m_timer, &Timer::timeout, [this, callback = std::move(callback)] {
+ callback(takeDirectoryPathIds());
+ });
}
unittest_public:
@@ -88,9 +79,8 @@ unittest_public:
}
private:
- FilePathIds m_filePaths;
+ DirectoryPathIds m_directoryPathIds;
Timer m_timer;
- FilePathCachingInterface &m_filePathCache;
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/directorypathid.h b/src/libs/clangsupport/directorypathid.h
new file mode 100644
index 0000000000..2fd0b5847e
--- /dev/null
+++ b/src/libs/clangsupport/directorypathid.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** 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 <QDataStream>
+
+#include <vector>
+
+namespace ClangBackEnd {
+class DirectoryPathId
+{
+public:
+ constexpr DirectoryPathId() = default;
+
+ DirectoryPathId(const char *) = delete;
+
+ DirectoryPathId(int directoryPathId)
+ : directoryPathId(directoryPathId)
+ {}
+
+ bool isValid() const { return directoryPathId >= 0; }
+
+ friend bool operator==(DirectoryPathId first, DirectoryPathId second)
+ {
+ return first.isValid() && first.directoryPathId == second.directoryPathId;
+ }
+
+ friend bool operator!=(DirectoryPathId first, DirectoryPathId second)
+ {
+ return !(first == second);
+ }
+
+ friend bool operator<(DirectoryPathId first, DirectoryPathId second)
+ {
+ return first.directoryPathId < second.directoryPathId;
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const DirectoryPathId &directoryPathId)
+ {
+ out << directoryPathId.directoryPathId;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, DirectoryPathId &directoryPathId)
+ {
+ in >> directoryPathId.directoryPathId;
+
+ return in;
+ }
+
+public:
+ int directoryPathId = -1;
+};
+
+using DirectoryPathIds = std::vector<DirectoryPathId>;
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filepathcache.h b/src/libs/clangsupport/filepathcache.h
index bdd925a79c..4845416d22 100644
--- a/src/libs/clangsupport/filepathcache.h
+++ b/src/libs/clangsupport/filepathcache.h
@@ -25,9 +25,10 @@
#pragma once
+#include "directorypathid.h"
+#include "filepath.h"
#include "filepathexceptions.h"
#include "filepathid.h"
-#include "filepath.h"
#include "filepathview.h"
#include "stringcache.h"
@@ -121,10 +122,10 @@ public:
{
Utils::SmallStringView directoryPath = filePath.directory();
- int directoryId = m_directoryPathCache.stringId(directoryPath,
- [&] (const Utils::SmallStringView) {
- return m_filePathStorage.fetchDirectoryId(directoryPath);
- });
+ int directoryId = m_directoryPathCache.stringId(
+ directoryPath, [&](const Utils::SmallStringView directoryPath) {
+ return m_filePathStorage.fetchDirectoryId(directoryPath);
+ });
Utils::SmallStringView fileName = filePath.name();
@@ -136,6 +137,17 @@ public:
return fileNameId;
}
+ DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const
+ {
+ Utils::SmallStringView path = directoryPath.back() == '/'
+ ? directoryPath.mid(0, directoryPath.size() - 1)
+ : directoryPath;
+
+ return m_directoryPathCache.stringId(path, [&](const Utils::SmallStringView directoryPath) {
+ return m_filePathStorage.fetchDirectoryId(directoryPath);
+ });
+ }
+
FilePath filePath(FilePathId filePathId) const
{
if (Q_UNLIKELY(!filePathId.isValid()))
@@ -157,6 +169,32 @@ public:
return FilePath{directoryPath, entry.fileName};
}
+ Utils::PathString directoryPath(DirectoryPathId directoryPathId) const
+ {
+ if (Q_UNLIKELY(!directoryPathId.isValid()))
+ throw NoDirectoryPathForInvalidDirectoryPathId();
+
+ auto fetchDirectoryPath = [&](int id) { return m_filePathStorage.fetchDirectoryPath(id); };
+
+ return m_directoryPathCache.string(directoryPathId.directoryPathId, fetchDirectoryPath);
+ }
+
+ DirectoryPathId directoryPathId(FilePathId filePathId) const
+ {
+ if (Q_UNLIKELY(!filePathId.isValid()))
+ throw NoFilePathForInvalidFilePathId();
+
+ auto fetchSoureNameAndDirectoryId = [&](int id) {
+ auto entry = m_filePathStorage.fetchSourceNameAndDirectoryId(id);
+ return FileNameEntry{entry.sourceName, entry.directoryId};
+ };
+
+ FileNameEntry entry = m_fileNameCache.string(filePathId.filePathId,
+ fetchSoureNameAndDirectoryId);
+
+ return m_fileNameCache.string(filePathId.filePathId, fetchSoureNameAndDirectoryId).directoryId;
+ }
+
private:
mutable DirectoryPathCache m_directoryPathCache;
mutable FileNameCache m_fileNameCache;
diff --git a/src/libs/clangsupport/filepathcaching.cpp b/src/libs/clangsupport/filepathcaching.cpp
index 0a3fc6ee41..372ed86bd3 100644
--- a/src/libs/clangsupport/filepathcaching.cpp
+++ b/src/libs/clangsupport/filepathcaching.cpp
@@ -37,4 +37,19 @@ FilePath FilePathCaching::filePath(FilePathId filePathId) const
return m_cache.filePath(filePathId);
}
+DirectoryPathId FilePathCaching::directoryPathId(Utils::SmallStringView directoryPath) const
+{
+ return m_cache.directoryPathId(directoryPath);
+}
+
+Utils::PathString FilePathCaching::directoryPath(DirectoryPathId directoryPathId) const
+{
+ return m_cache.directoryPath(directoryPathId);
+}
+
+DirectoryPathId FilePathCaching::directoryPathId(FilePathId filePathId) const
+{
+ return m_cache.directoryPathId(filePathId);
+}
+
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filepathcaching.h b/src/libs/clangsupport/filepathcaching.h
index a3337755fd..f69b940b15 100644
--- a/src/libs/clangsupport/filepathcaching.h
+++ b/src/libs/clangsupport/filepathcaching.h
@@ -50,6 +50,9 @@ public:
FilePathId filePathId(FilePathView filePath) const override;
FilePath filePath(FilePathId filePathId) const override;
+ DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const override;
+ Utils::PathString directoryPath(DirectoryPathId directoryPathId) const override;
+ DirectoryPathId directoryPathId(FilePathId filePathId) const override;
private:
Factory m_factory;
diff --git a/src/libs/clangsupport/filepathcachinginterface.h b/src/libs/clangsupport/filepathcachinginterface.h
index b9668362f7..098fd39ca9 100644
--- a/src/libs/clangsupport/filepathcachinginterface.h
+++ b/src/libs/clangsupport/filepathcachinginterface.h
@@ -25,6 +25,7 @@
#pragma once
+#include "directorypathid.h"
#include "filepath.h"
#include "filepathid.h"
#include "filepathview.h"
@@ -40,8 +41,11 @@ public:
virtual FilePathId filePathId(FilePathView filePath) const = 0;
virtual FilePath filePath(FilePathId filePathId) const = 0;
+ virtual DirectoryPathId directoryPathId(Utils::SmallStringView directoryPath) const = 0;
+ virtual DirectoryPathId directoryPathId(FilePathId filePathId) const = 0;
+ virtual Utils::PathString directoryPath(DirectoryPathId directoryPathId) const = 0;
- template <typename Container>
+ template<typename Container>
FilePathIds filePathIds(Container &&filePaths) const
{
FilePathIds filePathIds;
diff --git a/src/libs/clangsupport/filepathexceptions.h b/src/libs/clangsupport/filepathexceptions.h
index 80bded0c66..3174d89479 100644
--- a/src/libs/clangsupport/filepathexceptions.h
+++ b/src/libs/clangsupport/filepathexceptions.h
@@ -38,6 +38,15 @@ public:
}
};
+class NoDirectoryPathForInvalidDirectoryPathId : std::exception
+{
+public:
+ const char *what() const noexcept override
+ {
+ return "You cannot get a directory path for an invalid directory path id!";
+ }
+};
+
class SourceNameIdDoesNotExists : std::exception
{
public:
diff --git a/src/libs/clangsupport/filepathstorage.h b/src/libs/clangsupport/filepathstorage.h
index 5917504dbf..8aba2ef6d2 100644
--- a/src/libs/clangsupport/filepathstorage.h
+++ b/src/libs/clangsupport/filepathstorage.h
@@ -179,12 +179,32 @@ public:
transaction.commit();
- return optionalSourceName.value();
+ return *optionalSourceName;
} catch (const Sqlite::StatementIsBusy &) {
return fetchSourceNameAndDirectoryId(sourceId);
}
}
+ int fetchDirectoryId(int sourceId)
+ {
+ try {
+ Sqlite::DeferredTransaction transaction{m_statementFactory.database};
+
+ ReadStatement &statement = m_statementFactory.selectDirectoryIdFromSourcesBySourceId;
+
+ auto optionalDirectoryId = statement.template value<int>(sourceId);
+
+ if (!optionalDirectoryId)
+ throw SourceNameIdDoesNotExists();
+
+ transaction.commit();
+
+ return *optionalDirectoryId;
+ } catch (const Sqlite::StatementIsBusy &) {
+ return fetchDirectoryId(sourceId);
+ }
+ }
+
std::vector<Sources::Source> fetchAllSources()
{
try {
diff --git a/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h b/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h
index dbf8071775..27296a1df6 100644
--- a/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h
+++ b/src/libs/clangsupport/filepathstoragesqlitestatementfactory.h
@@ -69,6 +69,8 @@ public:
"SELECT sourceName, directoryId FROM sources WHERE sourceId = ?",
database
};
+ ReadStatement selectDirectoryIdFromSourcesBySourceId{
+ "SELECT directoryId FROM sources WHERE sourceId = ?", database};
WriteStatement insertIntoSources{
"INSERT INTO sources(directoryId, sourceName) VALUES (?,?)",
database
diff --git a/src/tools/clangrefactoringbackend/source/filestatus.h b/src/libs/clangsupport/filestatus.h
index da2be4a304..da2be4a304 100644
--- a/src/tools/clangrefactoringbackend/source/filestatus.h
+++ b/src/libs/clangsupport/filestatus.h
diff --git a/src/libs/clangsupport/filestatuscache.cpp b/src/libs/clangsupport/filestatuscache.cpp
new file mode 100644
index 0000000000..e8ed50a833
--- /dev/null
+++ b/src/libs/clangsupport/filestatuscache.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "filestatuscache.h"
+#include "filesystem.h"
+
+#include <set_algorithm.h>
+
+#include <utils/algorithm.h>
+
+#include <QDateTime>
+#include <QFileInfo>
+
+namespace ClangBackEnd {
+
+long long FileStatusCache::lastModifiedTime(FilePathId filePathId) const
+{
+ return findEntry(filePathId).lastModified;
+}
+
+void FileStatusCache::update(FilePathId filePathId)
+{
+ auto found = std::lower_bound(m_cacheEntries.begin(),
+ m_cacheEntries.end(),
+ Internal::FileStatusCacheEntry{filePathId},
+ [] (const auto &first, const auto &second) {
+ return first.filePathId < second.filePathId;
+ });
+
+ if (found != m_cacheEntries.end() && found->filePathId == filePathId)
+ found->lastModified = m_fileSystem.lastModified(filePathId);
+}
+
+void FileStatusCache::update(FilePathIds filePathIds)
+{
+ std::set_intersection(m_cacheEntries.begin(),
+ m_cacheEntries.end(),
+ filePathIds.begin(),
+ filePathIds.end(),
+ make_iterator([&](auto &entry) {
+ entry.lastModified = m_fileSystem.lastModified(entry.filePathId);
+ }));
+}
+
+FilePathIds FileStatusCache::modified(FilePathIds filePathIds) const
+{
+ FilePathIds modifiedFilePathIds;
+ modifiedFilePathIds.reserve(filePathIds.size());
+
+ std::set_intersection(m_cacheEntries.begin(),
+ m_cacheEntries.end(),
+ filePathIds.begin(),
+ filePathIds.end(),
+ make_iterator([&](auto &entry) {
+ auto newLastModified = m_fileSystem.lastModified(entry.filePathId);
+ if (newLastModified > entry.lastModified) {
+ modifiedFilePathIds.push_back(entry.filePathId);
+ entry.lastModified = newLastModified;
+ }
+ }));
+
+ Internal::FileStatusCacheEntries newEntries;
+ newEntries.reserve(filePathIds.size());
+
+ std::set_difference(filePathIds.begin(),
+ filePathIds.end(),
+ m_cacheEntries.begin(),
+ m_cacheEntries.end(),
+ make_iterator([&](FilePathId newFilePathId) {
+ newEntries.emplace_back(newFilePathId,
+ m_fileSystem.lastModified(newFilePathId));
+ modifiedFilePathIds.push_back(newFilePathId);
+ }));
+
+ if (newEntries.size()) {
+ Internal::FileStatusCacheEntries mergedEntries;
+ mergedEntries.reserve(m_cacheEntries.size() + newEntries.size());
+
+ std::set_union(newEntries.begin(),
+ newEntries.end(),
+ m_cacheEntries.begin(),
+ m_cacheEntries.end(),
+ std::back_inserter(mergedEntries));
+
+ m_cacheEntries = std::move(mergedEntries);
+ }
+
+ std::sort(modifiedFilePathIds.begin(), modifiedFilePathIds.end());
+
+ return modifiedFilePathIds;
+}
+
+FileStatusCache::size_type FileStatusCache::size() const
+{
+ return m_cacheEntries.size();
+}
+
+Internal::FileStatusCacheEntry FileStatusCache::findEntry(FilePathId filePathId) const
+{
+ auto found = std::lower_bound(m_cacheEntries.begin(),
+ m_cacheEntries.end(),
+ Internal::FileStatusCacheEntry{filePathId},
+ [] (const auto &first, const auto &second) {
+ return first.filePathId < second.filePathId;
+ });
+
+ if (found != m_cacheEntries.end() && found->filePathId == filePathId)
+ return *found;
+
+ auto inserted = m_cacheEntries.emplace(found, filePathId, m_fileSystem.lastModified(filePathId));
+
+ return *inserted;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/filestatuscache.h b/src/libs/clangsupport/filestatuscache.h
index 23195da605..3f0af56b3a 100644
--- a/src/tools/clangrefactoringbackend/source/filestatuscache.h
+++ b/src/libs/clangsupport/filestatuscache.h
@@ -31,6 +31,8 @@ QT_FORWARD_DECLARE_CLASS(QFileInfo)
namespace ClangBackEnd {
+class FileSystemInterface;
+
namespace Internal {
class FileStatusCacheEntry
{
@@ -41,8 +43,23 @@ public:
lastModified(lastModified)
{}
+ friend bool operator<(FileStatusCacheEntry first, FileStatusCacheEntry second)
+ {
+ return first.filePathId < second.filePathId;
+ }
+
+ friend bool operator<(FileStatusCacheEntry first, FilePathId second)
+ {
+ return first.filePathId < second;
+ }
+
+ friend bool operator<(FilePathId first, FileStatusCacheEntry second)
+ {
+ return first < second.filePathId;
+ }
+
public:
- ClangBackEnd::FilePathId filePathId;
+ FilePathId filePathId;
long long lastModified;
};
@@ -50,27 +67,30 @@ using FileStatusCacheEntries = std::vector<FileStatusCacheEntry>;
}
-class FileStatusCache
+class CLANGSUPPORT_EXPORT FileStatusCache
{
public:
using size_type = Internal::FileStatusCacheEntries::size_type;
- FileStatusCache(FilePathCachingInterface &filePathCache);
+ FileStatusCache(FileSystemInterface &fileSystem)
+ : m_fileSystem(fileSystem)
+ {}
FileStatusCache &operator=(const FileStatusCache &) = delete;
FileStatusCache(const FileStatusCache &) = delete;
- long long lastModifiedTime(ClangBackEnd::FilePathId filePathId) const;
- void update(ClangBackEnd::FilePathId filePathId);
+ long long lastModifiedTime(FilePathId filePathId) const;
+ void update(FilePathId filePathId);
+ void update(FilePathIds filePathIds);
+ FilePathIds modified(FilePathIds filePathIds) const;
size_type size() const;
private:
- Internal::FileStatusCacheEntry findEntry(ClangBackEnd::FilePathId filePathId) const;
- QFileInfo qFileInfo(ClangBackEnd::FilePathId filePathId) const;
+ Internal::FileStatusCacheEntry findEntry(FilePathId filePathId) const;
private:
mutable Internal::FileStatusCacheEntries m_cacheEntries;
- FilePathCachingInterface &m_filePathCache;
+ FileSystemInterface &m_fileSystem;
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filesystem.cpp b/src/libs/clangsupport/filesystem.cpp
new file mode 100644
index 0000000000..5b8c037f80
--- /dev/null
+++ b/src/libs/clangsupport/filesystem.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "filesystem.h"
+#include "filepathcachinginterface.h"
+
+#include <utils/algorithm.h>
+
+#include <QDateTime>
+#include <QDir>
+#include <QFileInfo>
+
+namespace ClangBackEnd {
+
+FilePathIds FileSystem::directoryEntries(const QString &directoryPath) const
+{
+ QDir directory{directoryPath};
+
+ QFileInfoList fileInfos = directory.entryInfoList();
+
+ FilePathIds filePathIds = Utils::transform<FilePathIds>(fileInfos, [&](const QFileInfo &fileInfo) {
+ return m_filePathCache.filePathId(FilePath{fileInfo.path()});
+ });
+
+ std::sort(filePathIds.begin(), filePathIds.end());
+
+ return filePathIds;
+}
+
+long long FileSystem::lastModified(FilePathId filePathId) const
+{
+ QFileInfo fileInfo(QString(m_filePathCache.filePath(filePathId)));
+
+ fileInfo.refresh();
+
+ return fileInfo.lastModified().toMSecsSinceEpoch() / 1000;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filesystem.h b/src/libs/clangsupport/filesystem.h
new file mode 100644
index 0000000000..ecf332de55
--- /dev/null
+++ b/src/libs/clangsupport/filesystem.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** 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 "filestatuscache.h"
+#include "filesysteminterface.h"
+
+namespace ClangBackEnd {
+class FilePathCachingInterface;
+
+class CLANGSUPPORT_EXPORT FileSystem final : public FileSystemInterface
+{
+public:
+ FileSystem(FilePathCachingInterface &filePathCache)
+ : m_filePathCache(filePathCache)
+ {}
+
+ FilePathIds directoryEntries(const QString &directoryPath) const override;
+ long long lastModified(FilePathId filePathId) const override;
+
+private:
+ FilePathCachingInterface &m_filePathCache;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filesysteminterface.h b/src/libs/clangsupport/filesysteminterface.h
new file mode 100644
index 0000000000..9d64d2a93a
--- /dev/null
+++ b/src/libs/clangsupport/filesysteminterface.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "filepathid.h"
+
+#include <utils/smallstringview.h>
+
+namespace ClangBackEnd {
+
+class FileSystemInterface
+{
+public:
+ virtual FilePathIds directoryEntries(const QString &directoryPath) const = 0;
+ virtual long long lastModified(FilePathId filePathId) const = 0;
+
+protected:
+ ~FileSystemInterface() = default;
+};
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/modifiedtimechecker.h b/src/libs/clangsupport/modifiedtimechecker.h
index c9b62c4673..00e8e3ebac 100644
--- a/src/libs/clangsupport/modifiedtimechecker.h
+++ b/src/libs/clangsupport/modifiedtimechecker.h
@@ -25,23 +25,23 @@
#pragma once
-#include "filepathcachinginterface.h"
+#include "filesysteminterface.h"
#include "modifiedtimecheckerinterface.h"
+#include "set_algorithm.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)
+ ModifiedTimeChecker(FileSystemInterface &fileSystem)
+ : m_fileSystem(fileSystem)
{}
bool isUpToDate(const SourceEntries &sourceEntries) const
@@ -51,165 +51,101 @@ public:
updateCurrentSourceTimeStamps(sourceEntries);
- return compareEntries(sourceEntries);
+ return compareEntries(sourceEntries) && notReseted(sourceEntries);
}
- void pathsChanged(const FilePathIds &filePathIds)
+ void pathsChanged(const FilePathIds &filePathIds) override
{
- 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));
+ make_iterator([&](SourceTimeStamp &sourceTimeStamp) {
+ sourceTimeStamp.timeStamp = m_fileSystem.lastModified(
+ sourceTimeStamp.sourceId);
+ }));
+ }
+
+ void reset(const FilePathIds &filePathIds)
+ {
+ FilePathIds newResetFilePathIds;
+ newResetFilePathIds.reserve(newResetFilePathIds.size() + m_resetFilePathIds.size());
+
+ std::set_union(m_resetFilePathIds.begin(),
+ m_resetFilePathIds.end(),
+ filePathIds.begin(),
+ filePathIds.end(),
+ std::back_inserter(newResetFilePathIds));
- for (SourceTimeStamp &sourceTimeStamp : timeStampsToUpdate) {
- sourceTimeStamp.timeStamp = m_getModifiedTime(
- m_filePathCache.filePath(sourceTimeStamp.sourceId));
- }
+ m_resetFilePathIds = std::move(newResetFilePathIds);
}
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{});
+ return set_intersection_compare(
+ m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end(),
+ sourceEntries.begin(),
+ sourceEntries.end(),
+ [](auto first, auto second) { return second.timeStamp > first.timeStamp; },
+ [](auto first, auto second) { return first.sourceId < second.sourceId; });
}
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;
+ m_currentSourceTimeStamps = std::move(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;
- }
- };
+ SourceTimeStamps newTimeStamps;
+ newTimeStamps.reserve(sourceEntries.size());
std::set_difference(sourceEntries.begin(),
sourceEntries.end(),
m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(),
- std::back_inserter(newSourceEntries),
- CompareSourceId{});
+ make_iterator([&](const SourceEntry &sourceEntry) {
+ newTimeStamps.emplace_back(sourceEntry.sourceId,
+ m_fileSystem.lastModified(
+ sourceEntry.sourceId));
+ }),
+ [](auto first, auto second) {
+ return first.sourceId < second.sourceId && first.timeStamp > 0;
+ });
- SourceTimeStamps newTimeStamps;
- newTimeStamps.reserve(newSourceEntries.size());
+ return newTimeStamps;
+ }
- std::transform(newSourceEntries.begin(),
- newSourceEntries.end(),
- std::back_inserter(newTimeStamps),
- [](SourceEntry entry) {
- return SourceTimeStamp{entry.sourceId, {}};
- });
+ bool notReseted(const SourceEntries &sourceEntries) const
+ {
+ auto oldSize = m_resetFilePathIds.size();
+ FilePathIds newResetFilePathIds;
+ newResetFilePathIds.reserve(newResetFilePathIds.size());
- return newTimeStamps;
+ std::set_difference(m_resetFilePathIds.begin(),
+ m_resetFilePathIds.end(),
+ sourceEntries.begin(),
+ sourceEntries.end(),
+ std::back_inserter(newResetFilePathIds));
+
+ m_resetFilePathIds = std::move(newResetFilePathIds);
+
+ return oldSize == m_resetFilePathIds.size();
}
private:
mutable SourceTimeStamps m_currentSourceTimeStamps;
- GetModifiedTime &m_getModifiedTime;
- FilePathCachingInterface &m_filePathCache;
+ mutable FilePathIds m_resetFilePathIds;
+ FileSystemInterface &m_fileSystem;
};
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/modifiedtimecheckerinterface.h b/src/libs/clangsupport/modifiedtimecheckerinterface.h
index a0e79b0701..b48c38869e 100644
--- a/src/libs/clangsupport/modifiedtimecheckerinterface.h
+++ b/src/libs/clangsupport/modifiedtimecheckerinterface.h
@@ -38,6 +38,7 @@ public:
ModifiedTimeCheckerInterface &operator=(const ModifiedTimeCheckerInterface &) = delete;
virtual bool isUpToDate(const SourceEntries &sourceEntries) const = 0;
+ virtual void pathsChanged(const FilePathIds &filePathIds) = 0;
protected:
~ModifiedTimeCheckerInterface() = default;
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
index a7058d3204..6042264a5d 100644
--- a/src/libs/clangsupport/refactoringdatabaseinitializer.h
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -144,11 +144,11 @@ public:
table.setName("projectPartsFiles");
const Sqlite::Column &projectPartIdColumn = table.addColumn("projectPartId", Sqlite::ColumnType::Integer);
const Sqlite::Column &sourceIdColumn = table.addColumn("sourceId", Sqlite::ColumnType::Integer);
- table.addColumn("sourceType", Sqlite::ColumnType::Integer);
+ const Sqlite::Column &sourceType = table.addColumn("sourceType", Sqlite::ColumnType::Integer);
table.addColumn("pchCreationTimeStamp", Sqlite::ColumnType::Integer);
table.addColumn("hasMissingIncludes", Sqlite::ColumnType::Integer);
table.addUniqueIndex({sourceIdColumn, projectPartIdColumn});
- table.addIndex({projectPartIdColumn});
+ table.addIndex({projectPartIdColumn, sourceType});
table.initialize(database);
}
diff --git a/src/libs/clangsupport/set_algorithm.h b/src/libs/clangsupport/set_algorithm.h
new file mode 100644
index 0000000000..39bd3a2055
--- /dev/null
+++ b/src/libs/clangsupport/set_algorithm.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** 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 <algorithm>
+
+namespace ClangBackEnd {
+
+template<class Callable>
+class function_output_iterator
+{
+public:
+ typedef std::output_iterator_tag iterator_category;
+ typedef void value_type;
+ typedef void difference_type;
+ typedef void pointer;
+ typedef void reference;
+
+ explicit function_output_iterator() {}
+
+ explicit function_output_iterator(const Callable &callable)
+ : m_callable(&callable)
+ {}
+
+ function_output_iterator &operator=(const function_output_iterator &iterator)
+ {
+ m_callable = iterator.m_callable;
+
+ return *this;
+ }
+
+ struct helper
+ {
+ helper(const Callable *callable)
+ : m_callable(callable)
+ {}
+ template<class T>
+ helper &operator=(T &&value)
+ {
+ (*m_callable)(std::forward<T>(value));
+ return *this;
+ }
+ const Callable *m_callable;
+ };
+
+ helper operator*() { return helper(m_callable); }
+ function_output_iterator &operator++() { return *this; }
+ function_output_iterator &operator++(int) { return *this; }
+
+private:
+ const Callable *m_callable;
+};
+
+template<typename Callable>
+function_output_iterator<Callable> make_iterator(const Callable &callable)
+{
+ return function_output_iterator<Callable>(callable);
+}
+
+template<class InputIt1, class InputIt2, class Callable, class Compare>
+bool set_intersection_compare(
+ InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp)
+{
+ while (first1 != last1 && first2 != last2) {
+ if (comp(*first1, *first2)) {
+ ++first1;
+ } else {
+ if (!comp(*first2, *first1)) {
+ if (call(*first2, *first1++))
+ return false;
+ }
+ ++first2;
+ }
+ }
+
+ return true;
+}
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/sourceentry.h b/src/libs/clangsupport/sourceentry.h
index c593f1fcd3..5e8769d14f 100644
--- a/src/libs/clangsupport/sourceentry.h
+++ b/src/libs/clangsupport/sourceentry.h
@@ -131,6 +131,10 @@ public:
return first.sourceId < second.sourceId;
}
+ friend bool operator<(SourceEntry first, FilePathId second) { return first.sourceId < second; }
+
+ friend bool operator<(FilePathId first, SourceEntry second) { return first < second.sourceId; }
+
friend bool operator==(SourceEntry first, SourceEntry second)
{
return first.sourceId == second.sourceId && first.sourceType == second.sourceType
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/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index deb95ea1d3..e5243830cd 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -1676,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/utils/smallstringview.h b/src/libs/utils/smallstringview.h
index 6052ff8777..911ba2eafd 100644
--- a/src/libs/utils/smallstringview.h
+++ b/src/libs/utils/smallstringview.h
@@ -179,6 +179,10 @@ public:
return m_pointer[0] == characterToSearch;
}
+ char back() const { return m_pointer[m_size - 1]; }
+
+ char operator[](std::size_t index) { return m_pointer[index]; }
+
private:
const char *m_pointer = "";
size_type m_size = 0;
diff --git a/src/plugins/autotest/autotestunittests.cpp b/src/plugins/autotest/autotestunittests.cpp
index eeeeb599de..614a61a6c2 100644
--- a/src/plugins/autotest/autotestunittests.cpp
+++ b/src/plugins/autotest/autotestunittests.cpp
@@ -77,8 +77,9 @@ void AutoTestUnitTests::initTestCase()
if (!qgetenv("BOOST_INCLUDE_DIR").isEmpty()) {
m_checkBoost = true;
} else {
- if (QFileInfo::exists("/usr/include/boost/version.hpp")
- || QFileInfo::exists("/usr/local/include/boost/version.hpp")) {
+ if (Utils::HostOsInfo::isLinuxHost()
+ && (QFileInfo::exists("/usr/include/boost/version.hpp")
+ || QFileInfo::exists("/usr/local/include/boost/version.hpp"))) {
qDebug() << "Found boost at system level - will run boost parser test.";
m_checkBoost = true;
}
diff --git a/src/plugins/autotest/boost/boosttestoutputreader.h b/src/plugins/autotest/boost/boosttestoutputreader.h
index e16c1fb996..91c38cb62f 100644
--- a/src/plugins/autotest/boost/boosttestoutputreader.h
+++ b/src/plugins/autotest/boost/boosttestoutputreader.h
@@ -37,6 +37,7 @@ enum class ReportLevel;
class BoostTestOutputReader : public TestOutputReader
{
+ Q_OBJECT
public:
BoostTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
QProcess *testApplication, const QString &buildDirectory,
diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp
index f18bcdaa8b..ad70d78b16 100644
--- a/src/plugins/baremetal/iarewtoolchain.cpp
+++ b/src/plugins/baremetal/iarewtoolchain.cpp
@@ -411,9 +411,9 @@ QList<ToolChain *> IarToolChainFactory::autoDetect(const QList<ToolChain *> &alr
QString registryKey;
QString subExePath;
} knowToolchains[] = {
- {"EWARM", "\\arm\\bin\\iccarm.exe"},
- {"EWAVR", "\\avr\\bin\\iccavr.exe"},
- {"EW8051", "\\8051\\bin\\icc8051.exe"},
+ {{"EWARM"}, {"\\arm\\bin\\iccarm.exe"}},
+ {{"EWAVR"}, {"\\avr\\bin\\iccavr.exe"}},
+ {{"EW8051"}, {"\\8051\\bin\\icc8051.exe"}},
};
QSettings registry(kRegistryNode, QSettings::NativeFormat);
diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
index c8f7d9f7d1..403433aec6 100644
--- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
+++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
@@ -144,7 +144,7 @@ void ClangCodeModelPlugin::createCompilationDBButton()
message = tr("Clang compilation database generated at \"%1\".")
.arg(QDir::toNativeSeparators(result.filePath));
} else {
- message = tr("Generating clang compilation database failed: %1").arg(result.error);
+ message = tr("Generating Clang compilation database failed: %1").arg(result.error);
}
Core::MessageManager::write(message, Core::MessageManager::Flash);
m_generateCompilationDBAction->setEnabled(
diff --git a/src/plugins/clangtools/clangselectablefilesdialog.cpp b/src/plugins/clangtools/clangselectablefilesdialog.cpp
index e48679aa05..c6ad76ff0a 100644
--- a/src/plugins/clangtools/clangselectablefilesdialog.cpp
+++ b/src/plugins/clangtools/clangselectablefilesdialog.cpp
@@ -295,6 +295,7 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
CppTools::ClangDiagnosticConfigsSelectionWidget *diagnosticConfigsSelectionWidget
= m_ui->clangToolsBasicSettings->ui()->clangDiagnosticConfigsSelectionWidget;
QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis;
+ buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
ClangToolsProjectSettings *settings = ClangToolsProjectSettingsManager::getSettings(m_project);
m_customDiagnosticConfig = diagnosticConfiguration(settings);
@@ -337,6 +338,8 @@ SelectableFilesDialog::SelectableFilesDialog(const ProjectInfo &projectInfo,
m_customDiagnosticConfig = currentConfigId;
});
connect(buildBeforeAnalysis, &QCheckBox::toggled, [this](bool checked) {
+ if (!checked)
+ showHintAboutBuildBeforeAnalysis();
if (m_ui->globalOrCustom->currentIndex() == CustomSettings)
m_buildBeforeAnalysis = checked;
});
diff --git a/src/plugins/clangtools/clangtoolruncontrol.cpp b/src/plugins/clangtools/clangtoolruncontrol.cpp
index b1572b0010..0c2ca841e6 100644
--- a/src/plugins/clangtools/clangtoolruncontrol.cpp
+++ b/src/plugins/clangtools/clangtoolruncontrol.cpp
@@ -477,6 +477,16 @@ void ClangToolRunControl::finalize()
if (m_filesNotAnalyzed != 0) {
QString msg = tr("%1: Not all files could be analyzed.").arg(toolName);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
+ if (m_target && !m_target->activeBuildConfiguration()->buildDirectory().exists()
+ && !ClangToolsProjectSettingsManager::getSettings(m_target->project())
+ ->buildBeforeAnalysis()) {
+ msg = tr("%1: You might need to build the project to generate or update source "
+ "files. To build automatically, enable \"Build the project before starting "
+ "analysis\".")
+ .arg(toolName);
+ TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
+ }
+
TaskHub::requestPopup();
}
diff --git a/src/plugins/clangtools/clangtoolsconfigwidget.cpp b/src/plugins/clangtools/clangtoolsconfigwidget.cpp
index ad966ab518..b634875f97 100644
--- a/src/plugins/clangtools/clangtoolsconfigwidget.cpp
+++ b/src/plugins/clangtools/clangtoolsconfigwidget.cpp
@@ -56,9 +56,12 @@ ClangToolsConfigWidget::ClangToolsConfigWidget(
[settings](int count) { settings->setSimultaneousProcesses(count); });
QCheckBox *buildBeforeAnalysis = m_ui->clangToolsBasicSettings->ui()->buildBeforeAnalysis;
+ buildBeforeAnalysis->setToolTip(hintAboutBuildBeforeAnalysis());
buildBeforeAnalysis->setCheckState(settings->savedBuildBeforeAnalysis()
? Qt::Checked : Qt::Unchecked);
connect(buildBeforeAnalysis, &QCheckBox::toggled, [settings](bool checked) {
+ if (!checked)
+ showHintAboutBuildBeforeAnalysis();
settings->setBuildBeforeAnalysis(checked);
});
diff --git a/src/plugins/clangtools/clangtoolsprojectsettings.cpp b/src/plugins/clangtools/clangtoolsprojectsettings.cpp
index bc8a3cabb6..55573c8ee6 100644
--- a/src/plugins/clangtools/clangtoolsprojectsettings.cpp
+++ b/src/plugins/clangtools/clangtoolsprojectsettings.cpp
@@ -87,7 +87,9 @@ void ClangToolsProjectSettings::load()
m_useGlobalSettings = useGlobalVariant.isValid() ? useGlobalVariant.toBool() : true;
m_diagnosticConfig = Core::Id::fromSetting(
m_project->namedSettings(SETTINGS_KEY_DIAGNOSTIC_CONFIG));
- m_buildBeforeAnalysis = m_project->namedSettings(SETTINGS_KEY_BUILD_BEFORE_ANALYSIS).toBool();
+
+ const QVariant value = m_project->namedSettings(SETTINGS_KEY_BUILD_BEFORE_ANALYSIS);
+ m_buildBeforeAnalysis = value.isValid() ? value.toBool() : true;
auto toFileName = [](const QString &s) { return Utils::FilePath::fromString(s); };
diff --git a/src/plugins/clangtools/clangtoolsutils.cpp b/src/plugins/clangtools/clangtoolsutils.cpp
index 3e811500ac..173d97e31d 100644
--- a/src/plugins/clangtools/clangtoolsutils.cpp
+++ b/src/plugins/clangtools/clangtoolsutils.cpp
@@ -25,6 +25,7 @@
#include "clangtoolsutils.h"
+#include "clangtool.h"
#include "clangtoolsdiagnostic.h"
#include "clangtoolssettings.h"
@@ -32,8 +33,9 @@
#include <projectexplorer/projectexplorerconstants.h>
-#include <utils/hostosinfo.h>
+#include <utils/checkablemessagebox.h>
#include <utils/environment.h>
+#include <utils/hostosinfo.h>
#include <utils/synchronousprocess.h>
#include <QCoreApplication>
@@ -49,5 +51,24 @@ QString createFullLocationString(const Debugger::DiagnosticLocation &location)
+ QLatin1Char(':') + QString::number(location.column);
}
+QString hintAboutBuildBeforeAnalysis()
+{
+ return ClangTool::tr(
+ "In general, the project should be built before starting the analysis to ensure that the "
+ "code to analyze is valid.<br/><br/>"
+ "Building the project might also run code generators that update the source files as "
+ "necessary.");
+}
+
+void showHintAboutBuildBeforeAnalysis()
+{
+ Utils::CheckableMessageBox::doNotShowAgainInformation(
+ Core::ICore::dialogParent(),
+ ClangTool::tr("Info About Build the Project Before Analysis"),
+ hintAboutBuildBeforeAnalysis(),
+ Core::ICore::settings(),
+ "ClangToolsDisablingBuildBeforeAnalysisHint");
+}
+
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/clangtools/clangtoolsutils.h b/src/plugins/clangtools/clangtoolsutils.h
index 6d3a7a90ca..05acb953c5 100644
--- a/src/plugins/clangtools/clangtoolsutils.h
+++ b/src/plugins/clangtools/clangtoolsutils.h
@@ -41,5 +41,8 @@ namespace Internal {
QString createFullLocationString(const Debugger::DiagnosticLocation &location);
+QString hintAboutBuildBeforeAnalysis();
+void showHintAboutBuildBeforeAnalysis();
+
} // namespace Internal
} // namespace ClangTools
diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp
index 813d12739d..f1073e6bb2 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.cpp
+++ b/src/plugins/coreplugin/editormanager/editormanager.cpp
@@ -2429,12 +2429,12 @@ void EditorManager::closeOtherDocuments(IDocument *document)
closeDocuments(documentsToClose, true);
}
-void EditorManager::closeAllDocuments()
+bool EditorManager::closeAllDocuments()
{
// Only close the files that aren't pinned.
const QList<DocumentModel::Entry *> entriesToClose
= Utils::filtered(DocumentModel::entries(), Utils::equal(&DocumentModel::Entry::pinned, false));
- EditorManager::closeDocuments(entriesToClose);
+ return EditorManager::closeDocuments(entriesToClose);
}
// SLOT connected to action
@@ -2631,7 +2631,7 @@ void EditorManager::closeDocument(DocumentModel::Entry *entry)
closeDocuments({entry->document});
}
-void EditorManager::closeDocuments(const QList<DocumentModel::Entry *> &entries)
+bool EditorManager::closeDocuments(const QList<DocumentModel::Entry *> &entries)
{
QList<IDocument *> documentsToClose;
for (DocumentModel::Entry *entry : entries) {
@@ -2642,7 +2642,7 @@ void EditorManager::closeDocuments(const QList<DocumentModel::Entry *> &entries)
else
documentsToClose << entry->document;
}
- closeDocuments(documentsToClose);
+ return closeDocuments(documentsToClose);
}
bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool askAboutModifiedEditors)
diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h
index 41429aedb1..5be379ceb2 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.h
+++ b/src/plugins/coreplugin/editormanager/editormanager.h
@@ -128,9 +128,9 @@ public:
static bool closeDocument(IDocument *document, bool askAboutModifiedEditors = true);
static bool closeDocuments(const QList<IDocument *> &documents, bool askAboutModifiedEditors = true);
static void closeDocument(DocumentModel::Entry *entry);
- static void closeDocuments(const QList<DocumentModel::Entry *> &entries);
+ static bool closeDocuments(const QList<DocumentModel::Entry *> &entries);
static void closeOtherDocuments(IDocument *document);
- static void closeAllDocuments();
+ static bool closeAllDocuments();
static void addCurrentPositionToNavigationHistory(const QByteArray &saveState = QByteArray());
static void cutForwardNavigationHistory();
diff --git a/src/plugins/coreplugin/idocument.cpp b/src/plugins/coreplugin/idocument.cpp
index 8fde404064..aab9845f1a 100644
--- a/src/plugins/coreplugin/idocument.cpp
+++ b/src/plugins/coreplugin/idocument.cpp
@@ -79,7 +79,6 @@ public:
bool hasWriteWarning = false;
bool restored = false;
bool isSuspendAllowed = false;
- bool pinned = false;
};
} // namespace Internal
diff --git a/src/plugins/coreplugin/ioutputpane.h b/src/plugins/coreplugin/ioutputpane.h
index d219e2aeff..b7800a65c8 100644
--- a/src/plugins/coreplugin/ioutputpane.h
+++ b/src/plugins/coreplugin/ioutputpane.h
@@ -41,6 +41,8 @@ class QWidget;
QT_END_NAMESPACE
namespace Core {
+class CommandButton;
+class IContext;
class CORE_EXPORT IOutputPane : public QObject
{
@@ -93,6 +95,7 @@ signals:
void setBadgeNumber(int number);
void zoomIn(int range);
void zoomOut(int range);
+ void resetZoom();
void wheelZoomEnabledChanged(bool enabled);
void fontChanged(const QFont &font);
@@ -103,7 +106,7 @@ protected:
Qt::CaseSensitivity filterCaseSensitivity() const { return m_filterCaseSensitivity; }
void setFilteringEnabled(bool enable);
QWidget *filterWidget() const { return m_filterOutputLineEdit; }
-
+ void setupContext(const char *context, QWidget *widget);
void setZoomButtonsEnabled(bool enabled);
private:
@@ -115,11 +118,12 @@ private:
Id filterRegexpActionId() const;
Id filterCaseSensitivityActionId() const;
- QToolButton * const m_zoomInButton = nullptr;
- QToolButton * const m_zoomOutButton = nullptr;
+ Core::CommandButton * const m_zoomInButton;
+ Core::CommandButton * const m_zoomOutButton;
QAction *m_filterActionRegexp = nullptr;
QAction *m_filterActionCaseSensitive = nullptr;
Utils::FancyLineEdit *m_filterOutputLineEdit = nullptr;
+ IContext *m_context = nullptr;
bool m_filterRegexp = false;
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
};
diff --git a/src/plugins/coreplugin/messageoutputwindow.cpp b/src/plugins/coreplugin/messageoutputwindow.cpp
index 7aabaefbbc..c7c752e155 100644
--- a/src/plugins/coreplugin/messageoutputwindow.cpp
+++ b/src/plugins/coreplugin/messageoutputwindow.cpp
@@ -56,6 +56,7 @@ MessageOutputWindow::MessageOutputWindow()
connect(this, &IOutputPane::zoomIn, m_widget, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, m_widget, &Core::OutputWindow::zoomOut);
+ connect(this, &IOutputPane::resetZoom, m_widget, &Core::OutputWindow::resetZoom);
connect(this, &IOutputPane::fontChanged, m_widget, &OutputWindow::setBaseFont);
connect(this, &IOutputPane::wheelZoomEnabledChanged, m_widget, &OutputWindow::setWheelZoomEnabled);
@@ -65,6 +66,7 @@ MessageOutputWindow::MessageOutputWindow()
setupFilterUi("MessageOutputPane.Filter");
setFilteringEnabled(true);
+ setupContext(Constants::C_GENERAL_OUTPUT_PANE, m_widget);
}
MessageOutputWindow::~MessageOutputWindow()
diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp
index 951fed419b..7cf2ec2c90 100644
--- a/src/plugins/coreplugin/outputpanemanager.cpp
+++ b/src/plugins/coreplugin/outputpanemanager.cpp
@@ -35,6 +35,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/actionmanager/commandbutton.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/find/optionspopup.h>
@@ -90,24 +91,27 @@ static bool g_managerConstructed = false; // For debugging reasons.
IOutputPane::IOutputPane(QObject *parent)
: QObject(parent),
- m_zoomInButton(new QToolButton),
- m_zoomOutButton(new QToolButton)
+ m_zoomInButton(new Core::CommandButton),
+ m_zoomOutButton(new Core::CommandButton)
{
// We need all pages first. Ignore latecomers and shout.
QTC_ASSERT(!g_managerConstructed, return);
g_outputPanes.append(OutputPaneData(this));
- m_zoomInButton->setToolTip(tr("Increase Font Size"));
m_zoomInButton->setIcon(Utils::Icons::PLUS_TOOLBAR.icon());
+ m_zoomInButton->setCommandId(Constants::ZOOM_IN);
connect(m_zoomInButton, &QToolButton::clicked, this, [this] { emit zoomIn(1); });
- m_zoomOutButton->setToolTip(tr("Decrease Font Size"));
m_zoomOutButton->setIcon(Utils::Icons::MINUS.icon());
+ m_zoomOutButton->setCommandId(Constants::ZOOM_OUT);
connect(m_zoomOutButton, &QToolButton::clicked, this, [this] { emit zoomOut(1); });
}
IOutputPane::~IOutputPane()
{
+ if (m_context)
+ ICore::removeContextObject(m_context);
+
const int i = Utils::indexOf(g_outputPanes, Utils::equal(&OutputPaneData::pane, this));
QTC_ASSERT(i >= 0, return);
delete g_outputPanes.at(i).button;
@@ -174,6 +178,26 @@ void IOutputPane::setFilteringEnabled(bool enable)
m_filterOutputLineEdit->setEnabled(enable);
}
+void IOutputPane::setupContext(const char *context, QWidget *widget)
+{
+ QTC_ASSERT(!m_context, return);
+ m_context = new IContext(this);
+ m_context->setContext(Context(context));
+ m_context->setWidget(widget);
+ ICore::addContextObject(m_context);
+
+ const auto zoomInAction = new QAction(this);
+ Core::ActionManager::registerAction(zoomInAction, Constants::ZOOM_IN, m_context->context());
+ connect(zoomInAction, &QAction::triggered, this, [this] { emit zoomIn(1); });
+ const auto zoomOutAction = new QAction(this);
+ Core::ActionManager::registerAction(zoomOutAction, Constants::ZOOM_OUT, m_context->context());
+ connect(zoomOutAction, &QAction::triggered, this, [this] { emit zoomOut(1); });
+ const auto resetZoomAction = new QAction(this);
+ Core::ActionManager::registerAction(resetZoomAction, Constants::ZOOM_RESET,
+ m_context->context());
+ connect(resetZoomAction, &QAction::triggered, this, &IOutputPane::resetZoom);
+}
+
void IOutputPane::setZoomButtonsEnabled(bool enabled)
{
m_zoomInButton->setEnabled(enabled);
diff --git a/src/plugins/coreplugin/outputwindow.h b/src/plugins/coreplugin/outputwindow.h
index 88692d5ab7..204a1106a9 100644
--- a/src/plugins/coreplugin/outputwindow.h
+++ b/src/plugins/coreplugin/outputwindow.h
@@ -75,6 +75,7 @@ public:
void setBaseFont(const QFont &newFont);
float fontZoom() const;
void setFontZoom(float zoom);
+ void resetZoom() { setFontZoom(0); }
void setWheelZoomEnabled(bool enabled);
void updateFilterProperties(const QString &filterText, Qt::CaseSensitivity caseSensitivity, bool regexp);
diff --git a/src/plugins/cppeditor/cppparsecontext.cpp b/src/plugins/cppeditor/cppparsecontext.cpp
index 7c98fbba8f..521cc49328 100644
--- a/src/plugins/cppeditor/cppparsecontext.cpp
+++ b/src/plugins/cppeditor/cppparsecontext.cpp
@@ -111,14 +111,16 @@ QString ParseContextModel::currentId() const
return m_projectParts[m_currentIndex]->id();
}
-int ParseContextModel::rowCount(const QModelIndex &) const
+int ParseContextModel::rowCount(const QModelIndex &parent) const
{
+ if (parent.isValid())
+ return 0;
return m_projectParts.size();
}
QVariant ParseContextModel::data(const QModelIndex &index, int role) const
{
- if (m_projectParts.isEmpty())
+ if (!index.isValid() || index.row() < 0 || index.row() >= m_projectParts.size())
return QVariant();
const int row = index.row();
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index 7d12b33f05..3d74ad8d32 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -709,6 +709,7 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
qgetenv("QTC_CLANG_CMD_OPTIONS_BLACKLIST"))
.split(';', QString::SkipEmptyParts);
+ const Core::Id &toolChain = m_projectPart.toolchainType;
bool containsDriverMode = false;
bool skipNext = false;
for (const QString &option : m_projectPart.compilerFlags) {
@@ -720,6 +721,13 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
if (userBlackList.contains(option))
continue;
+ // TODO: Make it possible that the clang binary/driver ignores unknown options,
+ // as it is done for libclang/clangd (not checking for OPT_UNKNOWN).
+ if (toolChain == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) {
+ if (option == "-fkeep-inline-dllexport" || option == "-fno-keep-inline-dllexport")
+ continue;
+ }
+
// Ignore warning flags as these interfere with our user-configured diagnostics.
// Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows.
if (m_useBuildSystemWarnings == UseBuildSystemWarnings::No
@@ -755,7 +763,7 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
// Check whether a language version is already used.
QString theOption = option;
- if (theOption.startsWith("-std=")) {
+ if (theOption.startsWith("-std=") || theOption.startsWith("--std=")) {
m_compilerFlags.isLanguageVersionSpecified = true;
theOption.replace("=c18", "=c17");
theOption.replace("=gnu18", "=gnu17");
@@ -772,7 +780,6 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
m_compilerFlags.flags.append(theOption);
}
- const Core::Id &toolChain = m_projectPart.toolchainType;
if (!containsDriverMode
&& (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|| toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)) {
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 26c075dfe1..79f779a295 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -1759,9 +1759,9 @@ void DebuggerPlugin::attachExternalApplication(RunControl *rc)
ProcessHandle pid = rc->applicationProcessHandle();
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
runControl->setTarget(rc->target());
+ runControl->setDisplayName(tr("Process %1").arg(pid.pid()));
auto debugger = new DebuggerRunTool(runControl);
debugger->setAttachPid(pid);
- debugger->setRunControlName(tr("Process %1").arg(pid.pid()));
debugger->setStartMode(AttachExternal);
debugger->setCloseMode(DetachAtClose);
debugger->startRunControl();
diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp
index 50465770d9..a1b8db2169 100644
--- a/src/plugins/languageclient/languageclientsettings.cpp
+++ b/src/plugins/languageclient/languageclientsettings.cpp
@@ -605,7 +605,7 @@ BaseSettingsWidget::BaseSettingsWidget(const BaseSettings *settings, QWidget *pa
mainLayout->addLayout(mimeLayout, row, 1);
m_filePattern->setPlaceholderText(tr("File pattern"));
mainLayout->addWidget(m_filePattern, ++row, 1);
- mainLayout->addWidget(new QLabel(tr("Startup Behavior:")), ++row, 0);
+ mainLayout->addWidget(new QLabel(tr("Startup behavior:")), ++row, 0);
for (int behavior = 0; behavior < BaseSettings::LastSentinel ; ++behavior)
m_startupBehavior->addItem(startupBehaviorString(BaseSettings::StartBehavior(behavior)));
m_startupBehavior->setCurrentIndex(settings->m_startBehavior);
@@ -650,8 +650,8 @@ QString BaseSettingsWidget::name() const
LanguageFilter BaseSettingsWidget::filter() const
{
- return {m_mimeTypes->text().split(filterSeparator),
- m_filePattern->text().split(filterSeparator)};
+ return {m_mimeTypes->text().split(filterSeparator, QString::SkipEmptyParts),
+ m_filePattern->text().split(filterSeparator, QString::SkipEmptyParts)};
}
BaseSettings::StartBehavior BaseSettingsWidget::startupBehavior() const
@@ -784,10 +784,10 @@ QString StdIOSettingsWidget::arguments() const
bool LanguageFilter::isSupported(const Utils::FilePath &filePath, const QString &mimeType) const
{
- if (mimeTypes.isEmpty() && filePattern.isEmpty())
- return true;
if (mimeTypes.contains(mimeType))
return true;
+ if (filePattern.isEmpty() && filePath.isEmpty())
+ return mimeTypes.isEmpty();
auto regexps = Utils::transform(filePattern, [](const QString &pattern){
return QRegExp(pattern, Utils::HostOsInfo::fileNameCaseSensitivity(), QRegExp::Wildcard);
});
diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp
index 5af097a9ec..bb71f925da 100644
--- a/src/plugins/perfprofiler/perfprofilertool.cpp
+++ b/src/plugins/perfprofiler/perfprofilertool.cpp
@@ -157,6 +157,9 @@ PerfProfilerTool::PerfProfilerTool()
tracePointsAction->setEnabled(m_startAction->isEnabled());
});
+ connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
+ this, &PerfProfilerTool::updateRunActions);
+
m_recordButton = new QToolButton;
m_clearButton = new QToolButton;
m_filterButton = new QToolButton;
@@ -341,9 +344,6 @@ void PerfProfilerTool::createViews()
menu1->exec(m_flameGraphView->mapToGlobal(pos));
});
- connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::updateRunActions,
- this, &PerfProfilerTool::updateRunActions);
-
m_perspective.addToolBarAction(m_startAction);
m_perspective.addToolBarAction(m_stopAction);
m_perspective.addToolBarWidget(m_recordButton);
diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp
index 7631f26cac..df9fd503ba 100644
--- a/src/plugins/projectexplorer/appoutputpane.cpp
+++ b/src/plugins/projectexplorer/appoutputpane.cpp
@@ -213,6 +213,7 @@ AppOutputPane::AppOutputPane() :
connect(this, &Core::IOutputPane::zoomIn, this, &AppOutputPane::zoomIn);
connect(this, &Core::IOutputPane::zoomOut, this, &AppOutputPane::zoomOut);
+ connect(this, &IOutputPane::resetZoom, this, &AppOutputPane::resetZoom);
m_settingsButton->setToolTip(tr("Open Settings Page"));
m_settingsButton->setIcon(Utils::Icons::SETTINGS_TOOLBAR.icon());
@@ -247,6 +248,7 @@ AppOutputPane::AppOutputPane() :
setupFilterUi("AppOutputPane.Filter");
setFilteringEnabled(false);
setZoomButtonsEnabled(false);
+ setupContext("Core.AppOutputPane", m_mainWidget);
}
AppOutputPane::~AppOutputPane()
@@ -662,6 +664,12 @@ void AppOutputPane::zoomOut(int range)
tab.window->zoomOut(range);
}
+void AppOutputPane::resetZoom()
+{
+ for (const RunControlTab &tab : qAsConst(m_runControlTabs))
+ tab.window->resetZoom();
+}
+
void AppOutputPane::enableButtons(const RunControl *rc)
{
if (rc) {
diff --git a/src/plugins/projectexplorer/appoutputpane.h b/src/plugins/projectexplorer/appoutputpane.h
index 5fc88219fc..6d7936042e 100644
--- a/src/plugins/projectexplorer/appoutputpane.h
+++ b/src/plugins/projectexplorer/appoutputpane.h
@@ -120,6 +120,7 @@ private:
void zoomIn(int range);
void zoomOut(int range);
+ void resetZoom();
void enableButtons(const RunControl *rc);
diff --git a/src/plugins/projectexplorer/compileoutputwindow.cpp b/src/plugins/projectexplorer/compileoutputwindow.cpp
index 91cc2fb22c..d92bcc4bbe 100644
--- a/src/plugins/projectexplorer/compileoutputwindow.cpp
+++ b/src/plugins/projectexplorer/compileoutputwindow.cpp
@@ -177,6 +177,7 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
connect(this, &IOutputPane::zoomIn, m_outputWindow, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, m_outputWindow, &Core::OutputWindow::zoomOut);
+ connect(this, &IOutputPane::resetZoom, m_outputWindow, &Core::OutputWindow::resetZoom);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::fontSettingsChanged,
this, updateFontSettings);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,
@@ -194,6 +195,7 @@ CompileOutputWindow::CompileOutputWindow(QAction *cancelBuildAction) :
m_handler = new ShowOutputTaskHandler(this);
ExtensionSystem::PluginManager::addObject(m_handler);
+ setupContext(C_COMPILE_OUTPUT, m_outputWindow);
loadSettings();
updateFromSettings();
}
diff --git a/src/plugins/projectexplorer/environmentwidget.cpp b/src/plugins/projectexplorer/environmentwidget.cpp
index 673aa61cfc..43758e0a36 100644
--- a/src/plugins/projectexplorer/environmentwidget.cpp
+++ b/src/plugins/projectexplorer/environmentwidget.cpp
@@ -381,7 +381,7 @@ void EnvironmentWidget::amendPathList(const PathListModifier &modifier)
{
const QString varName = d->m_model->indexToVariable(d->m_environmentView->currentIndex());
const QString dir = QDir::toNativeSeparators(
- QFileDialog::getExistingDirectory(this, tr("Choose a directory")));
+ QFileDialog::getExistingDirectory(this, tr("Choose Directory")));
if (dir.isEmpty())
return;
QModelIndex index = d->m_model->variableToIndex(varName);
diff --git a/src/plugins/projectexplorer/filterkitaspectsdialog.cpp b/src/plugins/projectexplorer/filterkitaspectsdialog.cpp
index 418ae03564..12bd7ccf13 100644
--- a/src/plugins/projectexplorer/filterkitaspectsdialog.cpp
+++ b/src/plugins/projectexplorer/filterkitaspectsdialog.cpp
@@ -92,7 +92,7 @@ class FilterKitAspectsModel : public TreeModel<TreeItem, FilterTreeItem>
public:
FilterKitAspectsModel(const Kit *kit, QObject *parent) : TreeModel(parent)
{
- setHeader({tr("Setting"), tr("Visible")});
+ setHeader({FilterKitAspectsDialog::tr("Setting"), FilterKitAspectsDialog::tr("Visible")});
for (const KitAspect * const aspect : KitManager::kitAspects()) {
if (kit && !aspect->isApplicableToKit(kit))
continue;
diff --git a/src/plugins/projectexplorer/filterkitaspectsdialog.h b/src/plugins/projectexplorer/filterkitaspectsdialog.h
index 441abd658d..f59a58f683 100644
--- a/src/plugins/projectexplorer/filterkitaspectsdialog.h
+++ b/src/plugins/projectexplorer/filterkitaspectsdialog.h
@@ -37,6 +37,7 @@ namespace Internal {
class FilterKitAspectsDialog : public QDialog
{
+ Q_OBJECT
public:
FilterKitAspectsDialog(const Kit *kit, QWidget *parent);
QSet<Core::Id> irrelevantAspects() const;
diff --git a/src/plugins/projectexplorer/importwidget.cpp b/src/plugins/projectexplorer/importwidget.cpp
index eac2c44c94..33db7d48df 100644
--- a/src/plugins/projectexplorer/importwidget.cpp
+++ b/src/plugins/projectexplorer/importwidget.cpp
@@ -63,10 +63,14 @@ ImportWidget::ImportWidget(QWidget *parent) :
connect(importButton, &QAbstractButton::clicked, this, &ImportWidget::handleImportRequest);
connect(m_pathChooser->lineEdit(), &QLineEdit::returnPressed, this, [this] {
if (m_pathChooser->isValid()) {
+ m_ownsReturnKey = true;
handleImportRequest();
// The next return should trigger the "Configure" button.
- QTimer::singleShot(0, this, QOverload<>::of(&QWidget::setFocus));
+ QTimer::singleShot(0, this, [this] {
+ setFocus();
+ m_ownsReturnKey = false;
+ });
}
});
@@ -79,9 +83,9 @@ void ImportWidget::setCurrentDirectory(const Utils::FilePath &dir)
m_pathChooser->setFileName(dir);
}
-bool ImportWidget::lineEditHasFocus() const
+bool ImportWidget::ownsReturnKey() const
{
- return m_pathChooser->lineEdit()->hasFocus();
+ return m_ownsReturnKey;
}
void ImportWidget::handleImportRequest()
diff --git a/src/plugins/projectexplorer/importwidget.h b/src/plugins/projectexplorer/importwidget.h
index 8999bc117d..5c63beecdb 100644
--- a/src/plugins/projectexplorer/importwidget.h
+++ b/src/plugins/projectexplorer/importwidget.h
@@ -44,7 +44,7 @@ public:
void setCurrentDirectory(const Utils::FilePath &dir);
- bool lineEditHasFocus() const;
+ bool ownsReturnKey() const;
signals:
void importFrom(const Utils::FilePath &dir);
@@ -53,6 +53,7 @@ private:
void handleImportRequest();
Utils::PathChooser *m_pathChooser;
+ bool m_ownsReturnKey = false;
};
} // namespace Internal
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp
index 7141148ef8..7684de0795 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizard.cpp
@@ -104,7 +104,7 @@ public:
: QDialog(parent), m_view(new Utils::TreeView(this))
{
setWindowTitle(QCoreApplication::translate("ProjectExplorer::JsonWizard",
- "Choose project file"));
+ "Choose Project File"));
const auto model = new ProjectFilesModel(candidates, this);
m_view->setSelectionMode(Utils::TreeView::ExtendedSelection);
m_view->setSelectionBehavior(Utils::TreeView::SelectRows);
@@ -121,7 +121,7 @@ public:
const auto layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(QCoreApplication::translate("ProjectExplorer::JsonWizard",
"The project contains more than one project file. "
- "Please select the one you would like to use.")));
+ "Select the one you would like to use.")));
layout->addWidget(m_view);
layout->addWidget(buttonBox);
}
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 15f345dc5b..60cd9a6e21 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -1298,6 +1298,7 @@ MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc)
m_mainLayout->removeRow(m_mainLayout->rowCount() - 1);
QHBoxLayout *hLayout = new QHBoxLayout();
+ m_varsBatPathCombo->setObjectName("varsBatCombo");
m_varsBatPathCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
m_varsBatPathCombo->setEditable(true);
for (const MsvcToolChain *tmpTc : g_availableMsvcToolchains) {
@@ -1442,6 +1443,7 @@ ClangClToolChainConfigWidget::ClangClToolChainConfigWidget(ToolChain *tc) :
{
m_mainLayout->removeRow(m_mainLayout->rowCount() - 1);
+ m_varsBatDisplayCombo->setObjectName("varsBatCombo");
m_varsBatDisplayCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
m_mainLayout->addRow(tr("Initialization:"), m_varsBatDisplayCombo);
diff --git a/src/plugins/projectexplorer/parseissuesdialog.cpp b/src/plugins/projectexplorer/parseissuesdialog.cpp
index 5b6015b5a5..7b0d3758e6 100644
--- a/src/plugins/projectexplorer/parseissuesdialog.cpp
+++ b/src/plugins/projectexplorer/parseissuesdialog.cpp
@@ -71,14 +71,14 @@ ParseIssuesDialog::ParseIssuesDialog(QWidget *parent) : QDialog(parent), d(new P
d->clearTasksCheckBox.setText(tr("Clear existing tasks"));
d->clearTasksCheckBox.setChecked(true);
- const auto loadFileButton = new QPushButton(tr("Load from file..."));
+ const auto loadFileButton = new QPushButton(tr("Load from File..."));
connect(loadFileButton, &QPushButton::clicked, this, [this] {
const QString filePath = QFileDialog::getOpenFileName(this, tr("Choose File"));
if (filePath.isEmpty())
return;
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
- QMessageBox::critical(this, tr("Could not open file"),
+ QMessageBox::critical(this, tr("Could Not Open File"),
tr("Could not open file: \"%1\": %2")
.arg(filePath, file.errorString()));
return;
@@ -116,7 +116,7 @@ ParseIssuesDialog::ParseIssuesDialog(QWidget *parent) : QDialog(parent), d(new P
// TODO: Only very few parsers are available from a Kit (basically just the Toolchain one).
// If we introduced factories for IOutputParsers, we could offer the user
// to combine arbitrary parsers here.
- const auto parserGroupBox = new QGroupBox(tr("Parsing options"));
+ const auto parserGroupBox = new QGroupBox(tr("Parsing Options"));
layout->addWidget(parserGroupBox);
const auto parserLayout = new QVBoxLayout(parserGroupBox);
const auto kitChooserWidget = new QWidget;
@@ -153,7 +153,7 @@ void ParseIssuesDialog::accept()
{
std::unique_ptr<IOutputParser> parser(d->kitChooser.currentKit()->createOutputParser());
if (!parser) {
- QMessageBox::critical(this, tr("Cannot parse"), tr("Cannot parse: The chosen kit does "
+ QMessageBox::critical(this, tr("Cannot Parse"), tr("Cannot parse: The chosen kit does "
"not provide an output parser."));
return;
}
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 420d6dad32..f34547cc95 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -667,7 +667,7 @@ void Project::changeRootProjectDirectory()
{
Utils::FilePath rootPath = Utils::FilePath::fromString(
QFileDialog::getExistingDirectory(Core::ICore::dialogParent(),
- tr("Select The Root Directory"),
+ tr("Select the Root Directory"),
rootProjectDirectory().toString(),
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks));
@@ -679,7 +679,7 @@ void Project::changeRootProjectDirectory()
}
/*!
- Returns the common root directory that contains all files which belongs to a project.
+ Returns the common root directory that contains all files which belong to a project.
*/
Utils::FilePath Project::rootProjectDirectory() const
{
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index d5c5fb9ce5..2f029ccedd 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -1780,7 +1780,7 @@ void ProjectExplorerPlugin::unloadProject(Project *project)
void ProjectExplorerPluginPrivate::closeAllProjects()
{
- if (!EditorManager::closeAllEditors())
+ if (!EditorManager::closeAllDocuments())
return; // Action has been cancelled
SessionManager::closeAllProjects();
@@ -1935,15 +1935,15 @@ void ProjectExplorerPluginPrivate::setStartupProject(Project *project)
bool ProjectExplorerPluginPrivate::closeAllFilesInProject(const Project *project)
{
QTC_ASSERT(project, return false);
- QList<IDocument *> openFiles = DocumentModel::openedDocuments();
- Utils::erase(openFiles, [project](const IDocument *doc) {
- return !project->isKnownFile(doc->filePath());
+ QList<DocumentModel::Entry *> openFiles = DocumentModel::entries();
+ Utils::erase(openFiles, [project](const DocumentModel::Entry *entry) {
+ return entry->pinned || !project->isKnownFile(entry->fileName());
});
for (const Project * const otherProject : SessionManager::projects()) {
if (otherProject == project)
continue;
- Utils::erase(openFiles, [otherProject](const IDocument *doc) {
- return otherProject->isKnownFile(doc->filePath());
+ Utils::erase(openFiles, [otherProject](const DocumentModel::Entry *entry) {
+ return otherProject->isKnownFile(entry->fileName());
});
}
return EditorManager::closeDocuments(openFiles);
@@ -3470,7 +3470,7 @@ void ProjectExplorerPluginPrivate::addExistingProjects()
QTC_ASSERT(projectNode, return);
const QString dir = directoryFor(currentNode);
QStringList subProjectFilePaths = QFileDialog::getOpenFileNames(
- ICore::mainWindow(), tr("Please choose a project file"), dir,
+ ICore::mainWindow(), tr("Choose Project File"), dir,
projectNode->subProjectFileNamePatterns().join(";;"));
if (!ProjectTree::hasNode(projectNode))
return;
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index 839f021f2b..08010bb50b 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -457,7 +457,7 @@ public:
: m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)),
m_buttonGroup(new QButtonGroup(this))
{
- setWindowTitle(tr("Please choose a drop action"));
+ setWindowTitle(tr("Choose Drop Action"));
const bool offerFileIo = !defaultTargetDir.isEmpty();
auto * const layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(tr("You just dragged some files from one project node to "
@@ -469,8 +469,8 @@ public:
m_buttonGroup->addButton(moveButton, int(DropAction::Move));
layout->addWidget(moveButton);
if (offerFileIo) {
- copyButton->setText(tr("Copy only the file references"));
- moveButton->setText(tr("Move only the file references"));
+ copyButton->setText(tr("Copy Only File References"));
+ moveButton->setText(tr("Move Only File References"));
auto * const copyWithFilesButton
= new QRadioButton(tr("Copy file references and files"), this);
m_buttonGroup->addButton(copyWithFilesButton, int(DropAction::CopyWithFiles));
@@ -506,8 +506,8 @@ public:
}
});
} else {
- copyButton->setText(tr("Copy the file references"));
- moveButton->setText(tr("Move the file references"));
+ copyButton->setText(tr("Copy File References"));
+ moveButton->setText(tr("Move File References"));
moveButton->setChecked(true);
}
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
diff --git a/src/plugins/projectexplorer/targetsetuppage.cpp b/src/plugins/projectexplorer/targetsetuppage.cpp
index c0dba5c020..0006d7678c 100644
--- a/src/plugins/projectexplorer/targetsetuppage.cpp
+++ b/src/plugins/projectexplorer/targetsetuppage.cpp
@@ -332,7 +332,7 @@ void TargetSetupPage::setProjectImporter(ProjectImporter *importer)
bool TargetSetupPage::importLineEditHasFocus() const
{
- return m_importWidget->lineEditHasFocus();
+ return m_importWidget->ownsReturnKey();
}
void TargetSetupPage::setNoteText(const QString &text)
diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
index 623b20a1a4..95b7c8eb5b 100644
--- a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp
@@ -164,7 +164,7 @@ KitAspect::ItemList QmakeKitAspect::toUserOutput(const Kit *k) const
void QmakeKitAspect::addToMacroExpander(Kit *kit, MacroExpander *expander) const
{
- expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the Kit."),
+ expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the kit."),
[kit]() -> QString {
return QDir::toNativeSeparators(mkspec(kit));
});
diff --git a/src/plugins/qmakeprojectmanager/qmakesettings.cpp b/src/plugins/qmakeprojectmanager/qmakesettings.cpp
index f3c2bf9760..37c0a4ce39 100644
--- a/src/plugins/qmakeprojectmanager/qmakesettings.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakesettings.cpp
@@ -103,7 +103,7 @@ public:
m_warnAgainstUnalignedBuildDirCheckbox.setText(tr("Warn if a project's source and "
"build directories are not at the same level"));
m_warnAgainstUnalignedBuildDirCheckbox.setToolTip(tr("Qmake has subtle bugs that "
- "can trigger if source and build directory are not at the same level."));
+ "can be triggered if source and build directory are not at the same level."));
m_warnAgainstUnalignedBuildDirCheckbox.setChecked(
QmakeSettings::warnAgainstUnalignedBuildDir());
m_alwaysRunQmakeCheckbox.setText(tr("Run qmake on every build"));
diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
index 028d3a21b4..0535a8f52e 100644
--- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
+++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
@@ -165,6 +165,7 @@ const int priorityGenericToolBar = 50;
const int priorityLast = 60;
const char addImagesDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Image Files");
+const char addFontsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Font Files");
} //ComponentCoreConstants
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 6edbacec36..37e1fdfd53 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -1026,6 +1026,13 @@ void DesignerActionManager::createDefaultAddResourceHandler()
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.svg",
ModelNodeOperations::addImageToProject));
+
+ registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addFontsDisplayString,
+ "*.ttf",
+ ModelNodeOperations::addFontToProject));
+ registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addFontsDisplayString,
+ "*.otf",
+ ModelNodeOperations::addFontToProject));
}
void DesignerActionManager::addDesignerAction(ActionInterface *newAction)
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
index 3c31998576..9f880c453b 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp
@@ -966,6 +966,38 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext)
}
+bool addFontToProject(const QStringList &fileNames, const QString &defaultDirectory)
+{
+ QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory);
+
+ if (directory.isEmpty())
+ return true;
+
+ bool allSuccessful = true;
+ for (const QString &fileName : fileNames) {
+ const QString targetFile = directory + "/" + QFileInfo(fileName).fileName();
+ const bool success = QFile::copy(fileName, targetFile);
+
+ auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
+
+ QTC_ASSERT(document, return false);
+
+ if (success) {
+ ProjectExplorer::Node *node = ProjectExplorer::ProjectTree::nodeForFile(document->fileName());
+ if (node) {
+ ProjectExplorer::FolderNode *containingFolder = node->parentFolderNode();
+ if (containingFolder)
+ containingFolder->addFiles(QStringList(targetFile));
+ }
+ } else {
+ allSuccessful = false;
+ }
+ }
+
+ return allSuccessful;
+}
+
+
bool addImageToProject(const QStringList &fileNames, const QString &defaultDirectory)
{
QString directory = AddImagesDialog::getDirectory(fileNames, defaultDirectory);
diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
index e3396a303e..52dfaf6f1d 100644
--- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
+++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h
@@ -73,6 +73,7 @@ void increaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void addTabBarToStackedContainer(const SelectionContext &selectionContext);
bool addImageToProject(const QStringList &fileNames, const QString &directory);
+bool addFontToProject(const QStringList &fileNames, const QString &directory);
} // namespace ModelNodeOperationso
} //QmlDesigner
diff --git a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h
index cfffeeaca4..f686631079 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h
@@ -27,6 +27,7 @@
#include <qmlitemnode.h>
+#include <QDir>
#include <QObject>
#include <QStringList>
#include <QUrl>
diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp
index 4263a1e498..aec85826a2 100644
--- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp
+++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp
@@ -256,6 +256,11 @@ QList<DeployableFile> QnxDeployQtLibrariesDialog::gatherFiles(
if (dirPath.isEmpty())
return result;
+ static const QStringList unusedDirs = {"include", "mkspecs", "cmake", "pkgconfig"};
+ const QString dp = dirPath.endsWith('/') ? dirPath.left(dirPath.size() - 1) : dirPath;
+ if (unusedDirs.contains(dp))
+ return result;
+
QDir dir(dirPath);
QFileInfoList list = dir.entryInfoList(nameFilters,
QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
@@ -265,6 +270,10 @@ QList<DeployableFile> QnxDeployQtLibrariesDialog::gatherFiles(
result.append(gatherFiles(fileInfo.absoluteFilePath(), baseDirPath.isEmpty() ?
dirPath : baseDirPath));
} else {
+ static const QStringList unusedSuffixes = {"cmake", "la", "prl", "a", "pc"};
+ if (unusedSuffixes.contains(fileInfo.suffix()))
+ continue;
+
QString remoteDir;
if (baseDirPath.isEmpty()) {
remoteDir = fullRemoteDirectory() + QLatin1Char('/') +
diff --git a/src/plugins/remotelinux/makeinstallstep.cpp b/src/plugins/remotelinux/makeinstallstep.cpp
index 96c41218e8..8af1a6aebd 100644
--- a/src/plugins/remotelinux/makeinstallstep.cpp
+++ b/src/plugins/remotelinux/makeinstallstep.cpp
@@ -118,13 +118,13 @@ bool MakeInstallStep::init()
}
QDir rootDir(rootDirPath);
if (cleanInstallRoot() && !rootDir.removeRecursively()) {
- emit addTask(Task(Task::Error, tr("The install root '%1' could not be cleaned.")
+ emit addTask(Task(Task::Error, tr("The install root \"%1\" could not be cleaned.")
.arg(installRoot().toUserOutput()),
FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM));
return false;
}
if (!rootDir.exists() && !QDir::root().mkpath(rootDirPath)) {
- emit addTask(Task(Task::Error, tr("The install root '%1' could not be created.")
+ emit addTask(Task(Task::Error, tr("The install root \"%1\" could not be created.")
.arg(installRoot().toUserOutput()),
FilePath(), -1, Constants::TASK_CATEGORY_BUILDSYSTEM));
return false;
diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp
index d1f7dbc1bf..bbeff2a484 100644
--- a/src/plugins/texteditor/highlighter.cpp
+++ b/src/plugins/texteditor/highlighter.cpp
@@ -33,6 +33,7 @@
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <utils/mimetypes/mimedatabase.h>
+#include <utils/qtcassert.h>
#include <DefinitionDownloader>
#include <Format>
@@ -119,6 +120,8 @@ Highlighter::Definition Highlighter::definitionForDocument(const TextDocument *d
Highlighter::Definition Highlighter::definitionForMimeType(const QString &mimeType)
{
+ if (mimeType.isEmpty())
+ return {};
const Definitions definitions = definitionsForMimeType(mimeType);
if (definitions.size() == 1)
return definitions.first();
@@ -140,13 +143,23 @@ Highlighter::Definition Highlighter::definitionForName(const QString &name)
Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument *document)
{
- const Utils::MimeType mimeType = Utils::mimeTypeForName(document->mimeType());
- Definitions definitions;
- if (mimeType.isValid())
- definitions = Highlighter::definitionsForMimeType(mimeType.name());
- if (definitions.isEmpty())
- definitions = Highlighter::definitionsForFileName(document->filePath());
- return definitions;
+ QTC_ASSERT(document, return {});
+ const Utils::MimeType &mimeType = Utils::mimeTypeForName(document->mimeType());
+ if (mimeType.isValid()) {
+ if (mimeType.name() == "text/plain") {
+ // text/plain is the base mime type for all text types so ignore it and try matching the
+ // file name against the pattern and only if no definition can be found for the
+ // file name try matching the mime type
+ const Definitions &fileNameDefinitions = definitionsForFileName(document->filePath());
+ if (!fileNameDefinitions.isEmpty())
+ return fileNameDefinitions;
+ return definitionsForMimeType(mimeType.name());
+ }
+ const Definitions &mimeTypeDefinitions = definitionsForMimeType(mimeType.name());
+ if (!mimeTypeDefinitions.isEmpty())
+ return mimeTypeDefinitions;
+ }
+ return definitionsForFileName(document->filePath());
}
static Highlighter::Definition definitionForSetting(const QString &settingsKey,
@@ -193,6 +206,7 @@ Highlighter::Definitions Highlighter::definitionsForFileName(const Utils::FilePa
void Highlighter::rememberDefintionForDocument(const Highlighter::Definition &definition,
const TextDocument *document)
{
+ QTC_ASSERT(document, return );
if (!definition.isValid())
return;
const QString &mimeType = document->mimeType();
diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp
index 2d7a98457d..6a699c4686 100644
--- a/src/plugins/valgrind/memchecktool.cpp
+++ b/src/plugins/valgrind/memchecktool.cpp
@@ -630,7 +630,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
});
action = new QAction(this);
- action->setText(tr("Valgrind Memory Analyzer with GDB"));
+ action->setText(MemcheckTool::tr("Valgrind Memory Analyzer with GDB"));
action->setToolTip(MemcheckTool::tr("Valgrind Analyze Memory with GDB uses the "
"Memcheck tool to find memory leaks.\nWhen a problem is detected, "
"the application is interrupted and can be debugged."));
@@ -650,7 +650,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
} else {
action = new QAction(MemcheckTool::tr("Heob"), this);
Core::Command *cmd = Core::ActionManager::registerAction(action, "Memcheck.Local");
- cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+H")));
+ cmd->setDefaultKeySequence(QKeySequence(MemcheckTool::tr("Ctrl+Alt+H")));
connect(action, &QAction::triggered, this, &MemcheckToolPrivate::heobAction);
menu->addAction(cmd, Debugger::Constants::G_ANALYZER_TOOLS);
connect(m_startAction, &QAction::changed, action, [action, this] {
@@ -659,7 +659,7 @@ MemcheckToolPrivate::MemcheckToolPrivate()
}
action = new QAction(this);
- action->setText(tr("Valgrind Memory Analyzer (External Application)"));
+ action->setText(MemcheckTool::tr("Valgrind Memory Analyzer (External Application)"));
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, "Memcheck.Remote"),
Debugger::Constants::G_ANALYZER_REMOTE_TOOLS);
@@ -724,7 +724,7 @@ void MemcheckToolPrivate::heobAction()
}
}
if (!hasLocalRc) {
- const QString msg = tr("Heob: No local run configuration available.");
+ const QString msg = MemcheckTool::tr("Heob: No local run configuration available.");
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
return;
@@ -733,7 +733,7 @@ void MemcheckToolPrivate::heobAction()
|| abi.os() != Abi::WindowsOS
|| abi.binaryFormat() != Abi::PEFormat
|| (abi.wordWidth() != 32 && abi.wordWidth() != 64)) {
- const QString msg = tr("Heob: No toolchain available.");
+ const QString msg = MemcheckTool::tr("Heob: No toolchain available.");
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
return;
@@ -746,7 +746,7 @@ void MemcheckToolPrivate::heobAction()
// target executable
if (executable.isEmpty()) {
- const QString msg = tr("Heob: No executable set.");
+ const QString msg = MemcheckTool::tr("Heob: No executable set.");
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
return;
@@ -754,7 +754,7 @@ void MemcheckToolPrivate::heobAction()
if (!QFile::exists(executable))
executable = Utils::HostOsInfo::withExecutableSuffix(executable);
if (!QFile::exists(executable)) {
- const QString msg = tr("Heob: Cannot find %1.").arg(executable);
+ const QString msg = MemcheckTool::tr("Heob: Cannot find %1.").arg(executable);
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
return;
@@ -775,9 +775,11 @@ void MemcheckToolPrivate::heobAction()
const QString heob = QString("heob%1.exe").arg(abi.wordWidth());
const QString heobPath = dialog.path() + '/' + heob;
if (!QFile::exists(heobPath)) {
- QMessageBox::critical(Core::ICore::mainWindow(), tr("Heob"),
- tr("The %1 executables must be in the appropriate location.")
- .arg("<a href=\"https://github.com/ssbssa/heob/releases\">Heob</a>"));
+ QMessageBox::critical(
+ Core::ICore::mainWindow(),
+ MemcheckTool::tr("Heob"),
+ MemcheckTool::tr("The %1 executables must be in the appropriate location.")
+ .arg("<a href=\"https://github.com/ssbssa/heob/releases\">Heob</a>"));
return;
}
@@ -786,13 +788,19 @@ void MemcheckToolPrivate::heobAction()
const QString dwarfstack = QString("dwarfstack%1.dll").arg(abi.wordWidth());
const QString dwarfstackPath = dialog.path() + '/' + dwarfstack;
if (!QFile::exists(dwarfstackPath)
- && CheckableMessageBox::doNotShowAgainInformation(
- Core::ICore::mainWindow(), tr("Heob"),
- tr("Heob used with MinGW projects needs the %1 DLLs for proper stacktrace resolution.")
- .arg("<a href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"),
- ICore::settings(), "HeobDwarfstackInfo",
- QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
- QDialogButtonBox::Ok) != QDialogButtonBox::Ok)
+ && CheckableMessageBox::doNotShowAgainInformation(
+ Core::ICore::mainWindow(),
+ MemcheckTool::tr("Heob"),
+ MemcheckTool::tr("Heob used with MinGW projects needs the %1 DLLs for proper "
+ "stacktrace resolution.")
+ .arg(
+ "<a "
+ "href=\"https://github.com/ssbssa/dwarfstack/releases\">Dwarfstack</a>"),
+ ICore::settings(),
+ "HeobDwarfstackInfo",
+ QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ QDialogButtonBox::Ok)
+ != QDialogButtonBox::Ok)
return;
}
@@ -837,7 +845,9 @@ void MemcheckToolPrivate::heobAction()
CREATE_UNICODE_ENVIRONMENT | CREATE_SUSPENDED | CREATE_NEW_CONSOLE, envPtr,
reinterpret_cast<LPCWSTR>(workingDirectory.utf16()), &si, &pi)) {
DWORD e = GetLastError();
- const QString msg = tr("Heob: Cannot create %1 process (%2).").arg(heob).arg(qt_error_string(e));
+ const QString msg = MemcheckTool::tr("Heob: Cannot create %1 process (%2).")
+ .arg(heob)
+ .arg(qt_error_string(e));
TaskHub::addTask(Task::Error, msg, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
return;
diff --git a/src/plugins/vcsbase/vcsoutputwindow.cpp b/src/plugins/vcsbase/vcsoutputwindow.cpp
index d5b4a48b8e..da3cb8fa29 100644
--- a/src/plugins/vcsbase/vcsoutputwindow.cpp
+++ b/src/plugins/vcsbase/vcsoutputwindow.cpp
@@ -239,7 +239,7 @@ void OutputWindowPlainTextEdit::appendLinesWithStyle(const QString &s,
setFormat(style);
if (style == VcsOutputWindow::Command) {
- const QString timeStamp = QTime::currentTime().toString("\nHH:mm ");
+ const QString timeStamp = QTime::currentTime().toString("\nHH:mm:ss ");
appendLines(timeStamp + s, repository);
} else {
appendLines(s, repository);
@@ -291,22 +291,17 @@ VcsOutputWindow::VcsOutputWindow()
Q_ASSERT(d->passwordRegExp.isValid());
m_instance = this;
- auto updateFontSettings = [] {
- d->widget.setBaseFont(TextEditor::TextEditorSettings::fontSettings().font());
- };
-
auto updateBehaviorSettings = [] {
d->widget.setWheelZoomEnabled(
TextEditor::TextEditorSettings::behaviorSettings().m_scrollWheelZooming);
};
- updateFontSettings();
updateBehaviorSettings();
+ setupContext(Internal::C_VCS_OUTPUT_PANE, &d->widget);
connect(this, &IOutputPane::zoomIn, &d->widget, &Core::OutputWindow::zoomIn);
connect(this, &IOutputPane::zoomOut, &d->widget, &Core::OutputWindow::zoomOut);
- connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::fontSettingsChanged,
- this, updateFontSettings);
+ connect(this, &IOutputPane::resetZoom, &d->widget, &Core::OutputWindow::resetZoom);
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,
this, updateBehaviorSettings);
}
diff --git a/src/shared/proparser/qmakeevaluator.cpp b/src/shared/proparser/qmakeevaluator.cpp
index 01233fc46f..6e75847eb9 100644
--- a/src/shared/proparser/qmakeevaluator.cpp
+++ b/src/shared/proparser/qmakeevaluator.cpp
@@ -1702,7 +1702,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFunction(
if (m_valuemapStack.count() >= 100) {
evalError(fL1S("Ran into infinite recursion (depth > 100)."));
- vr = ReturnFalse;
+ vr = ReturnError;
} else {
m_valuemapStack.push(ProValueMap());
m_locationStack.push(m_current);
diff --git a/src/shared/qbs b/src/shared/qbs
-Subproject 59cc3f249b1f507afda1757e6edd1ba25970fa1
+Subproject e0ac40e53c5fc16b675ea2ac63fb5f3a6cab3de
diff --git a/src/shared/registryaccess/registryaccess.h b/src/shared/registryaccess/registryaccess.h
index 2880aa6677..cfd945d35a 100644
--- a/src/shared/registryaccess/registryaccess.h
+++ b/src/shared/registryaccess/registryaccess.h
@@ -45,6 +45,7 @@ enum AccessMode {
static const char *debuggerApplicationFileC = "qtcdebugger";
static const WCHAR *debuggerRegistryKeyC = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
static const WCHAR *debuggerRegistryValueNameC = L"Debugger";
+static const WCHAR *autoRegistryValueNameC = L"Auto";
static inline QString wCharToQString(const WCHAR *w)
{
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
index 0ce49e829d..bcf05e5d04 100644
--- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
@@ -31,6 +31,7 @@
#include <environment.h>
#include <executeinloop.h>
#include <filepathcaching.h>
+#include <filesystem.h>
#include <generatedfiles.h>
#include <modifiedtimechecker.h>
#include <pchcreator.h>
@@ -179,7 +180,8 @@ struct Data // because we have a cycle dependency
Sqlite::Database database;
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
- ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher{filePathCache};
+ ClangBackEnd::FileSystem fileSystem{filePathCache};
+ ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher{filePathCache, fileSystem};
ApplicationEnvironment environment;
ProjectPartsStorage<> projectPartsStorage{database};
PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
@@ -212,12 +214,7 @@ struct Data // because we have a cycle dependency
ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache,
generatedFiles,
environment};
- std::function<TimeStamp(FilePathView filePath)> getModifiedTime{
- [&](ClangBackEnd::FilePathView path) -> TimeStamp {
- return QFileInfo(QString(path)).lastModified().toSecsSinceEpoch();
- }};
- ClangBackEnd::ModifiedTimeChecker<ClangBackEnd::SourceEntries> modifiedTimeChecker{getModifiedTime,
- filePathCache};
+ ClangBackEnd::ModifiedTimeChecker<ClangBackEnd::SourceEntries> modifiedTimeChecker{fileSystem};
ClangBackEnd::BuildDependenciesProvider buildDependencyProvider{buildDependencyStorage,
modifiedTimeChecker,
buildDependencyCollector,
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
index 8c8c51a6cd..187a27cf89 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
@@ -66,10 +66,9 @@ public:
}
}
- FilePathIds fetchSources(ProjectPartId projectPartId) const override
+ FilePathIds fetchPchSources(ProjectPartId projectPartId) const override
{
- return fetchProjectPartsFilesStatement.template values<FilePathId>(1024,
- projectPartId.projectPathId);
+ return fetchPchSourcesStatement.template values<FilePathId>(1024, projectPartId.projectPathId);
}
void insertOrUpdateFileStatuses(const FileStatuses &fileStatuses) override
@@ -252,8 +251,10 @@ public:
"CONFLICT(sourceId, projectPartId) DO UPDATE SET sourceType = ?003, "
"hasMissingIncludes = ?004",
database};
- mutable ReadStatement fetchProjectPartsFilesStatement{
- "SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? ORDER BY sourceId", database};
+ mutable ReadStatement fetchPchSourcesStatement{
+ "SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? AND sourceType IN (0, 1, "
+ "3, 4) ORDER BY sourceId",
+ database};
mutable ReadStatement fetchSourceDependenciesStatement{
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION "
"SELECT dependencySourceId FROM sourceDependencies, "
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
index 1166564b32..a1c20811aa 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
@@ -56,7 +56,7 @@ public:
virtual UsedMacros fetchUsedMacros(FilePathId sourceId) const = 0;
virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) = 0;
virtual void updatePchCreationTimeStamp(long long pchCreationTimeStamp, ProjectPartId projectPartId) = 0;
- virtual FilePathIds fetchSources(ProjectPartId projectPartId) const = 0;
+ virtual FilePathIds fetchPchSources(ProjectPartId projectPartId) const = 0;
protected:
~BuildDependenciesStorageInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
index cd7b492868..15c9a19547 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
@@ -114,7 +114,7 @@ void PchCreator::generatePch(PchTask &&pchTask)
{
m_projectPartPch.projectPartId = pchTask.projectPartId();
m_projectPartPch.lastModified = QDateTime::currentSecsSinceEpoch();
-
+ m_sources = std::move(pchTask.sources);
if (pchTask.includes.empty())
return;
@@ -127,10 +127,9 @@ void PchCreator::generatePch(PchTask &&pchTask)
m_clangTool.addFile(std::move(headerFilePath), content.clone(), std::move(commandLine));
bool success = generatePch(NativeFilePath{headerFilePath}, content);
- if (success) {
- m_sources = pchTask.sources;
- m_projectPartPch.pchPath = std::move(pchOutputPath);
- }
+
+ if (success)
+ m_projectPartPch.pchPath = std::move(pchOutputPath);
}
const ProjectPartPch &PchCreator::projectPartPch()
diff --git a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
index 9db3c683b9..2d16b484a1 100644
--- a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
+++ b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
@@ -128,23 +128,26 @@ private:
case SourceType::TopSystemInclude:
topSystemIncludes.emplace_back(source.sourceId);
systemIncludes.emplace_back(source.sourceId);
+ sources.emplace_back(source.sourceId);
break;
case SourceType::SystemInclude:
systemIncludes.emplace_back(source.sourceId);
+ sources.emplace_back(source.sourceId);
break;
case SourceType::TopProjectInclude:
topProjectIncludes.emplace_back(source.sourceId);
projectIncludes.emplace_back(source.sourceId);
+ sources.emplace_back(source.sourceId);
break;
case SourceType::ProjectInclude:
projectIncludes.emplace_back(source.sourceId);
+ sources.emplace_back(source.sourceId);
break;
case SourceType::UserInclude:
case SourceType::Source:
break;
}
- sources.emplace_back(source.sourceId);
}
static Utils::SmallStringVector filterUsedMarcos(const UsedMacros &usedMacros,
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
index e7e83da788..a3da84d83b 100644
--- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
+++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri
@@ -17,8 +17,6 @@ HEADERS += \
$$PWD/symbolsvisitorbase.h \
$$PWD/usedmacro.h \
$$PWD/sourcedependency.h \
- $$PWD/filestatus.h \
- $$PWD/filestatuscache.h \
$$PWD/indexdataconsumer.h \
$$PWD/sourcesmanager.h \
$$PWD/symbolindexertaskqueue.h \
@@ -67,5 +65,4 @@ HEADERS += \
SOURCES += \
$$PWD/filestatuspreprocessorcallbacks.cpp \
$$PWD/sourcerangefilter.cpp \
- $$PWD/symbolindexer.cpp \
- $$PWD/filestatuscache.cpp
+ $$PWD/symbolindexer.cpp
diff --git a/src/tools/clangrefactoringbackend/source/filestatuscache.cpp b/src/tools/clangrefactoringbackend/source/filestatuscache.cpp
deleted file mode 100644
index 14ad48da14..0000000000
--- a/src/tools/clangrefactoringbackend/source/filestatuscache.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "filestatuscache.h"
-
-#include <QDateTime>
-#include <QFileInfo>
-
-namespace ClangBackEnd {
-
-FileStatusCache::FileStatusCache(FilePathCachingInterface &filePathCache)
- : m_filePathCache(filePathCache)
-{
-
-}
-
-long long FileStatusCache::lastModifiedTime(FilePathId filePathId) const
-{
- return findEntry(filePathId).lastModified;
-}
-
-void FileStatusCache::update(FilePathId filePathId)
-{
- auto found = std::lower_bound(m_cacheEntries.begin(),
- m_cacheEntries.end(),
- Internal::FileStatusCacheEntry{filePathId},
- [] (const auto &first, const auto &second) {
- return first.filePathId < second.filePathId;
- });
-
- if (found != m_cacheEntries.end() && found->filePathId == filePathId) {
- QFileInfo fileInfo = qFileInfo(filePathId);
- found->lastModified = fileInfo.lastModified().toMSecsSinceEpoch() / 1000;
- }
-}
-
-FileStatusCache::size_type FileStatusCache::size() const
-{
- return m_cacheEntries.size();
-}
-
-Internal::FileStatusCacheEntry FileStatusCache::findEntry(FilePathId filePathId) const
-{
- auto found = std::lower_bound(m_cacheEntries.begin(),
- m_cacheEntries.end(),
- Internal::FileStatusCacheEntry{filePathId},
- [] (const auto &first, const auto &second) {
- return first.filePathId < second.filePathId;
- });
-
- if (found != m_cacheEntries.end() && found->filePathId == filePathId)
- return *found;
-
- QFileInfo fileInfo = qFileInfo(filePathId);
- auto inserted = m_cacheEntries.emplace(found,
- filePathId,
- fileInfo.lastModified().toMSecsSinceEpoch() / 1000);
-
- return *inserted;
-}
-
-QFileInfo FileStatusCache::qFileInfo(FilePathId filePathId) const
-{
- QFileInfo fileInfo(QString(m_filePathCache.filePath(filePathId)));
-
- fileInfo.refresh();
-
- return fileInfo;
-}
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
index 1ee61eb67c..4f3a6f172f 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -87,8 +87,8 @@ SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQ
void SymbolIndexer::updateProjectParts(ProjectPartContainers &&projectParts)
{
- for (ProjectPartContainer &projectPart : projectParts)
- updateProjectPart(std::move(projectPart));
+ for (ProjectPartContainer &projectPart : projectParts)
+ updateProjectPart(std::move(projectPart));
}
void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
@@ -145,7 +145,7 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
}
m_pathWatcher.updateIdPaths(
- {{projectPartId, m_buildDependencyStorage.fetchSources(projectPartId)}});
+ {{projectPartId, m_buildDependencyStorage.fetchPchSources(projectPartId)}});
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
m_symbolIndexerTaskQueue.processEntries();
}
@@ -154,6 +154,8 @@ void SymbolIndexer::pathsWithIdsChanged(const ProjectPartIds &) {}
void SymbolIndexer::pathsChanged(const FilePathIds &filePathIds)
{
+ m_modifiedTimeChecker.pathsChanged(filePathIds);
+
FilePathIds dependentSourcePathIds = m_symbolStorage.fetchDependentSourceIds(filePathIds);
std::vector<SymbolIndexerTask> symbolIndexerTask;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h
index 64b442bf33..d969cd8026 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h
@@ -29,8 +29,8 @@
#include "symbolindexertaskqueueinterface.h"
#include "symbolstorageinterface.h"
#include "builddependenciesstorageinterface.h"
-#include "clangpathwatcher.h"
+#include <clangpathwatcher.h>
#include <filecontainerv2.h>
#include <modifiedtimecheckerinterface.h>
#include <precompiledheaderstorageinterface.h>
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h
index 5c391503bf..936a34af00 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexing.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h
@@ -39,6 +39,7 @@
#include <projectpartsstorage.h>
#include <filepathcachingfwd.h>
+#include <filesystem.h>
#include <modifiedtimechecker.h>
#include <refactoringdatabaseinitializer.h>
@@ -142,16 +143,12 @@ private:
PrecompiledHeaderStorage<Sqlite::Database> m_precompiledHeaderStorage;
ProjectPartsStorage<Sqlite::Database> m_projectPartsStorage;
SymbolStorage m_symbolStorage;
- ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
- FileStatusCache m_fileStatusCache{m_filePathCache};
+ FileSystem m_fileSytem{m_filePathCache};
+ ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache, m_fileSytem};
+ FileStatusCache m_fileStatusCache{m_fileSytem};
SymbolsCollectorManager m_collectorManger;
ProgressCounter m_progressCounter;
- std::function<TimeStamp(FilePathView filePath)> getModifiedTime{
- [&](ClangBackEnd::FilePathView path) -> TimeStamp {
- return QFileInfo(QString(path)).lastModified().toSecsSinceEpoch();
- }};
- ModifiedTimeChecker<ClangBackEnd::SourceTimeStamps> m_modifiedTimeChecker{getModifiedTime,
- m_filePathCache};
+ ModifiedTimeChecker<ClangBackEnd::SourceTimeStamps> m_modifiedTimeChecker{m_fileSytem};
SymbolIndexer m_indexer;
SymbolIndexerTaskQueue m_indexerQueue;
SymbolIndexerTaskScheduler m_indexerScheduler;
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
index 071837ac52..ab5a00fc6b 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp
@@ -129,7 +129,11 @@ bool SymbolsCollector::collectSymbols()
auto actionFactory = ClangBackEnd::newFrontendActionFactory(&m_collectSymbolsAction);
- return tool.run(actionFactory.get()) != 1;
+ bool noErrors = tool.run(actionFactory.get()) != 1;
+
+ m_clangTool = ClangTool();
+
+ return noErrors;
}
void SymbolsCollector::doInMainThreadAfterFinished()
diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h
index cc7ca4396c..e103471372 100644
--- a/src/tools/clangrefactoringbackend/source/symbolscollector.h
+++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h
@@ -63,6 +63,8 @@ public:
bool isUsed() const override;
void setIsUsed(bool isUsed) override;
+ bool isClean() const { return m_clangTool.isClean(); }
+
private:
FilePathCaching m_filePathCache;
ClangTool m_clangTool;
diff --git a/src/tools/qtcdebugger/main.cpp b/src/tools/qtcdebugger/main.cpp
index 38507c8539..6beda7c1ec 100644
--- a/src/tools/qtcdebugger/main.cpp
+++ b/src/tools/qtcdebugger/main.cpp
@@ -419,6 +419,15 @@ static bool registerDebuggerKey(const WCHAR *key,
do {
if (!openRegistryKey(HKEY_LOCAL_MACHINE, key, true, &handle, access, errorMessage))
break;
+
+ // Make sure to automatically open the qtcdebugger dialog on a crash
+ QString autoVal;
+ registryReadStringKey(handle, autoRegistryValueNameC, &autoVal, errorMessage);
+ if (autoVal != "1") {
+ if (!registryWriteStringKey(handle, autoRegistryValueNameC, "1", errorMessage))
+ break;
+ }
+
// Save old key, which might be missing
QString oldDebugger;
if (isRegistered(handle, call, errorMessage, &oldDebugger)) {
diff --git a/tests/system/objects.map b/tests/system/objects.map
index 276ae23b35..c6064297c7 100644
--- a/tests/system/objects.map
+++ b/tests/system/objects.map
@@ -76,10 +76,10 @@
:FormEditorStack.menuBar_QDesignerMenuBar {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' name='menuBar' type='QDesignerMenuBar' visible='1'}
:FormEditorStack_qdesigner_internal::FormWindow {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' type='qdesigner_internal::FormWindow' unnamed='1' visible='1'}
:FormEditorStack_qdesigner_internal::PropertyLineEdit {container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack' type='qdesigner_internal::PropertyLineEdit' unnamed='1' visible='1'}
-:Git Repository Clone.Cancel_QPushButton {text='Cancel' type='QPushButton' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
-:Git Repository Clone.Finish_QPushButton {text~='(Finish|Done)' type='QPushButton' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
-:Git Repository Clone.Result._QLabel {type='QLabel' unnamed='1' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
-:Git Repository Clone.logPlainTextEdit_QPlainTextEdit {type='QPlainTextEdit' unnamed='1' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
+:Git Repository Clone.Cancel_QPushButton {text='Cancel' type='QPushButton' visible='1' window=':New_ProjectExplorer::JsonWizard'}
+:Git Repository Clone.Finish_QPushButton {text~='(Finish|Done)' type='QPushButton' visible='1' window=':New_ProjectExplorer::JsonWizard'}
+:Git Repository Clone.Result._QLabel {type='QLabel' unnamed='1' visible='1' window=':New_ProjectExplorer::JsonWizard'}
+:Git Repository Clone.logPlainTextEdit_QPlainTextEdit {type='QPlainTextEdit' unnamed='1' visible='1' window=':New_ProjectExplorer::JsonWizard'}
:Go to slot.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Go to slot_QDialog'}
:Go to slot.Select signal_QGroupBox {name='groupBox' title='Select signal' type='QGroupBox' visible='1' window=':Go to slot_QDialog'}
:Go to slot_QDialog {name='SelectSignalDialog' type='QDialog' visible='1' windowTitle='Go to slot'}
@@ -88,14 +88,14 @@
:Hits_QResultWidget {aboveWidget=':Hits_QLabel' type='QResultWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Kits_QtVersion_QComboBox {container=':qt_tabwidget_stackedwidget_QWidget' leftWidget=':QtVersionLabel_KitPage' type='QComboBox' unnamed='1' visible='1'}
:Locals and Expressions_Debugger::Internal::WatchTreeView {container=':Debugger.Docks.LocalsAndWatchersDockWidget.Inspector_QFrame' name='WatchWindow' type='Debugger::Internal::WatchTreeView' visible='1'}
-:Minimal required Qt version:_QLabel {text='Minimal required Qt version:' type='QLabel' unnamed='1' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
-:New Text File.Add to project:_QLabel {name='projectLabel' text='Add to project:' type='QLabel' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
-:New Text File.nameLineEdit_Utils::FileNameValidatingLineEdit {name='nameLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
-:New Text File_ProjectExplorer::JsonWizard {type='ProjectExplorer::JsonWizard' unnamed='1' visible='1'}
+:Minimal required Qt version:_QLabel {text='Minimal required Qt version:' type='QLabel' unnamed='1' visible='1' window=':New_ProjectExplorer::JsonWizard'}
+:New Text File.Add to project:_QLabel {name='projectLabel' text='Add to project:' type='QLabel' visible='1' window=':New_ProjectExplorer::JsonWizard'}
+:New Text File.nameLineEdit_Utils::FileNameValidatingLineEdit {name='nameLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1' window=':New_ProjectExplorer::JsonWizard'}
:New.comboBox_QComboBox {name='comboBox' type='QComboBox' visible='1' window=':New_Core::Internal::NewDialog'}
:New.frame_QFrame {name='frame' type='QFrame' visible='1' window=':New_Core::Internal::NewDialog'}
:New.templateCategoryView_QTreeView {name='templateCategoryView' type='QTreeView' visible='1' window=':New_Core::Internal::NewDialog'}
:New_Core::Internal::NewDialog {name='Core__Internal__NewDialog' type='Core::Internal::NewDialog' visible='1' windowTitle?='New*'}
+:New_ProjectExplorer::JsonWizard {type='ProjectExplorer::JsonWizard' unnamed='1' visible='1'}
:Next_QPushButton {text~='(Next.*|Continue)' type='QPushButton' visible='1'}
:No valid kits found._QLabel {text?='*No valid kits found.*' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:OpenDocuments_Widget {type='Core::Internal::OpenEditorsWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Open Documents'}
@@ -163,10 +163,6 @@
:Qt Creator_Utils::BuildDirectoryLineEdit {name='shadowBuildDirEditLineEdit' type='Utils::FancyLineEdit' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Utils::NavigationTreeView {type='Utils::NavigationTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:Qt Creator_Utils::NavigationTreeView::QExpandingLineEdit {container=':Qt Creator_Utils::NavigationTreeView' type='QExpandingLineEdit' unnamed='1' visible='1'}
-:Qt Gui Application.Form file:_QLabel {name='formLabel' text='Form file:' type='QLabel' visible='1' window=':Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog'}
-:Qt Gui Application.Header file:_QLabel {name='headerLabel' text='Header file:' type='QLabel' visible='1' window=':Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog'}
-:Qt Gui Application.Source file:_QLabel {name='sourceLabel' text='Source file:' type='QLabel' visible='1' window=':Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog'}
-:Qt Gui Application_QmakeProjectManager::Internal::GuiAppWizardDialog {type='QmakeProjectManager::Internal::GuiAppWizardDialog' unnamed='1' visible='1' windowTitle='Qt Widgets Application'}
:QtSupport__Internal__QtVersionManager.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' text?='Qt version *' type='QLabel' unnamed='1' visible='1'}
:QtSupport__Internal__QtVersionManager.errorLabel.QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='errorLabel' type='QLabel' visible='1'}
:QtSupport__Internal__QtVersionManager.qmake_QLabel {container=':qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget' name='qmakePath' type='QLabel' visible='1'}
@@ -186,7 +182,6 @@
:Select a Git Commit.workingDirectoryEdit_QLineEdit {type='Utils::FancyLineEdit' unnamed='1' visible='1' window=':Select a Git Commit_Git::Internal::ChangeSelectionDialog'}
:Select a Git Commit_Git::Internal::ChangeSelectionDialog {name='Git__Internal__ChangeSelectionDialog' type='Git::Internal::ChangeSelectionDialog' visible='1' windowTitle='Select a Git Commit'}
:Select signal.signalList_QTreeView {container=':Go to slot.Select signal_QGroupBox' name='signalList' type='QTreeView' visible='1'}
-:Select signal.signalList_QTreeWidget {container=':Go to slot.Select signal_QGroupBox' name='signalList' type='QTreeWidget' visible='1'}
:Send to Codepaster.Cancel_QPushButton {text='Cancel' type='QPushButton' unnamed='1' visible='1' window=':Send to Codepaster_CodePaster::PasteView'}
:Send to Codepaster.Description:_QLabel {name='descriptionLabel' text='Description:' type='QLabel' visible='1' window=':Send to Codepaster_CodePaster::PasteView'}
:Send to Codepaster.Paste_QPushButton {text='Paste' type='QPushButton' unnamed='1' visible='1' window=':Send to Codepaster_CodePaster::PasteView'}
@@ -200,12 +195,12 @@
:Take a UI Tour_Utils::CheckableMessageBox {type='Utils::CheckableMessageBox' unnamed='1' visible='1' windowTitle='Take a UI Tour'}
:User Interface.languageBox_QComboBox {container=':Core__Internal__GeneralSettings.User Interface_QGroupBox' name='languageBox' type='QComboBox' visible='1'}
:Widget Box_qdesigner_internal::WidgetBoxTreeWidget {container=':*Qt Creator.Widget Box_QDockWidget' type='qdesigner_internal::WidgetBoxTreeWidget' unnamed='1' visible='1'}
-:Working Copy_Utils::BaseValidatingLineEdit {type='Utils::FancyLineEdit' unnamed='1' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'}
+:Working Copy_Utils::BaseValidatingLineEdit {type='Utils::FancyLineEdit' unnamed='1' visible='1' window=':New_ProjectExplorer::JsonWizard'}
:WritePermissions_Core::Internal::ReadOnlyFilesDialog {name='Core__Internal__ReadOnlyFilesDialog' type='Core::ReadOnlyFilesDialog' visible='1' windowTitle='Files Without Write Permissions'}
:addToVersionControlComboBox_QComboBox {name='addToVersionControlComboBox' type='QComboBox' visible='1'}
-:formFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Form file:_QLabel' name='formFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'}
+:formFileLineEdit_Utils::FileNameValidatingLineEdit {name='FormFileName' type='Utils::FancyLineEdit' visible='1' window=':New_ProjectExplorer::JsonWizard'}
:frame.templateDescription_QTextBrowser {container=':New.frame_QFrame' name='templateDescription' type='QTextBrowser' visible='1'}
-:headerFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Header file:_QLabel' name='headerFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'}
+:headerFileLineEdit_Utils::FileNameValidatingLineEdit {name='HdrFileName' type='Utils::FancyLineEdit' visible='1' window=':New_ProjectExplorer::JsonWizard'}
:popupFrame_Proposal_QListView {container=':popupFrame_TextEditor::GenericProposalWidget' type='QListView' unnamed='1' visible='1'}
:popupFrame_TextEditor::GenericProposalWidget {name='m_popupFrame' type='TextEditor::GenericProposalWidget' visible='1'}
:projectComboBox_QComboBox {buddy=':New Text File.Add to project:_QLabel' name='projectComboBox' type='QComboBox' visible='1'}
@@ -222,7 +217,7 @@
:scrollArea.Edit build configuration:_QLabel {text='Edit build configuration:' type='QLabel' unnamed='1' visible='1'}
:scrollArea.Library not available_QLabel {name='qmlDebuggingWarningText' text?='Library not available*' type='QLabel' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:scrollArea.qmlDebuggingLibraryCheckBox_QCheckBox {name='qmlDebuggingLibraryCheckBox' type='QCheckBox' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
-:sourceFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Source file:_QLabel' name='sourceFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'}
+:sourceFileLineEdit_Utils::FileNameValidatingLineEdit {name='SrcFileName' type='Utils::FancyLineEdit' visible='1' window=':New_ProjectExplorer::JsonWizard'}
:splitter.Commit File(s)_VcsBase::QActionPushButton {text~='(Commit .+/.+ File.*)' type='VcsBase::QActionPushButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
:splitter.Description_QGroupBox {container=':Qt Creator.splitter_QSplitter' name='descriptionBox' title='Description' type='QGroupBox' visible='1'}
:splitter.Files_QGroupBox {container=':Qt Creator.splitter_QSplitter' name='groupBox' title='Files' type='QGroupBox' visible='1'}
diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py
index a4be7f14d1..a0eea63b82 100644
--- a/tests/system/shared/project.py
+++ b/tests/system/shared/project.py
@@ -53,17 +53,17 @@ def openQmakeProject(projectPath, targets=Targets.desktopTargetClasses(), fromWe
def openCmakeProject(projectPath, buildDir):
def additionalFunction():
- pChooser = waitForObject("{leftWidget={text='Default' type='QCheckBox' unnamed='1' "
+ pChooser = waitForObject("{leftWidget={text='Debug' type='QCheckBox' unnamed='1' "
"visible='1'} type='Utils::PathChooser' unnamed='1' visible='1'}")
lineEdit = getChildByClass(pChooser, "Utils::FancyLineEdit")
replaceEditorContent(lineEdit, buildDir)
- # disable all build configurations except "Default"
- configs = ['Debug', 'Release', 'Release with Debug Information', 'Minimum Size Release']
+ # disable all build configurations except "Debug"
+ configs = ['Release', 'Release with Debug Information', 'Minimum Size Release']
for checkbox in configs:
ensureChecked(waitForObject("{text='%s' type='QCheckBox' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}"
% checkbox), False)
- ensureChecked(waitForObject("{text='Default' type='QCheckBox' unnamed='1' visible='1' "
+ ensureChecked(waitForObject("{text='Debug' type='QCheckBox' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}"), True)
invokeMenuItem("File", "Open File or Project...")
@@ -216,7 +216,7 @@ def createProject_Qt_GUI(path, projectName, checks = True, addToVersionControl =
template = "Qt Widgets Application"
available = __createProjectOrFileSelectType__(" Application", template)
__createProjectSetNameAndPath__(path, projectName, checks)
- __selectQtVersionDesktop__(checks, available, True)
+ __handleBuildSystem__(None)
if checks:
exp_filename = "mainwindow"
@@ -234,6 +234,7 @@ def createProject_Qt_GUI(path, projectName, checks = True, addToVersionControl =
test.compare(findObject(":formFileLineEdit_Utils::FileNameValidatingLineEdit").text, ui_file)
clickButton(waitForObject(":Next_QPushButton"))
+ __selectQtVersionDesktop__(checks, available, True)
expectedFiles = []
if checks:
diff --git a/tests/system/suite_debugger/tst_qml_locals/test.py b/tests/system/suite_debugger/tst_qml_locals/test.py
index 0430c306c9..f85a2d3b23 100644
--- a/tests/system/suite_debugger/tst_qml_locals/test.py
+++ b/tests/system/suite_debugger/tst_qml_locals/test.py
@@ -122,7 +122,8 @@ def fetchItems(index, valIndex, treeView):
tree.setName(name)
tree.setValue(value)
for row in range(model.rowCount(index)):
- tree.addChild(fetchItems(model.index(row, 0, index), model.index(row, 1, index), treeView))
+ tree.addChild(fetchItems(model.index(row, 0, index),
+ model.index(row, 2, index), treeView))
return tree
def checkForEmptyRows(items, isRootCheck=True):
diff --git a/tests/system/suite_editors/tst_edit_externally/test.py b/tests/system/suite_editors/tst_edit_externally/test.py
index ec6fcd9203..9c2ea61d2c 100644
--- a/tests/system/suite_editors/tst_edit_externally/test.py
+++ b/tests/system/suite_editors/tst_edit_externally/test.py
@@ -47,7 +47,8 @@ def main():
mBox = ("{text?='The file * has been changed on disk. Do you want to reload it?' "
"type='QMessageBox' unnamed='1' visible='1'}")
- popupText = "The file <i>%s</i> has been changed on disk. Do you want to reload it?"
+ popupText = ("<p>The file <i>%s</i> has been changed on disk. Do you want to reload it?</p>"
+ "<p>The default behavior can be set in Tools > Options > Environment > System.</p>")
formerContent = None
for i, currentFile in enumerate(files):
diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py
index 928f890b2a..3270f619e5 100644
--- a/tests/system/suite_general/tst_default_settings/test.py
+++ b/tests/system/suite_general/tst_default_settings/test.py
@@ -121,14 +121,8 @@ def __compFunc__(it, foundComp, foundCompNames):
pathLineEdit = findObject(":Path.Utils_BaseValidatingLineEdit")
foundComp.append(str(pathLineEdit.text))
except:
- objectString = ("{buddy={container=':qt_tabwidget_stackedwidget_QWidget'"
- " text='Initialization:' type='QLabel' unnamed='1' visible='1'}"
- " type='%s' unnamed='1' visible='1'}")
- try:
- foundText = findObject(objectString % "QLabel").text
- except:
- foundText = findObject(objectString % "QComboBox").currentText
- foundComp.append({it:str(foundText)})
+ varsBatCombo = waitForObjectExists("{name='varsBatCombo' type='QComboBox' visible='1'}")
+ foundComp.append({it:str(varsBatCombo.currentText)})
foundCompNames.append(it)
diff --git a/tests/system/suite_tools/tst_designer_goto_slot/test.py b/tests/system/suite_tools/tst_designer_goto_slot/test.py
index eadea648ae..f1e47727db 100644
--- a/tests/system/suite_tools/tst_designer_goto_slot/test.py
+++ b/tests/system/suite_tools/tst_designer_goto_slot/test.py
@@ -50,14 +50,8 @@ def main():
waitFor("macHackActivateContextMenuItem('Go to slot...', con[0])", 6000)
else:
activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1'}", "Go to slot..."))
- try:
- # Creator built with Qt <= 5.9
- signalWidgetObject = waitForObject(":Select signal.signalList_QTreeWidget", 5000)
- signalName = con[2]
- except:
- # Creator built with Qt >= 5.10
- signalWidgetObject = waitForObject(":Select signal.signalList_QTreeView")
- signalName = con[1] + "." + con[2]
+ signalWidgetObject = waitForObject(":Select signal.signalList_QTreeView")
+ signalName = con[1] + "." + con[2]
waitForObjectItem(signalWidgetObject, signalName)
clickItem(signalWidgetObject, signalName, 5, 5, 0, Qt.LeftButton)
clickButton(waitForObject(":Go to slot.OK_QPushButton"))
diff --git a/tests/system/suite_tools/tst_git_clone/test.py b/tests/system/suite_tools/tst_git_clone/test.py
index dbafe77690..476c1be365 100644
--- a/tests/system/suite_tools/tst_git_clone/test.py
+++ b/tests/system/suite_tools/tst_git_clone/test.py
@@ -55,7 +55,7 @@ def verifyCloneLog(targetDir, canceled):
if canceled:
test.warning("Could not find resultLabel",
"Cloning might have failed before clicking 'Cancel'")
- return object.exists(":New Text File_ProjectExplorer::JsonWizard")
+ return object.exists(":New_ProjectExplorer::JsonWizard")
else:
test.fail("Could not find resultLabel")
return True
diff --git a/tests/system/suite_tools/tst_git_local/test.py b/tests/system/suite_tools/tst_git_local/test.py
index d5617642f4..8cbdfc42c6 100644
--- a/tests/system/suite_tools/tst_git_local/test.py
+++ b/tests/system/suite_tools/tst_git_local/test.py
@@ -146,9 +146,9 @@ def verifyClickCommit():
"Verifying whether diff editor contains pointless_header.h file.")
test.verify(pointlessHeader not in diffOriginal,
"Verifying whether original does not contain pointless_header.h file.")
- test.verify("HEADERS += \\\n mainwindow.h \\\n pointless_header.h\n" in diffChanged,
+ test.verify("HEADERS += \\\n mainwindow.h \\\n pointless_header.h\n" in diffChanged,
"Verifying whether diff editor has pointless_header.h listed in pro file.")
- test.verify("HEADERS += \\\n mainwindow.h\n\n" in diffOriginal
+ test.verify("HEADERS += \\\n mainwindow.h\n\n" in diffOriginal
and "pointless_header.h" not in diffOriginal,
"Verifying whether original has no additional header in pro file.")
test.verify(original.readOnly and changed.readOnly,
@@ -173,7 +173,7 @@ def main():
% os.path.join(srcPath, projectName, ".git").replace("\\", "/") in str(vcsLog),
"Has initialization of repo been logged:\n%s " % vcsLog)
createLocalGitConfig(os.path.join(srcPath, projectName, ".git"))
- commitMessages = [commit("Initial Commit", "Committed 5 files.")]
+ commitMessages = [commit("Initial Commit", "Committed 6 files.")]
clickButton(waitForObject(":*Qt Creator.Clear_QToolButton"))
headerName = "pointless_header.h"
addCPlusPlusFile(headerName, "C++ Header File", projectName + ".pro",
diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp
index 052ed452f0..d14b94fe30 100644
--- a/tests/unit/unittest/builddependenciesstorage-test.cpp
+++ b/tests/unit/unittest/builddependenciesstorage-test.cpp
@@ -70,7 +70,7 @@ protected:
MockSqliteWriteStatement &updatePchCreationTimeStampStatement = storage.updatePchCreationTimeStampStatement;
MockSqliteWriteStatement &deleteAllProjectPartsFilesWithProjectPartNameStatement
= storage.deleteAllProjectPartsFilesWithProjectPartNameStatement;
- MockSqliteReadStatement &fetchProjectPartsFilesStatement = storage.fetchProjectPartsFilesStatement;
+ MockSqliteReadStatement &fetchProjectPartsFilesStatement = storage.fetchPchSourcesStatement;
};
TEST_F(BuildDependenciesStorage, ConvertStringsToJson)
@@ -238,7 +238,7 @@ TEST_F(BuildDependenciesStorage, FetchSources)
ClangBackEnd::FilePathIds result{3, 5, 7};
EXPECT_CALL(fetchProjectPartsFilesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result));
- auto sources = storage.fetchSources(22);
+ auto sources = storage.fetchPchSources(22);
ASSERT_THAT(sources, result);
}
diff --git a/tests/unit/unittest/changedfilepathcompressor-test.cpp b/tests/unit/unittest/changedfilepathcompressor-test.cpp
deleted file mode 100644
index 08e66a2541..0000000000
--- a/tests/unit/unittest/changedfilepathcompressor-test.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "googletest.h"
-
-#include "mocktimer.h"
-
-#include <changedfilepathcompressor.h>
-#include <filepathcaching.h>
-#include <refactoringdatabaseinitializer.h>
-
-namespace {
-
-using testing::ElementsAre;
-using testing::Invoke;
-using testing::IsEmpty;
-using testing::NiceMock;
-
-using ClangBackEnd::FilePath;
-using ClangBackEnd::FilePathId;
-
-class ChangedFilePathCompressor : public testing::Test
-{
-protected:
- void SetUp()
- {
- compressor.setCallback(mockCompressorCallback.AsStdFunction());
- }
-
- FilePathId filePathId(const QString &filePath)
- {
- Utils::SmallString utf8FilePath{filePath};
-
- return filePathCache.filePathId(ClangBackEnd::FilePathView{utf8FilePath});
- }
-
-protected:
- Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
- ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
- ClangBackEnd::FilePathCaching filePathCache{database};
- NiceMock<MockFunction<void (const ClangBackEnd::FilePathIds &filePathIds)>> mockCompressorCallback;
- ClangBackEnd::ChangedFilePathCompressor<NiceMock<MockTimer>> compressor{filePathCache};
- NiceMock<MockTimer> &mockTimer = compressor.timer();
- QString filePath1{"filePath1"};
- QString filePath2{"filePath2"};
- FilePathId filePathId1 = filePathId(filePath1);
- FilePathId filePathId2 = filePathId(filePath2);
-};
-
-TEST_F(ChangedFilePathCompressor, AddFilePath)
-{
- compressor.addFilePath(filePath1);
-
- ASSERT_THAT(compressor.takeFilePathIds(), ElementsAre(filePathId(filePath1)));
-}
-
-TEST_F(ChangedFilePathCompressor, NoFilePathsAferTakenThem)
-{
- compressor.addFilePath(filePath1);
-
- compressor.takeFilePathIds();
-
- ASSERT_THAT(compressor.takeFilePathIds(), IsEmpty());
-}
-
-TEST_F(ChangedFilePathCompressor, CallRestartTimerAfterAddingPath)
-{
- EXPECT_CALL(mockTimer, start(20));
-
- compressor.addFilePath(filePath1);
-}
-
-TEST_F(ChangedFilePathCompressor, CallTimeOutAfterAddingPath)
-{
- EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(filePathId1, filePathId2)));
-
- compressor.addFilePath(filePath1);
- compressor.addFilePath(filePath2);
-}
-
-TEST_F(ChangedFilePathCompressor, RemoveDuplicates)
-{
- EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(filePathId1, filePathId2)));
-
- compressor.addFilePath(filePath1);
- compressor.addFilePath(filePath2);
- compressor.addFilePath(filePath1);
-}
-
-}
diff --git a/tests/unit/unittest/clangpathwatcher-test.cpp b/tests/unit/unittest/clangpathwatcher-test.cpp
index 00fe91dc49..f4d99e358d 100644
--- a/tests/unit/unittest/clangpathwatcher-test.cpp
+++ b/tests/unit/unittest/clangpathwatcher-test.cpp
@@ -25,10 +25,11 @@
#include "googletest.h"
-#include "mocktimer.h"
+#include "mockclangpathwatchernotifier.h"
#include "mockfilepathcaching.h"
+#include "mockfilesystem.h"
#include "mockqfilesystemwatcher.h"
-#include "mockclangpathwatchernotifier.h"
+#include "mocktimer.h"
#include <clangpathwatcher.h>
@@ -55,91 +56,126 @@ using ClangBackEnd::WatcherEntry;
class ClangPathWatcher : public testing::Test
{
protected:
- void SetUp();
+ void SetUp()
+ {
+ ON_CALL(mockFilePathCache, filePathId(Eq(path1))).WillByDefault(Return(pathIds[0]));
+ ON_CALL(mockFilePathCache, filePathId(Eq(path2))).WillByDefault(Return(pathIds[1]));
+ ON_CALL(mockFilePathCache, filePathId(Eq(path3))).WillByDefault(Return(pathIds[2]));
+ ON_CALL(mockFilePathCache, filePathId(Eq(path4))).WillByDefault(Return(pathIds[3]));
+ ON_CALL(mockFilePathCache, filePathId(Eq(path5))).WillByDefault(Return(pathIds[4]));
+ ON_CALL(mockFilePathCache, filePath(Eq(pathIds[0]))).WillByDefault(Return(FilePath{path1}));
+ ON_CALL(mockFilePathCache, filePath(Eq(pathIds[1]))).WillByDefault(Return(FilePath{path2}));
+ ON_CALL(mockFilePathCache, filePath(Eq(pathIds[2]))).WillByDefault(Return(FilePath{path3}));
+ ON_CALL(mockFilePathCache, filePath(Eq(pathIds[3]))).WillByDefault(Return(FilePath{path4}));
+ ON_CALL(mockFilePathCache, filePath(Eq(pathIds[4]))).WillByDefault(Return(FilePath{path5}));
+ ON_CALL(mockFilePathCache, directoryPathId(TypedEq<FilePathId>(pathIds[0])))
+ .WillByDefault(Return(directoryPaths[0]));
+ ON_CALL(mockFilePathCache, directoryPathId(TypedEq<FilePathId>(pathIds[1])))
+ .WillByDefault(Return(directoryPaths[0]));
+ ON_CALL(mockFilePathCache, directoryPathId(TypedEq<FilePathId>(pathIds[2])))
+ .WillByDefault(Return(directoryPaths[1]));
+ ON_CALL(mockFilePathCache, directoryPathId(TypedEq<FilePathId>(pathIds[3])))
+ .WillByDefault(Return(directoryPaths[1]));
+ ON_CALL(mockFilePathCache, directoryPathId(TypedEq<FilePathId>(pathIds[4])))
+ .WillByDefault(Return(directoryPaths[2]));
+ ON_CALL(mockFileSystem, lastModified(_)).WillByDefault(Return(1));
+ ON_CALL(mockFilePathCache,
+ directoryPathId(TypedEq<Utils::SmallStringView>(directoryPathString)))
+ .WillByDefault(Return(directoryPaths[0]));
+ ON_CALL(mockFilePathCache,
+ directoryPathId(TypedEq<Utils::SmallStringView>(directoryPathString2)))
+ .WillByDefault(Return(directoryPaths[1]));
+ ON_CALL(mockFilePathCache, directoryPath(Eq(directoryPaths[0])))
+ .WillByDefault(Return(directoryPath));
+ ON_CALL(mockFilePathCache, directoryPath(Eq(directoryPaths[1])))
+ .WillByDefault(Return(directoryPath2));
+ ON_CALL(mockFilePathCache, directoryPath(Eq(directoryPaths[2])))
+ .WillByDefault(Return(directoryPath3));
+ ON_CALL(mockFileSystem, directoryEntries(Eq(directoryPath)))
+ .WillByDefault(Return(FilePathIds{pathIds[0], pathIds[1]}));
+ ON_CALL(mockFileSystem, directoryEntries(Eq(directoryPath2)))
+ .WillByDefault(Return(FilePathIds{pathIds[2], pathIds[3]}));
+ ON_CALL(mockFileSystem, directoryEntries(Eq(directoryPath3)))
+ .WillByDefault(Return(FilePathIds{pathIds[4]}));
+ }
static WatcherEntries sorted(WatcherEntries &&entries)
{
std::stable_sort(entries.begin(), entries.end());
- return entries;
+ return std::move(entries);
}
protected:
- NiceMock<MockFilePathCaching> filePathCache;
+ NiceMock<MockFilePathCaching> mockFilePathCache;
NiceMock<MockClangPathWatcherNotifier> notifier;
- Watcher watcher{filePathCache, &notifier};
+ NiceMock<MockFileSystem> mockFileSystem;
+ Watcher watcher{mockFilePathCache, mockFileSystem, &notifier};
NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();
ProjectPartId id1{2};
ProjectPartId id2{3};
ProjectPartId id3{4};
FilePathView path1{"/path/path1"};
FilePathView path2{"/path/path2"};
+ FilePathView path3{"/path2/path1"};
+ FilePathView path4{"/path2/path2"};
+ FilePathView path5{"/path3/path"};
QString path1QString = QString(path1.toStringView());
QString path2QString = QString(path2.toStringView());
- FilePathIds pathIds = {1, 2};
+ QString directoryPath = "/path";
+ QString directoryPath2 = "/path2";
+ QString directoryPath3 = "/path3";
+ Utils::PathString directoryPathString = directoryPath;
+ Utils::PathString directoryPathString2 = directoryPath2;
+ FilePathIds pathIds = {1, 2, 3, 4, 5};
+ ClangBackEnd::DirectoryPathIds directoryPaths = {1, 2, 3};
ClangBackEnd::ProjectPartIds ids{id1, id2, id3};
- WatcherEntry watcherEntry1{ids[0], pathIds[0]};
- WatcherEntry watcherEntry2{ids[1], pathIds[0]};
- WatcherEntry watcherEntry3{ids[0], pathIds[1]};
- WatcherEntry watcherEntry4{ids[1], pathIds[1]};
- WatcherEntry watcherEntry5{ids[2], pathIds[1]};
+ WatcherEntry watcherEntry1{ids[0], directoryPaths[0], pathIds[0]};
+ WatcherEntry watcherEntry2{ids[1], directoryPaths[0], pathIds[0]};
+ WatcherEntry watcherEntry3{ids[0], directoryPaths[0], pathIds[1]};
+ WatcherEntry watcherEntry4{ids[1], directoryPaths[0], pathIds[1]};
+ WatcherEntry watcherEntry5{ids[2], directoryPaths[0], pathIds[1]};
+ WatcherEntry watcherEntry6{ids[0], directoryPaths[1], pathIds[2]};
+ WatcherEntry watcherEntry7{ids[1], directoryPaths[1], pathIds[3]};
};
-TEST_F(ClangPathWatcher, ConvertWatcherEntriesToQStringList)
-{
- auto convertedList = watcher.convertWatcherEntriesToQStringList(sorted({watcherEntry1, watcherEntry3}));
-
- ASSERT_THAT(convertedList, ElementsAre(path1QString, path2QString));
-}
-
-TEST_F(ClangPathWatcher, UniquePaths)
-{
- auto uniqueEntries = watcher.uniquePaths(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4}));
-
- ASSERT_THAT(uniqueEntries, ElementsAre(watcherEntry1, watcherEntry3));
-}
-
-TEST_F(ClangPathWatcher, NotWatchedEntries)
-{
- watcher.addEntries({watcherEntry1, watcherEntry4});
-
- auto newEntries = watcher.notWatchedEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4}));
-
- ASSERT_THAT(newEntries, ElementsAre(watcherEntry2, watcherEntry3));
-}
-
TEST_F(ClangPathWatcher, AddIdPaths)
{
- EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1QString, path2QString}));
+ EXPECT_CALL(mockQFileSytemWatcher,
+ addPaths(UnorderedElementsAre(QString(directoryPath), QString(directoryPath2))));
- watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}});
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1], pathIds[2]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
}
TEST_F(ClangPathWatcher, UpdateIdPathsCallsAddPathInFileWatcher)
{
- watcher.updateIdPaths({{id1, {pathIds[0]}}, {id2, {pathIds[0]}}});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}});
- EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path2QString}));
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(UnorderedElementsAre(QString(directoryPath2))));
- watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}});
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1], pathIds[2]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
}
TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPathsCallsRemovePathInFileWatcher)
{
- watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}, {id3, {pathIds[0]}}});
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1], pathIds[2]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
- EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2QString}));
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(UnorderedElementsAre(QString(directoryPath2))));
- watcher.updateIdPaths({{id1, {pathIds[0]}}, {id2, {pathIds[0]}}});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}});
}
TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPathsDoNotCallsRemovePathInFileWatcher)
{
- watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}, {id3, {pathIds[0]}}});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2]}},
+ {id2, {pathIds[0], pathIds[1], pathIds[3]}},
+ {id3, {pathIds[0]}}});
- EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2QString}))
- .Times(0);
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(_)).Times(0);
- watcher.updateIdPaths({{id1, {pathIds[1]}}, {id2, {pathIds[0]}}});
+ watcher.updateIdPaths({{id1, {pathIds[1]}}, {id2, {pathIds[3]}}});
}
TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPaths)
@@ -165,36 +201,18 @@ TEST_F(ClangPathWatcher, ExtractSortedIdsFromConvertIdPaths)
ASSERT_THAT(entriesAndIds.second, ElementsAre(ids[0], ids[1], ids[2]));
}
-TEST_F(ClangPathWatcher, NotWatchedPaths)
-{
- watcher.mergeToWatchedEntries(sorted({watcherEntry1}));
-
- auto newEntries = watcher.notWatchedPaths({watcherEntry2, watcherEntry3});
-
- ASSERT_THAT(newEntries, ElementsAre(watcherEntry3));
-}
-
-TEST_F(ClangPathWatcher, AddedPaths)
-{
- watcher.mergeToWatchedEntries(sorted({watcherEntry1, watcherEntry2}));
-
- auto filteredEntries = watcher.filterNotWatchedPaths({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4});
-
- ASSERT_THAT(filteredEntries, ElementsAre(watcherEntry3));
-}
-
TEST_F(ClangPathWatcher, MergeEntries)
{
- watcher.mergeToWatchedEntries(sorted({watcherEntry1, watcherEntry4}));
+ watcher.updateIdPaths({{id1, {pathIds[0]}}, {id2, {pathIds[1]}}});
ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry4));
}
TEST_F(ClangPathWatcher, MergeMoreEntries)
{
- watcher.mergeToWatchedEntries(sorted({watcherEntry1, watcherEntry4}));
+ watcher.updateIdPaths({{id2, {pathIds[0], pathIds[1]}}});
- watcher.mergeToWatchedEntries(sorted({watcherEntry2, watcherEntry3}));
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}});
ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4));
}
@@ -204,48 +222,48 @@ TEST_F(ClangPathWatcher, AddEmptyEntries)
EXPECT_CALL(mockQFileSytemWatcher, addPaths(_))
.Times(0);
- watcher.addEntries({});
+ watcher.updateIdPaths({});
}
TEST_F(ClangPathWatcher, AddEntriesWithSameIdAndDifferentPaths)
{
- EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1QString, path2QString}));
+ EXPECT_CALL(mockQFileSytemWatcher,
+ addPaths(ElementsAre(directoryPath, directoryPath2, directoryPath3)));
- watcher.addEntries({watcherEntry1, watcherEntry3});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2], pathIds[4]}}});
}
TEST_F(ClangPathWatcher, AddEntriesWithDifferentIdAndSamePaths)
{
- EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1QString}));
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(ElementsAre(directoryPath)));
- watcher.addEntries({watcherEntry1, watcherEntry2});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1]}}});
}
TEST_F(ClangPathWatcher, DontAddNewEntriesWithSameIdAndSamePaths)
{
- watcher.addEntries({watcherEntry1});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2], pathIds[3], pathIds[4]}}});
- EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1QString}))
- .Times(0);
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(_)).Times(0);
- watcher.addEntries({watcherEntry1});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2], pathIds[3], pathIds[4]}}});
}
TEST_F(ClangPathWatcher, DontAddNewEntriesWithDifferentIdAndSamePaths)
{
- watcher.addEntries({watcherEntry1});
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2], pathIds[3], pathIds[4]}}});
- EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1QString}))
- .Times(0);
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(_)).Times(0);
- watcher.addEntries({watcherEntry2});
+ watcher.updateIdPaths({{id2, {pathIds[0], pathIds[1], pathIds[2], pathIds[3], pathIds[4]}}});
}
TEST_F(ClangPathWatcher, RemoveEntriesWithId)
{
- watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5}));
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}, {id3, {pathIds[1]}}});
- watcher.removeIdsFromWatchedEntries({ids[0]});
+ watcher.removeIds({id1});
ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry2, watcherEntry4, watcherEntry5));
}
@@ -260,37 +278,52 @@ TEST_F(ClangPathWatcher, RemoveNoPathsForEmptyIds)
TEST_F(ClangPathWatcher, RemoveNoPathsForOneId)
{
- watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4}));
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
EXPECT_CALL(mockQFileSytemWatcher, removePaths(_))
.Times(0);
- watcher.removeIds({id1});
+ watcher.removeIds({id3});
}
TEST_F(ClangPathWatcher, RemovePathForOneId)
{
- watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3}));
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
- EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2QString}));
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath2)));
- watcher.removeIds({id1});
+ watcher.removeIds({id2});
+}
+
+TEST_F(ClangPathWatcher, RemoveNoPathSecondTime)
+{
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
+ watcher.removeIds({id2});
+
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(_)).Times(0);
+
+ watcher.removeIds({id2});
}
TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId)
{
- watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5}));
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1], pathIds[2]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
- EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path1QString, path2QString}));
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath, directoryPath2)));
watcher.removeIds({id1, id2, id3});
}
TEST_F(ClangPathWatcher, RemoveOnePathForTwoId)
{
- watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5}));
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1]}}, {id2, {pathIds[0], pathIds[1]}}, {id3, {pathIds[3]}}});
- EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path1QString}));
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(ElementsAre(directoryPath)));
watcher.removeIds({id1, id2});
}
@@ -313,71 +346,51 @@ TEST_F(ClangPathWatcher, RemoveUnusedEntries)
ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry4, watcherEntry5));
}
-TEST_F(ClangPathWatcher, EmptyVectorNotifyFileChange)
-{
- watcher.addEntries({watcherEntry3});
-
- EXPECT_CALL(notifier, pathsWithIdsChanged(IsEmpty()));
-
- mockQFileSytemWatcher.fileChanged(path1QString);
-}
-
-TEST_F(ClangPathWatcher, NotifyFileChange)
-{
- watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5}));
-
- EXPECT_CALL(notifier, pathsWithIdsChanged(ElementsAre(id1, id2)));
-
- mockQFileSytemWatcher.fileChanged(path1QString);
-}
-
TEST_F(ClangPathWatcher, TwoNotifyFileChanges)
{
- watcher.addEntries(sorted({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5}));
+ watcher.updateIdPaths({{id1, {pathIds[0], pathIds[1], pathIds[2]}},
+ {id2, {pathIds[0], pathIds[1], pathIds[3]}},
+ {id3, {pathIds[4]}}});
+ ON_CALL(mockFileSystem, lastModified(Eq(pathIds[0]))).WillByDefault(Return(2));
+ ON_CALL(mockFileSystem, lastModified(Eq(pathIds[1]))).WillByDefault(Return(2));
+ ON_CALL(mockFileSystem, lastModified(Eq(pathIds[3]))).WillByDefault(Return(2));
- EXPECT_CALL(notifier, pathsWithIdsChanged(ElementsAre(id1, id2, id3)));
+ EXPECT_CALL(notifier, pathsWithIdsChanged(ElementsAre(id1, id2)));
- mockQFileSytemWatcher.fileChanged(path2QString);
- mockQFileSytemWatcher.fileChanged(path1QString);
+ mockQFileSytemWatcher.directoryChanged(directoryPath);
+ mockQFileSytemWatcher.directoryChanged(directoryPath2);
}
TEST_F(ClangPathWatcher, NotifyForPathChanges)
{
- watcher.addEntries({watcherEntry1});
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1], pathIds[2]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
+ ON_CALL(mockFileSystem, lastModified(Eq(pathIds[0]))).WillByDefault(Return(2));
+ ON_CALL(mockFileSystem, lastModified(Eq(pathIds[3]))).WillByDefault(Return(2));
EXPECT_CALL(notifier, pathsChanged(ElementsAre(pathIds[0])));
- mockQFileSytemWatcher.fileChanged(path1QString);
+ mockQFileSytemWatcher.directoryChanged(directoryPath);
}
TEST_F(ClangPathWatcher, NoNotifyForUnwatchedPathChanges)
{
- watcher.addEntries({watcherEntry3});
+ watcher.updateIdPaths({{id1, {pathIds[3]}}, {id2, {pathIds[3]}}});
EXPECT_CALL(notifier, pathsChanged(IsEmpty()));
- mockQFileSytemWatcher.fileChanged(path1QString);
+ mockQFileSytemWatcher.directoryChanged(directoryPath);
}
TEST_F(ClangPathWatcher, NoDuplicatePathChanges)
{
- watcher.addEntries({watcherEntry1});
+ watcher.updateIdPaths(
+ {{id1, {pathIds[0], pathIds[1], pathIds[2]}}, {id2, {pathIds[0], pathIds[1], pathIds[3]}}});
+ ON_CALL(mockFileSystem, lastModified(Eq(pathIds[0]))).WillByDefault(Return(2));
EXPECT_CALL(notifier, pathsChanged(ElementsAre(pathIds[0])));
- mockQFileSytemWatcher.fileChanged(path1QString);
- mockQFileSytemWatcher.fileChanged(path1QString);
-}
-
-void ClangPathWatcher::SetUp()
-{
- ON_CALL(filePathCache, filePathId(Eq(path1)))
- .WillByDefault(Return(pathIds[0]));
- ON_CALL(filePathCache, filePathId(Eq(path2)))
- .WillByDefault(Return(pathIds[1]));
- ON_CALL(filePathCache, filePath(pathIds[0]))
- .WillByDefault(Return(FilePath{path1}));
- ON_CALL(filePathCache, filePath(Eq(pathIds[1])))
- .WillByDefault(Return(FilePath{path2}));
-}
+ mockQFileSytemWatcher.directoryChanged(directoryPath);
+ mockQFileSytemWatcher.directoryChanged(directoryPath);
}
+} // namespace
diff --git a/tests/unit/unittest/directorypathcompressor-test.cpp b/tests/unit/unittest/directorypathcompressor-test.cpp
new file mode 100644
index 0000000000..50853e8e1c
--- /dev/null
+++ b/tests/unit/unittest/directorypathcompressor-test.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include "mockfilesystem.h"
+#include "mocktimer.h"
+
+#include <directorypathcompressor.h>
+
+namespace {
+
+using testing::ElementsAre;
+using testing::Invoke;
+using testing::IsEmpty;
+using testing::NiceMock;
+
+using ClangBackEnd::DirectoryPathId;
+using ClangBackEnd::DirectoryPathIds;
+
+class DirectoryPathCompressor : public testing::Test
+{
+protected:
+ void SetUp()
+ {
+ compressor.setCallback(mockCompressorCallback.AsStdFunction());
+ }
+
+protected:
+ NiceMock<MockFunction<void(const DirectoryPathIds &directoryPathIds)>> mockCompressorCallback;
+ ClangBackEnd::DirectoryPathCompressor<NiceMock<MockTimer>> compressor;
+ NiceMock<MockTimer> &mockTimer = compressor.timer();
+ DirectoryPathId directoryPathId1{1};
+ DirectoryPathId directoryPathId2{2};
+};
+
+TEST_F(DirectoryPathCompressor, AddFilePath)
+{
+ compressor.addDirectoryPathId(directoryPathId1);
+
+ ASSERT_THAT(compressor.takeDirectoryPathIds(), ElementsAre(directoryPathId1));
+}
+
+TEST_F(DirectoryPathCompressor, NoFilePathsAferTakenThem)
+{
+ compressor.addDirectoryPathId(directoryPathId1);
+
+ compressor.takeDirectoryPathIds();
+
+ ASSERT_THAT(compressor.takeDirectoryPathIds(), IsEmpty());
+}
+
+TEST_F(DirectoryPathCompressor, CallRestartTimerAfterAddingPath)
+{
+ EXPECT_CALL(mockTimer, start(20));
+
+ compressor.addDirectoryPathId(directoryPathId1);
+}
+
+TEST_F(DirectoryPathCompressor, CallTimeOutAfterAddingPath)
+{
+ EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(directoryPathId1, directoryPathId2)));
+
+ compressor.addDirectoryPathId(directoryPathId1);
+ compressor.addDirectoryPathId(directoryPathId2);
+}
+
+TEST_F(DirectoryPathCompressor, RemoveDuplicates)
+{
+ EXPECT_CALL(mockCompressorCallback, Call(ElementsAre(directoryPathId1, directoryPathId2)));
+
+ compressor.addDirectoryPathId(directoryPathId1);
+ compressor.addDirectoryPathId(directoryPathId2);
+ compressor.addDirectoryPathId(directoryPathId1);
+}
+
+}
diff --git a/tests/unit/unittest/filepathcache-test.cpp b/tests/unit/unittest/filepathcache-test.cpp
index 43b5b026bb..478e5f0215 100644
--- a/tests/unit/unittest/filepathcache-test.cpp
+++ b/tests/unit/unittest/filepathcache-test.cpp
@@ -31,6 +31,7 @@
namespace {
+using ClangBackEnd::DirectoryPathId;
using ClangBackEnd::FilePathId;
using Cache = ClangBackEnd::FilePathCache<NiceMock<MockFilePathStorage>>;
using ClangBackEnd::FilePathId;
@@ -166,4 +167,153 @@ TEST_F(FilePathCache, DuplicateFilePathsAreEqual)
ASSERT_THAT(filePath2Id, Eq(filePath1Id));
}
+TEST_F(FilePathCache, DirectoryPathIdCallsFetchDirectoryId)
+{
+ EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("/path/to")));
+
+ cache.directoryPathId(Utils::SmallString("/path/to"));
+}
+
+TEST_F(FilePathCache, SecondDirectoryPathIdCallsNotFetchDirectoryId)
+{
+ cache.directoryPathId(Utils::SmallString("/path/to"));
+
+ EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("/path/to"))).Times(0);
+
+ cache.directoryPathId(Utils::SmallString("/path/to"));
+}
+
+TEST_F(FilePathCache, DirectoryPathIdWithTrailingSlash)
+{
+ EXPECT_CALL(mockStorage, fetchDirectoryId(Eq("/path/to")));
+
+ cache.directoryPathId(Utils::SmallString("/path/to/"));
+}
+
+TEST_F(FilePathCache, DirectoryPathId)
+{
+ auto id = cache.directoryPathId(Utils::SmallString("/path/to"));
+
+ ASSERT_THAT(id, Eq(DirectoryPathId{5}));
+}
+
+TEST_F(FilePathCache, DirectoryPathIdIsAlreadyInCache)
+{
+ auto firstId = cache.directoryPathId(Utils::SmallString("/path/to"));
+
+ auto secondId = cache.directoryPathId(Utils::SmallString("/path/to"));
+
+ ASSERT_THAT(secondId, firstId);
+}
+
+TEST_F(FilePathCache, DirectoryPathIdIsAlreadyInCacheWithTrailingSlash)
+{
+ auto firstId = cache.directoryPathId(Utils::SmallString("/path/to/"));
+
+ auto secondId = cache.directoryPathId(Utils::SmallString("/path/to/"));
+
+ ASSERT_THAT(secondId, firstId);
+}
+
+TEST_F(FilePathCache, DirectoryPathIdIsAlreadyInCacheWithAndWithoutTrailingSlash)
+{
+ auto firstId = cache.directoryPathId(Utils::SmallString("/path/to/"));
+
+ auto secondId = cache.directoryPathId(Utils::SmallString("/path/to"));
+
+ ASSERT_THAT(secondId, firstId);
+}
+
+TEST_F(FilePathCache, DirectoryPathIdIsAlreadyInCacheWithoutAndWithTrailingSlash)
+{
+ auto firstId = cache.directoryPathId(Utils::SmallString("/path/to"));
+
+ auto secondId = cache.directoryPathId(Utils::SmallString("/path/to/"));
+
+ ASSERT_THAT(secondId, firstId);
+}
+
+TEST_F(FilePathCache, ThrowForGettingADirectoryPathWithAnInvalidId)
+{
+ DirectoryPathId directoryPathId;
+
+ ASSERT_THROW(cache.directoryPath(directoryPathId),
+ ClangBackEnd::NoDirectoryPathForInvalidDirectoryPathId);
+}
+
+TEST_F(FilePathCache, GetADirectoryPath)
+{
+ DirectoryPathId directoryPathId{5};
+
+ auto directoryPath = cache.directoryPath(directoryPathId);
+
+ ASSERT_THAT(directoryPath, Eq(Utils::SmallStringView{"/path/to"}));
+}
+
+TEST_F(FilePathCache, GetADirectoryPathWithCachedDirectoryPathId)
+{
+ DirectoryPathId directoryPathId{5};
+ cache.directoryPath(directoryPathId);
+
+ auto directoryPath = cache.directoryPath(directoryPathId);
+
+ ASSERT_THAT(directoryPath, Eq(Utils::SmallStringView{"/path/to"}));
+}
+
+TEST_F(FilePathCache, DirectoryPathCallsFetchDirectoryPath)
+{
+ EXPECT_CALL(mockStorage, fetchDirectoryPath(Eq(DirectoryPathId{5})));
+
+ cache.directoryPath(5);
+}
+
+TEST_F(FilePathCache, SecondDirectoryPathCallsNotFetchDirectoryPath)
+{
+ cache.directoryPath(5);
+
+ EXPECT_CALL(mockStorage, fetchDirectoryPath(_)).Times(0);
+
+ cache.directoryPath(5);
+}
+
+TEST_F(FilePathCache, ThrowForGettingADirectoryPathIdWithAnInvalidFilePathId)
+{
+ FilePathId filePathId;
+
+ ASSERT_THROW(cache.directoryPathId(filePathId), ClangBackEnd::NoFilePathForInvalidFilePathId);
+}
+
+TEST_F(FilePathCache, FetchDirectoryPathIdByFilePathId)
+{
+ auto directoryId = cache.directoryPathId(42);
+
+ ASSERT_THAT(directoryId, Eq(5));
+}
+
+TEST_F(FilePathCache, FetchDirectoryPathIdByFilePathIdCached)
+{
+ cache.directoryPathId(42);
+
+ auto directoryId = cache.directoryPathId(42);
+
+ ASSERT_THAT(directoryId, Eq(5));
+}
+
+TEST_F(FilePathCache, FetchFilePathAfterFetchingDirectoryIdByFilePathId)
+{
+ cache.directoryPathId(42);
+
+ auto filePath = cache.filePath(42);
+
+ ASSERT_THAT(filePath, Eq("/path/to/file.cpp"));
+}
+
+TEST_F(FilePathCache, FetchDirectoryPathIdAfterFetchingFilePathByFilePathId)
+{
+ cache.filePath(42);
+
+ auto directoryId = cache.directoryPathId(42);
+
+ ASSERT_THAT(directoryId, Eq(5));
}
+} // namespace
diff --git a/tests/unit/unittest/filepathstorage-test.cpp b/tests/unit/unittest/filepathstorage-test.cpp
index 37f325daf0..fb60e32512 100644
--- a/tests/unit/unittest/filepathstorage-test.cpp
+++ b/tests/unit/unittest/filepathstorage-test.cpp
@@ -46,8 +46,8 @@ protected:
void SetUp()
{
ON_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(_))
- .WillByDefault(Return(Utils::optional<int>()));
+ valueReturnInt32(A<Utils::SmallStringView>()))
+ .WillByDefault(Return(Utils::optional<int>()));
ON_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
valueReturnInt32(Utils::SmallStringView("")))
.WillByDefault(Return(Utils::optional<int>(0)));
@@ -77,9 +77,12 @@ protected:
ON_CALL(selectSourceNameAndDirectoryIdFromSourcesBySourceId,
valueReturnSourceNameAndDirectoryId(42))
.WillByDefault(Return(Utils::optional<ClangBackEnd::Sources::SourceNameAndDirectoryId>({"file.cpp", 5})));
+ ON_CALL(selectDirectoryIdFromSourcesBySourceId, valueReturnInt32(TypedEq<int>(42)))
+ .WillByDefault(Return(Utils::optional<int>(5)));
- EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, valueReturnInt32(_))
- .Times(AnyNumber());
+ EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
+ valueReturnInt32(A<Utils::SmallStringView>()))
+ .Times(AnyNumber());
EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, valueReturnInt32(_, _))
.Times(AnyNumber());
EXPECT_CALL(insertIntoDirectories, write(An<Utils::SmallStringView>()))
@@ -107,6 +110,7 @@ protected:
MockSqliteWriteStatement &insertIntoDirectories = factory.insertIntoDirectories;
MockSqliteWriteStatement &insertIntoSources = factory.insertIntoSources;
MockSqliteReadStatement &selectAllSources = factory.selectAllSources;
+ MockSqliteReadStatement &selectDirectoryIdFromSourcesBySourceId = factory.selectDirectoryIdFromSourcesBySourceId;
Storage storage{factory};
};
@@ -229,7 +233,7 @@ TEST_F(FilePathStorage, CallSelectForFetchingDirectoryIdForKnownPath)
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(Eq("/path/to")));
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/path/to")));
EXPECT_CALL(mockDatabase, commit());
storage.fetchDirectoryId("/path/to");
@@ -267,7 +271,7 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdForUnknownPath)
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(Eq("/some/not/known/path")));
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/some/not/known/path")));
EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/some/not/known/path")));
EXPECT_CALL(mockDatabase, commit());
@@ -296,7 +300,7 @@ TEST_F(FilePathStorage, RestartFetchDirectoryIDIfTheStatementIsBusyInBeginBecaus
EXPECT_CALL(mockDatabase, rollback()).Times(0);
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(Eq("/other/unknow/path")));
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/other/unknow/path")));
EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path")));
EXPECT_CALL(mockDatabase, commit());
@@ -310,13 +314,13 @@ TEST_F(FilePathStorage,
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(Eq("/other/unknow/path")));
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/other/unknow/path")));
EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path")))
.WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
EXPECT_CALL(mockDatabase, rollback());
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(Eq("/other/unknow/path")));
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/other/unknow/path")));
EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path")));
EXPECT_CALL(mockDatabase, commit());
@@ -329,13 +333,13 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdTwoTimesIfTheInd
EXPECT_CALL(mockDatabase,deferredBegin());
EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(Eq("/other/unknow/path")));
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/other/unknow/path")));
EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path")))
.WillOnce(Throw(Sqlite::ConstraintPreventsModification("busy")));
EXPECT_CALL(mockDatabase, rollback());
EXPECT_CALL(mockDatabase,deferredBegin());
EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath,
- valueReturnInt32(Eq("/other/unknow/path")));
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("/other/unknow/path")));
EXPECT_CALL(mockDatabase, commit());
storage.fetchDirectoryId("/other/unknow/path");
@@ -368,7 +372,6 @@ TEST_F(FilePathStorage,
EXPECT_CALL(insertIntoSources,
write(TypedEq<int>(5), TypedEq<Utils::SmallStringView>("otherunknownfile.h")))
.WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
- ;
EXPECT_CALL(mockDatabase, rollback());
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
@@ -545,4 +548,59 @@ TEST_F(FilePathStorage, RestartFetchAllSourcesIfBeginIsBusy)
storage.fetchAllSources();
}
+TEST_F(FilePathStorage, FetchDirectoryIdForUnknownFileID)
+{
+ ASSERT_THROW(storage.fetchDirectoryId(1111), ClangBackEnd::SourceNameIdDoesNotExists);
+}
+
+TEST_F(FilePathStorage, FetchDirectoryId)
+{
+ auto directoryId = storage.fetchDirectoryId(42);
+
+ ASSERT_THAT(directoryId, 5);
+}
+
+TEST_F(FilePathStorage, FetchDirectoryIdCalls)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, lock());
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(selectDirectoryIdFromSourcesBySourceId, valueReturnInt32(TypedEq<int>(42)));
+ EXPECT_CALL(mockDatabase, commit());
+ EXPECT_CALL(mockDatabase, unlock());
+
+ storage.fetchDirectoryId(42);
}
+
+TEST_F(FilePathStorage, FetchDirectoryIdCallsDatabaseIsBusy)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, lock());
+ EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
+ EXPECT_CALL(mockDatabase, rollback()).Times(0);
+ EXPECT_CALL(mockDatabase, unlock());
+ EXPECT_CALL(mockDatabase, lock());
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(selectDirectoryIdFromSourcesBySourceId, valueReturnInt32(TypedEq<int>(42)));
+ EXPECT_CALL(mockDatabase, commit());
+ EXPECT_CALL(mockDatabase, unlock());
+
+ storage.fetchDirectoryId(42);
+}
+
+TEST_F(FilePathStorage, FetchDirectoryIdCallsThrows)
+{
+ InSequence s;
+
+ EXPECT_CALL(mockDatabase, lock());
+ EXPECT_CALL(mockDatabase, deferredBegin());
+ EXPECT_CALL(selectDirectoryIdFromSourcesBySourceId, valueReturnInt32(TypedEq<int>(41)));
+ EXPECT_CALL(mockDatabase, rollback());
+ EXPECT_CALL(mockDatabase, unlock());
+
+ ASSERT_ANY_THROW(storage.fetchDirectoryId(41));
+}
+
+} // namespace
diff --git a/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp b/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp
index ac902fa700..40af2d99c3 100644
--- a/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp
+++ b/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp
@@ -61,7 +61,13 @@ TEST_F(FilePathStorageSqliteStatementFactory, SelectSourceIdFromSourcesByDirecto
Eq("SELECT sourceId FROM sources WHERE directoryId = ? AND sourceName = ?"));
}
-TEST_F(FilePathStorageSqliteStatementFactory, SelectSourceNameFromSourcesByDirectoryIdAndSourceId)
+TEST_F(FilePathStorageSqliteStatementFactory, SelectSourceNameAndDirectoryIdFromSourcesByAndSourceId)
+{
+ ASSERT_THAT(factory.selectSourceNameAndDirectoryIdFromSourcesBySourceId.sqlStatement,
+ Eq("SELECT sourceName, directoryId FROM sources WHERE sourceId = ?"));
+}
+
+TEST_F(FilePathStorageSqliteStatementFactory, SelectSourceNameAndDirectoryIdBySourceId)
{
ASSERT_THAT(factory.selectSourceNameAndDirectoryIdFromSourcesBySourceId.sqlStatement,
Eq("SELECT sourceName, directoryId FROM sources WHERE sourceId = ?"));
diff --git a/tests/unit/unittest/filestatuscache-test.cpp b/tests/unit/unittest/filestatuscache-test.cpp
index db13bc28a7..07ba02655b 100644
--- a/tests/unit/unittest/filestatuscache-test.cpp
+++ b/tests/unit/unittest/filestatuscache-test.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "googletest.h"
+#include "mockfilesystem.h"
#include <filepathcaching.h>
#include <filestatuscache.h>
@@ -37,31 +38,33 @@
namespace {
using ClangBackEnd::FilePathId;
+using ClangBackEnd::FilePathIds;
class FileStatusCache : public testing::Test
{
protected:
- FilePathId filePathId(Utils::SmallStringView path) const
+ FileStatusCache()
{
- return filePathCache.filePathId(ClangBackEnd::FilePathView(path));
- }
-
- void touchFile(FilePathId filePathId)
- {
- std::ofstream ostream(std::string(filePathCache.filePath(filePathId)), std::ios::binary);
- ostream.write("\n", 1);
- ostream.close();
+ ON_CALL(fileSystem, lastModified(Eq(header))).WillByDefault(Return(headerLastModifiedTime));
+ ON_CALL(fileSystem, lastModified(Eq(source))).WillByDefault(Return(sourceLastModifiedTime));
+ ON_CALL(fileSystem, lastModified(Eq(header2))).WillByDefault(Return(header2LastModifiedTime));
+ ON_CALL(fileSystem, lastModified(Eq(source2))).WillByDefault(Return(source2LastModifiedTime));
}
protected:
- Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
- ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
- ClangBackEnd::FilePathCaching filePathCache{database};
- ClangBackEnd::FileStatusCache cache{filePathCache};
- FilePathId header{filePathId(TESTDATA_DIR "/filestatuscache_header.h")};
- FilePathId source{filePathId(TESTDATA_DIR "/filestatuscache_header.cpp")};
- long long headerLastModifiedTime = QFileInfo(TESTDATA_DIR "/filestatuscache_header.h").lastModified().toSecsSinceEpoch();
- long long sourceLastModifiedTime = QFileInfo(TESTDATA_DIR "/filestatuscache_header.cpp").lastModified().toSecsSinceEpoch();
+ NiceMock<MockFileSystem> fileSystem;
+ ClangBackEnd::FileStatusCache cache{fileSystem};
+ FilePathId header{1};
+ FilePathId source{2};
+ FilePathId header2{3};
+ FilePathId source2{4};
+ FilePathIds entries{header, source, header2, source2};
+ long long headerLastModifiedTime = 100;
+ long long headerLastModifiedTime2 = 110;
+ long long header2LastModifiedTime = 300;
+ long long header2LastModifiedTime2 = 310;
+ long long sourceLastModifiedTime = 200;
+ long long source2LastModifiedTime = 400;
};
TEST_F(FileStatusCache, CreateEntry)
@@ -134,18 +137,24 @@ TEST_F(FileStatusCache, AskNewEntryReverseOrderAddedForLastModifiedTime)
TEST_F(FileStatusCache, UpdateFile)
{
- auto oldLastModified = cache.lastModifiedTime(header);
- touchFile(header);
+ EXPECT_CALL(fileSystem, lastModified(Eq(header)))
+ .Times(2)
+ .WillOnce(Return(headerLastModifiedTime))
+ .WillOnce(Return(headerLastModifiedTime2));
+ cache.lastModifiedTime(header);
cache.update(header);
- ASSERT_THAT(cache.lastModifiedTime(header), Gt(oldLastModified));
+ ASSERT_THAT(cache.lastModifiedTime(header), headerLastModifiedTime2);
}
TEST_F(FileStatusCache, UpdateFileDoesNotChangeEntryCount)
{
+ EXPECT_CALL(fileSystem, lastModified(Eq(header)))
+ .Times(2)
+ .WillOnce(Return(headerLastModifiedTime))
+ .WillOnce(Return(headerLastModifiedTime2));
cache.lastModifiedTime(header);
- touchFile(header);
cache.update(header);
@@ -154,11 +163,136 @@ TEST_F(FileStatusCache, UpdateFileDoesNotChangeEntryCount)
TEST_F(FileStatusCache, UpdateFileForNonExistingEntry)
{
- touchFile(header);
-
cache.update(header);
ASSERT_THAT(cache, SizeIs(0));
}
+TEST_F(FileStatusCache, UpdateFiles)
+{
+ EXPECT_CALL(fileSystem, lastModified(Eq(header)))
+ .Times(2)
+ .WillOnce(Return(headerLastModifiedTime))
+ .WillOnce(Return(headerLastModifiedTime2));
+ EXPECT_CALL(fileSystem, lastModified(Eq(header2)))
+ .Times(2)
+ .WillOnce(Return(header2LastModifiedTime))
+ .WillOnce(Return(header2LastModifiedTime2));
+ cache.lastModifiedTime(header);
+ cache.lastModifiedTime(header2);
+
+ cache.update(entries);
+
+ ASSERT_THAT(cache.lastModifiedTime(header), headerLastModifiedTime2);
+ ASSERT_THAT(cache.lastModifiedTime(header2), header2LastModifiedTime2);
}
+
+TEST_F(FileStatusCache, UpdateFilesDoesNotChangeEntryCount)
+{
+ EXPECT_CALL(fileSystem, lastModified(Eq(header)))
+ .Times(2)
+ .WillOnce(Return(headerLastModifiedTime))
+ .WillOnce(Return(headerLastModifiedTime2));
+ EXPECT_CALL(fileSystem, lastModified(Eq(header2)))
+ .Times(2)
+ .WillOnce(Return(header2LastModifiedTime))
+ .WillOnce(Return(header2LastModifiedTime2));
+ cache.lastModifiedTime(header);
+ cache.lastModifiedTime(header2);
+
+ cache.update(entries);
+
+ ASSERT_THAT(cache, SizeIs(2));
+}
+
+TEST_F(FileStatusCache, UpdateFilesForNonExistingEntry)
+{
+ cache.update(entries);
+
+ ASSERT_THAT(cache, SizeIs(0));
+}
+
+TEST_F(FileStatusCache, NewModifiedEntries)
+{
+ auto modifiedIds = cache.modified(entries);
+
+ ASSERT_THAT(modifiedIds, entries);
+}
+
+TEST_F(FileStatusCache, NoNewModifiedEntries)
+{
+ cache.modified(entries);
+
+ auto modifiedIds = cache.modified(entries);
+
+ ASSERT_THAT(modifiedIds, IsEmpty());
+}
+
+TEST_F(FileStatusCache, SomeNewModifiedEntries)
+{
+ cache.modified({source, header2});
+
+ auto modifiedIds = cache.modified(entries);
+
+ ASSERT_THAT(modifiedIds, ElementsAre(header, source2));
+}
+
+TEST_F(FileStatusCache, SomeAlreadyExistingModifiedEntries)
+{
+ EXPECT_CALL(fileSystem, lastModified(Eq(header)))
+ .Times(2)
+ .WillOnce(Return(headerLastModifiedTime))
+ .WillOnce(Return(headerLastModifiedTime2));
+ EXPECT_CALL(fileSystem, lastModified(Eq(header2)))
+ .Times(2)
+ .WillOnce(Return(header2LastModifiedTime))
+ .WillOnce(Return(header2LastModifiedTime2));
+ EXPECT_CALL(fileSystem, lastModified(Eq(source))).Times(2).WillRepeatedly(Return(sourceLastModifiedTime));
+ EXPECT_CALL(fileSystem, lastModified(Eq(source2)))
+ .Times(2)
+ .WillRepeatedly(Return(source2LastModifiedTime));
+ cache.modified(entries);
+
+ auto modifiedIds = cache.modified(entries);
+
+ ASSERT_THAT(modifiedIds, ElementsAre(header, header2));
+}
+
+TEST_F(FileStatusCache, SomeAlreadyExistingAndSomeNewModifiedEntries)
+{
+ EXPECT_CALL(fileSystem, lastModified(Eq(header))).WillRepeatedly(Return(headerLastModifiedTime));
+ EXPECT_CALL(fileSystem, lastModified(Eq(header2)))
+ .Times(2)
+ .WillOnce(Return(header2LastModifiedTime))
+ .WillOnce(Return(header2LastModifiedTime2));
+ EXPECT_CALL(fileSystem, lastModified(Eq(source))).Times(2).WillRepeatedly(Return(sourceLastModifiedTime));
+ EXPECT_CALL(fileSystem, lastModified(Eq(source2))).WillRepeatedly(Return(source2LastModifiedTime));
+ cache.modified({source, header2});
+
+ auto modifiedIds = cache.modified(entries);
+
+ ASSERT_THAT(modifiedIds, ElementsAre(header, header2, source2));
+}
+
+TEST_F(FileStatusCache, TimeIsUpdatedForSomeAlreadyExistingModifiedEntries)
+{
+ EXPECT_CALL(fileSystem, lastModified(Eq(header)))
+ .Times(2)
+ .WillOnce(Return(headerLastModifiedTime))
+ .WillOnce(Return(headerLastModifiedTime2));
+ EXPECT_CALL(fileSystem, lastModified(Eq(header2)))
+ .Times(2)
+ .WillOnce(Return(header2LastModifiedTime))
+ .WillOnce(Return(header2LastModifiedTime2));
+ EXPECT_CALL(fileSystem, lastModified(Eq(source))).Times(2).WillRepeatedly(Return(sourceLastModifiedTime));
+ EXPECT_CALL(fileSystem, lastModified(Eq(source2)))
+ .Times(2)
+ .WillRepeatedly(Return(source2LastModifiedTime));
+ cache.modified(entries);
+
+ cache.modified(entries);
+
+ ASSERT_THAT(cache.lastModifiedTime(header), headerLastModifiedTime2);
+}
+
+} // namespace
diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp
index 7ac4a676e3..0ab962dfa5 100644
--- a/tests/unit/unittest/gtest-creator-printing.cpp
+++ b/tests/unit/unittest/gtest-creator-printing.cpp
@@ -361,7 +361,7 @@ std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry)
{
out << "("
<< entry.id << ", "
- << entry.pathId
+ << entry.filePathId
<< ")";
return out;
diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h
index 897a9f2a28..b874fc90e4 100644
--- a/tests/unit/unittest/gtest-creator-printing.h
+++ b/tests/unit/unittest/gtest-creator-printing.h
@@ -49,7 +49,7 @@ std::ostream &operator<<(std::ostream &out, const CompileCommand &command);
} // namespace clang
namespace Core {
-class LocatorFilterEntry;
+struct LocatorFilterEntry;
std::ostream &operator<<(std::ostream &out, const LocatorFilterEntry &entry);
diff --git a/tests/unit/unittest/mockbuilddependenciesstorage.h b/tests/unit/unittest/mockbuilddependenciesstorage.h
index a4d34e481d..dd2850d88c 100644
--- a/tests/unit/unittest/mockbuilddependenciesstorage.h
+++ b/tests/unit/unittest/mockbuilddependenciesstorage.h
@@ -51,7 +51,7 @@ public:
ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName));
MOCK_METHOD2(updatePchCreationTimeStamp,
void(long long pchCreationTimeStamp, ClangBackEnd::ProjectPartId projectPartId));
- MOCK_CONST_METHOD1(fetchSources,
+ MOCK_CONST_METHOD1(fetchPchSources,
ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId));
};
diff --git a/tests/unit/unittest/mockfilepathcaching.h b/tests/unit/unittest/mockfilepathcaching.h
index 1b22e910ee..ca7960513e 100644
--- a/tests/unit/unittest/mockfilepathcaching.h
+++ b/tests/unit/unittest/mockfilepathcaching.h
@@ -36,5 +36,11 @@ public:
ClangBackEnd::FilePathId (ClangBackEnd::FilePathView filePath));
MOCK_CONST_METHOD1(filePath,
ClangBackEnd::FilePath (ClangBackEnd::FilePathId filePathId));
+ MOCK_CONST_METHOD1(directoryPathId,
+ ClangBackEnd::DirectoryPathId(Utils::SmallStringView directoryPath));
+ MOCK_CONST_METHOD1(directoryPath,
+ Utils::PathString(ClangBackEnd::DirectoryPathId directoryPathId));
+ MOCK_CONST_METHOD1(directoryPathId,
+ ClangBackEnd::DirectoryPathId(ClangBackEnd::FilePathId filePathId));
};
diff --git a/tests/unit/unittest/mockfilesystem.h b/tests/unit/unittest/mockfilesystem.h
new file mode 100644
index 0000000000..688edbcae5
--- /dev/null
+++ b/tests/unit/unittest/mockfilesystem.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** 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 "googletest.h"
+
+#include <filesysteminterface.h>
+
+class MockFileSystem : public ClangBackEnd::FileSystemInterface
+{
+public:
+ MOCK_CONST_METHOD1(directoryEntries, ClangBackEnd::FilePathIds(const QString &directoryPath));
+ MOCK_CONST_METHOD1(lastModified, long long(ClangBackEnd::FilePathId filePathId));
+};
diff --git a/tests/unit/unittest/mockmodifiedtimechecker.h b/tests/unit/unittest/mockmodifiedtimechecker.h
index bf101988b1..1fa3dd497c 100644
--- a/tests/unit/unittest/mockmodifiedtimechecker.h
+++ b/tests/unit/unittest/mockmodifiedtimechecker.h
@@ -35,6 +35,7 @@ class MockSourceEntriesModifiedTimeChecker
public:
MOCK_CONST_METHOD1(isUpToDate,
bool (const ClangBackEnd::SourceEntries &sourceEntries));
+ MOCK_METHOD1(pathsChanged, void(const ClangBackEnd::FilePathIds &filePathIds));
};
class MockSourceTimeStampsModifiedTimeChecker
@@ -42,4 +43,5 @@ class MockSourceTimeStampsModifiedTimeChecker
{
public:
MOCK_CONST_METHOD1(isUpToDate, bool(const ClangBackEnd::SourceTimeStamps &sourceTimeStamps));
+ MOCK_METHOD1(pathsChanged, void(const ClangBackEnd::FilePathIds &filePathIds));
};
diff --git a/tests/unit/unittest/mockqfilesystemwatcher.h b/tests/unit/unittest/mockqfilesystemwatcher.h
index 1bb90b2c37..00f4c600b4 100644
--- a/tests/unit/unittest/mockqfilesystemwatcher.h
+++ b/tests/unit/unittest/mockqfilesystemwatcher.h
@@ -41,4 +41,5 @@ public:
signals:
void fileChanged(const QString &);
+ void directoryChanged(const QString &);
};
diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp
index b0df1ab75d..1e800e2be1 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.cpp
+++ b/tests/unit/unittest/mocksqlitereadstatement.cpp
@@ -137,6 +137,12 @@ MockSqliteReadStatement::value<int>(const int &directoryId, const Utils::SmallSt
return valueReturnInt32(directoryId, text);
}
+template<>
+Utils::optional<int> MockSqliteReadStatement::value<int>(const int &value)
+{
+ return valueReturnInt32(value);
+}
+
template <>
Utils::optional<long long>
MockSqliteReadStatement::value<long long>(const int &sourceId)
diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h
index d952c90dec..191c38accd 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.h
+++ b/tests/unit/unittest/mocksqlitereadstatement.h
@@ -92,11 +92,11 @@ public:
MOCK_METHOD1(valueReturnInt32, Utils::optional<int>(Utils::SmallStringView));
- MOCK_METHOD2(valueReturnInt32,
- Utils::optional<int>(int, Utils::SmallStringView));
+ MOCK_METHOD2(valueReturnInt32, Utils::optional<int>(int, Utils::SmallStringView));
- MOCK_METHOD1(valueReturnInt64,
- Utils::optional<long long>(int));
+ MOCK_METHOD1(valueReturnInt32, Utils::optional<int>(int));
+
+ MOCK_METHOD1(valueReturnInt64, Utils::optional<long long>(int));
MOCK_METHOD1(valueReturnPathString,
Utils::optional<Utils::PathString>(int));
@@ -244,6 +244,9 @@ template <>
Utils::optional<int>
MockSqliteReadStatement::value<int>(const int&, const Utils::SmallStringView&);
+template<>
+Utils::optional<int> MockSqliteReadStatement::value<int>(const int &);
+
template <>
Utils::optional<long long>
MockSqliteReadStatement::value<long long>(const ClangBackEnd::FilePathId&);
diff --git a/tests/unit/unittest/modifiedtimechecker-test.cpp b/tests/unit/unittest/modifiedtimechecker-test.cpp
index ff0c3c66d8..0e18228ac3 100644
--- a/tests/unit/unittest/modifiedtimechecker-test.cpp
+++ b/tests/unit/unittest/modifiedtimechecker-test.cpp
@@ -24,6 +24,7 @@
****************************************************************************/
#include "googletest.h"
+#include "mockfilesystem.h"
#include <filepathcaching.h>
#include <modifiedtimechecker.h>
@@ -39,29 +40,24 @@ using ClangBackEnd::FilePathView;
class ModifiedTimeChecker : public testing::Test
{
protected:
-
- ClangBackEnd::FilePathId id(const Utils::SmallStringView &path) const
- {
- return filePathCache.filePathId(ClangBackEnd::FilePathView{path});
- }
-
-
ModifiedTimeChecker()
{
- ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1")))).WillByDefault(Return(50));
- ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2")))).WillByDefault(Return(30));
+ ON_CALL(mockFileSystem, lastModified(Eq(1))).WillByDefault(Return(50));
+ ON_CALL(mockFileSystem, lastModified(Eq(2))).WillByDefault(Return(30));
+ ON_CALL(mockFileSystem, lastModified(Eq(3))).WillByDefault(Return(50));
+ ON_CALL(mockFileSystem, lastModified(Eq(4))).WillByDefault(Return(30));
}
- NiceMock<MockFunction<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>> getModifiedTimeCallback;
- Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
- ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
- ClangBackEnd::FilePathCaching filePathCache{database};
- decltype(getModifiedTimeCallback.AsStdFunction()) callback = getModifiedTimeCallback
- .AsStdFunction();
- ClangBackEnd::ModifiedTimeChecker<> checker{callback, filePathCache};
- SourceEntries upToDateEntries = {{id("/path1"), SourceType::UserInclude, 100},
- {id("/path2"), SourceType::SystemInclude, 30}};
- SourceEntries notUpToDateEntries = {{id("/path1"), SourceType::UserInclude, 50},
- {id("/path2"), SourceType::SystemInclude, 20}};
+
+ NiceMock<MockFileSystem> mockFileSystem;
+ ClangBackEnd::ModifiedTimeChecker<> checker{mockFileSystem};
+ SourceEntries upToDateEntries = {{1, SourceType::UserInclude, 100},
+ {2, SourceType::SystemInclude, 30},
+ {3, SourceType::UserInclude, 100},
+ {4, SourceType::SystemInclude, 30}};
+ SourceEntries notUpToDateEntries = {{1, SourceType::UserInclude, 50},
+ {2, SourceType::SystemInclude, 20},
+ {3, SourceType::UserInclude, 100},
+ {4, SourceType::SystemInclude, 30}};
};
TEST_F(ModifiedTimeChecker, IsUpToDate)
@@ -71,6 +67,15 @@ TEST_F(ModifiedTimeChecker, IsUpToDate)
ASSERT_TRUE(isUpToDate);
}
+TEST_F(ModifiedTimeChecker, IsUpToDateSecondRun)
+{
+ checker.isUpToDate(upToDateEntries);
+
+ auto isUpToDate = checker.isUpToDate(upToDateEntries);
+
+ ASSERT_TRUE(isUpToDate);
+}
+
TEST_F(ModifiedTimeChecker, IsNotUpToDateIfSourceEntriesAreEmpty)
{
auto isUpToDate = checker.isUpToDate({});
@@ -80,7 +85,16 @@ TEST_F(ModifiedTimeChecker, IsNotUpToDateIfSourceEntriesAreEmpty)
TEST_F(ModifiedTimeChecker, IsNotUpToDate)
{
- auto isUpToDate = checker.isUpToDate({});
+ auto isUpToDate = checker.isUpToDate(notUpToDateEntries);
+
+ ASSERT_FALSE(isUpToDate);
+}
+
+TEST_F(ModifiedTimeChecker, IsNotUpToDateSecondRun)
+{
+ checker.isUpToDate(notUpToDateEntries);
+
+ auto isUpToDate = checker.isUpToDate(notUpToDateEntries);
ASSERT_FALSE(isUpToDate);
}
@@ -89,21 +103,80 @@ TEST_F(ModifiedTimeChecker, PathChangesUpdatesTimeStamps)
{
checker.isUpToDate(upToDateEntries);
- EXPECT_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1"))));
- EXPECT_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2"))));
+ EXPECT_CALL(mockFileSystem, lastModified(Eq(2)));
+ EXPECT_CALL(mockFileSystem, lastModified(Eq(3)));
- checker.pathsChanged({id(FilePathView("/path1")), id(FilePathView("/path2")), id(FilePathView("/path3"))});
+ checker.pathsChanged({2, 3});
}
TEST_F(ModifiedTimeChecker, IsNotUpToDateAnyMoreAfterUpdating)
{
checker.isUpToDate(upToDateEntries);
- ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1")))).WillByDefault(Return(120));
- ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2")))).WillByDefault(Return(30));
+ ON_CALL(mockFileSystem, lastModified(Eq(1))).WillByDefault(Return(120));
+ ON_CALL(mockFileSystem, lastModified(Eq(2))).WillByDefault(Return(30));
- checker.pathsChanged({id(FilePathView("/path1")), id(FilePathView("/path2")), id(FilePathView("/path3"))});
+ checker.pathsChanged({1, 2, 3});
ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
}
+TEST_F(ModifiedTimeChecker, Reset)
+{
+ checker.isUpToDate(upToDateEntries);
+
+ checker.reset({2, 3});
+
+ ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
+}
+
+TEST_F(ModifiedTimeChecker, UpdateNonResetedId)
+{
+ checker.isUpToDate(upToDateEntries);
+
+ checker.reset({2, 3});
+
+ ASSERT_TRUE(checker.isUpToDate({upToDateEntries[0]}));
+}
+
+TEST_F(ModifiedTimeChecker, ResetTwoTimes)
+{
+ checker.isUpToDate(upToDateEntries);
+ checker.reset({2, 3});
+
+ checker.reset({2, 3});
+
+ ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
+ ASSERT_TRUE(checker.isUpToDate(upToDateEntries));
+}
+
+TEST_F(ModifiedTimeChecker, ResetSecondUpdate)
+{
+ checker.isUpToDate(upToDateEntries);
+ checker.reset({2, 3});
+ checker.isUpToDate(upToDateEntries);
+
+ auto isUpToDate = checker.isUpToDate(upToDateEntries);
+
+ ASSERT_TRUE(isUpToDate);
+}
+
+TEST_F(ModifiedTimeChecker, ResetPartialUpdate)
+{
+ checker.isUpToDate(upToDateEntries);
+ checker.reset({2, 3});
+ checker.isUpToDate({upToDateEntries[1]});
+
+ ASSERT_FALSE(checker.isUpToDate({upToDateEntries[2]}));
+}
+
+TEST_F(ModifiedTimeChecker, ResetMoreIds)
+{
+ checker.isUpToDate(upToDateEntries);
+ checker.reset({2, 3});
+
+ checker.reset({1, 5});
+
+ ASSERT_FALSE(checker.isUpToDate({upToDateEntries[2]}));
+}
+
} // namespace
diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp
index 0cf84a983d..04e198eec7 100644
--- a/tests/unit/unittest/pchcreator-test.cpp
+++ b/tests/unit/unittest/pchcreator-test.cpp
@@ -226,16 +226,21 @@ TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterSucess)
creator.doInMainThreadAfterFinished();
}
-TEST_F(PchCreatorVerySlowTest, SourcesAreNotWatchedAfterFail)
+TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterFail)
{
pchTask1.systemIncludeSearchPaths = {};
pchTask1.projectIncludeSearchPaths = {};
creator.generatePch(std::move(pchTask1));
EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(
- ElementsAre(AllOf(Field(&ClangBackEnd::IdPaths::id, 1),
- Field(&ClangBackEnd::IdPaths::filePathIds, IsEmpty())))));
+ updateIdPaths(ElementsAre(AllOf(
+ Field(&ClangBackEnd::IdPaths::id, 1),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp")))))));
creator.doInMainThreadAfterFinished();
}
@@ -337,9 +342,14 @@ TEST_F(PchCreatorSlowTest, NoIncludesInTheMainThreadCalls)
Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds,
ElementsAre(Eq(creator.projectPartPch().projectPartId)))));
EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(
- ElementsAre(AllOf(Field(&ClangBackEnd::IdPaths::id, 1),
- Field(&ClangBackEnd::IdPaths::filePathIds, IsEmpty())))));
+ updateIdPaths(ElementsAre(AllOf(
+ Field(&ClangBackEnd::IdPaths::id, 1),
+ Field(&ClangBackEnd::IdPaths::filePathIds,
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp")))))));
EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1)));
creator.doInMainThreadAfterFinished();
diff --git a/tests/unit/unittest/pchtaskgenerator-test.cpp b/tests/unit/unittest/pchtaskgenerator-test.cpp
index 8f5f0754af..cb9df32235 100644
--- a/tests/unit/unittest/pchtaskgenerator-test.cpp
+++ b/tests/unit/unittest/pchtaskgenerator-test.cpp
@@ -117,7 +117,7 @@ TEST_F(PchTaskGenerator, AddProjectParts)
&PchTaskSet::project,
AllOf(Field(&PchTask::projectPartIds, ElementsAre(ProjectPartId{1})),
Field(&PchTask::includes, ElementsAre(3)),
- Field(&PchTask::sources, ElementsAre(1, 2, 3, 4, 5)),
+ Field(&PchTask::sources, ElementsAre(1, 3, 4, 5)),
Field(&PchTask::compilerMacros,
ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})),
Field(&PchTask::systemIncludeSearchPaths,
diff --git a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
index 7177060311..3af0fc8cfe 100644
--- a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
+++ b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
@@ -107,7 +107,10 @@ TEST_F(RefactoringDatabaseInitializer, AddProjectPartsFilesTable)
"sourceId INTEGER, sourceType INTEGER, pchCreationTimeStamp INTEGER, "
"hasMissingIncludes INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsFiles_sourceId_projectPartId ON projectPartsFiles(sourceId, projectPartId)")));
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsFiles_projectPartId ON projectPartsFiles(projectPartId)")));
+ EXPECT_CALL(mockDatabase,
+ execute(Eq(
+ "CREATE INDEX IF NOT EXISTS index_projectPartsFiles_projectPartId_sourceType "
+ "ON projectPartsFiles(projectPartId, sourceType)")));
initializer.createProjectPartsFilesTable();
}
@@ -247,9 +250,10 @@ TEST_F(RefactoringDatabaseInitializer, CreateInTheContructor)
execute(
Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsFiles_sourceId_projectPartId "
"ON projectPartsFiles(sourceId, projectPartId)")));
- EXPECT_CALL(mockDatabase,
- execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsFiles_projectPartId ON "
- "projectPartsFiles(projectPartId)")));
+ EXPECT_CALL(
+ mockDatabase,
+ execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsFiles_projectPartId_sourceType ON "
+ "projectPartsFiles(projectPartId, sourceType)")));
EXPECT_CALL(mockDatabase,
execute(Eq("CREATE TABLE IF NOT EXISTS usedMacros(usedMacroId INTEGER PRIMARY KEY, "
"sourceId INTEGER, macroName TEXT)")));
diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp
index 2db11dc5fb..16e0fc81b0 100644
--- a/tests/unit/unittest/symbolindexer-test.cpp
+++ b/tests/unit/unittest/symbolindexer-test.cpp
@@ -28,6 +28,7 @@
#include "mockbuilddependenciesstorage.h"
#include "mockclangpathwatcher.h"
#include "mockfilepathcaching.h"
+#include "mockfilesystem.h"
#include "mockmodifiedtimechecker.h"
#include "mockprecompiledheaderstorage.h"
#include "mockprojectpartsstorage.h"
@@ -149,13 +150,6 @@ protected:
data.reset();
}
- void touchFile(FilePathId filePathId)
- {
- std::ofstream ostream(std::string(filePathCache.filePath(filePathId)), std::ios::binary);
- ostream.write("\n", 1);
- ostream.close();
- }
-
FilePathId filePathId(Utils::SmallStringView path) const
{
return filePathCache.filePathId(ClangBackEnd::FilePathView(path));
@@ -249,7 +243,8 @@ protected:
NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage;
NiceMock<MockProjectPartsStorage> mockProjectPartsStorage;
NiceMock<MockClangPathWatcher> mockPathWatcher;
- ClangBackEnd::FileStatusCache fileStatusCache{filePathCache};
+ NiceMock<MockFileSystem> mockFileSystem;
+ ClangBackEnd::FileStatusCache fileStatusCache{mockFileSystem};
ClangBackEnd::GeneratedFiles generatedFiles;
Manager collectorManger{generatedFiles};
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
@@ -928,7 +923,7 @@ TEST_F(SymbolIndexer, SourcesAreWatched)
InSequence s;
FilePathIds sourcePathIds{4, 6, 8};
- EXPECT_CALL(mockBuildDependenciesStorage, fetchSources(projectPart1.projectPartId))
+ EXPECT_CALL(mockBuildDependenciesStorage, fetchPchSources(projectPart1.projectPartId))
.WillOnce(Return(sourcePathIds));
EXPECT_CALL(mockPathWatcher,
updateIdPaths(ElementsAre(AllOf(Field(&IdPaths::id, projectPart1.projectPartId),
@@ -1664,13 +1659,21 @@ TEST_F(SymbolIndexer, DISABLED_DontReparseInUpdateProjectPartsIfDefinesAreTheSam
TEST_F(SymbolIndexer, PathsChangedUpdatesFileStatusCache)
{
auto sourceId = filePathId(TESTDATA_DIR "/symbolindexer_pathChanged.cpp");
- auto oldLastModified = fileStatusCache.lastModifiedTime(sourceId);
- touchFile(sourceId);
+ ON_CALL(mockFileSystem, lastModified(Eq(sourceId))).WillByDefault(Return(65));
ON_CALL(mockSymbolStorage, fetchDependentSourceIds(_)).WillByDefault(Return(FilePathIds{sourceId}));
indexer.pathsChanged({sourceId});
- ASSERT_THAT(fileStatusCache.lastModifiedTime(sourceId), Gt(oldLastModified));
+ ASSERT_THAT(fileStatusCache.lastModifiedTime(sourceId), 65);
+}
+
+TEST_F(SymbolIndexer, PathsChangedCallsModifiedTimeChecker)
+{
+ auto sourceId = filePathId(TESTDATA_DIR "/symbolindexer_pathChanged.cpp");
+
+ EXPECT_CALL(mockModifiedTimeChecker, pathsChanged(ElementsAre(sourceId)));
+
+ indexer.pathsChanged({sourceId});
}
TEST_F(SymbolIndexer, GetUpdatableFilePathIdsIfCompilerMacrosAreDifferent)
@@ -1706,6 +1709,7 @@ TEST_F(SymbolIndexer, GetNoUpdatableFilePathIdsIfArtefactsAreTheSame)
TEST_F(SymbolIndexer, OutdatedFilesPassUpdatableFilePathIds)
{
+ ON_CALL(mockFileSystem, lastModified(Eq(main1PathId))).WillByDefault(Return(65));
indexer.pathsChanged({main1PathId});
ON_CALL(mockProjectPartsStorage, fetchProjectPartArtefact(A<ProjectPartId>()))
.WillByDefault(Return(artefact));
diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp
index f0080a5d2c..a766b70fa4 100644
--- a/tests/unit/unittest/symbolscollector-test.cpp
+++ b/tests/unit/unittest/symbolscollector-test.cpp
@@ -53,17 +53,18 @@ using testing::Value;
using testing::_;
using ClangBackEnd::FilePath;
-using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathCaching;
-using ClangBackEnd::V2::FileContainers;
+using ClangBackEnd::FilePathId;
+using ClangBackEnd::FileStatus;
using ClangBackEnd::SourceDependency;
using ClangBackEnd::SourceLocationEntry;
+using ClangBackEnd::SourceLocationKind;
using ClangBackEnd::SymbolEntry;
+using ClangBackEnd::SymbolIndex;
using ClangBackEnd::SymbolKind;
using ClangBackEnd::SymbolTag;
-using ClangBackEnd::SourceLocationKind;
-using ClangBackEnd::SymbolIndex;
using ClangBackEnd::UsedMacro;
+using ClangBackEnd::V2::FileContainers;
using Sqlite::Database;
@@ -130,6 +131,9 @@ MATCHER_P(HasSymbolTag, symbolTag,
class SymbolsCollector : public testing::Test
{
protected:
+ SymbolsCollector() { setFilePathCache(&filePathCache); }
+ ~SymbolsCollector() { setFilePathCache({}); }
+
FilePathId filePathId(Utils::SmallStringView filePath) const
{
return filePathCache.filePathId(ClangBackEnd::FilePathView{filePath});
@@ -664,4 +668,15 @@ TEST_F(SymbolsCollector, CollectReturnsFalseIfThereIsNoError)
ASSERT_TRUE(success);
}
+
+TEST_F(SymbolsCollector, ClearInputFilesAfterCollectingSymbols)
+{
+ collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main2.cpp"), {"cc"});
+ collector.collectSymbols();
+ collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"});
+
+ collector.collectSymbols();
+
+ ASSERT_TRUE(collector.isClean());
+}
} // namespace
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index 5ea9ba2fef..2989331ebe 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -36,7 +36,7 @@ CONFIG(release, debug|release):QMAKE_LFLAGS += -Wl,--strip-debug
}
gcc:!clang: QMAKE_CXXFLAGS += -Wno-noexcept-type
-msvc: QMAKE_CXXFLAGS += /bigobj
+msvc: QMAKE_CXXFLAGS += /bigobj /wd4267 /wd4141 /wd4146
# create fake CppTools.json for the mime type definitions
dependencyList = "\"Dependencies\" : []"
@@ -46,7 +46,6 @@ QMAKE_SUBSTITUTES += cpptoolsjson
DEFINES += CPPTOOLS_JSON=\"R\\\"xxx($${cpptoolsjson.output})xxx\\\"\"
SOURCES += \
- changedfilepathcompressor-test.cpp \
clangindexingsettingsmanager-test.cpp \
clangpathwatcher-test.cpp \
clangqueryexamplehighlightmarker-test.cpp \
@@ -56,6 +55,7 @@ SOURCES += \
cppprojectfilecategorizer-test.cpp \
cppprojectinfogenerator-test.cpp \
cppprojectpartchooser-test.cpp \
+ directorypathcompressor-test.cpp \
fakeprocess.cpp \
filepath-test.cpp \
filepathview-test.cpp \
@@ -177,7 +177,7 @@ SOURCES += \
translationunitupdater-test.cpp \
unsavedfiles-test.cpp \
unsavedfile-test.cpp \
- utf8positionfromlinecolumn-test.cpp \
+ utf8positionfromlinecolumn-test.cpp
}
!isEmpty(LIBTOOLING_LIBS) {
@@ -228,6 +228,7 @@ HEADERS += \
mockclangcodemodelserver.h \
mockclangpathwatcher.h \
mockclangpathwatchernotifier.h \
+ mockfilesystem.h \
mockpchcreator.h \
mockpchmanagerclient.h \
mockpchmanagernotifier.h \
diff --git a/tests/unit/unittest/usedmacrofilter-test.cpp b/tests/unit/unittest/usedmacrofilter-test.cpp
index 788a443eee..85e1bb59b5 100644
--- a/tests/unit/unittest/usedmacrofilter-test.cpp
+++ b/tests/unit/unittest/usedmacrofilter-test.cpp
@@ -98,12 +98,7 @@ TEST_F(UsedMacroFilter, Sources)
ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.sources,
- ElementsAre(FilePathId{1},
- FilePathId{2},
- FilePathId{3},
- FilePathId{4},
- FilePathId{5},
- FilePathId{6}));
+ ElementsAre(FilePathId{2}, FilePathId{3}, FilePathId{4}, FilePathId{5}));
}
TEST_F(UsedMacroFilter, SystemUsedMacros)