aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2019-03-14 15:14:40 +0100
committerEike Ziller <eike.ziller@qt.io>2019-03-14 15:51:15 +0100
commitc53ccceff1e1642b7704fa8b0681604c25a833a0 (patch)
tree7258d63fba4dabd6f9e2f2f36089ce45df7fe3af
parent62cafc1782369cde0605fbd6b1182a83d5473a12 (diff)
parent429eb73ace5909e228a58bf8b067823e2be44212 (diff)
Merge remote-tracking branch 'origin/4.9'
Conflicts: qbs/modules/qtc/qtc.qbs qtcreator.pri src/plugins/debugger/debuggerkitinformation.cpp src/plugins/languageclient/languageclientmanager.cpp src/plugins/plugins.pro src/plugins/projectexplorer/kit.cpp src/plugins/projectexplorer/kitmanager.cpp Change-Id: I66fb941202991f35f7d7761430b21e42dfc678a8
-rw-r--r--.clang-format2
-rw-r--r--README.md17
-rw-r--r--dist/changes-4.9.0.md10
-rw-r--r--qtcreator.pro16
-rwxr-xr-xscripts/flake2tasks.py50
-rw-r--r--share/qtcreator/debugger/lldbbridge.py24
-rw-r--r--share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json2
-rw-r--r--src/app/app.pro3
-rw-r--r--src/libs/clangsupport/commandlinebuilder.h3
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h8
-rw-r--r--src/libs/cplusplus/ExpressionUnderCursor.cpp2
-rw-r--r--src/libs/libs.pro24
-rw-r--r--src/libs/qmljs/qmljscheck.cpp4
-rw-r--r--src/libs/ssh/sshremoteprocess.cpp2
-rw-r--r--src/libs/utils/fileutils.cpp7
-rw-r--r--src/libs/utils/jsontreeitem.cpp4
-rw-r--r--src/libs/utils/textutils.cpp7
-rw-r--r--src/plugins/android/androiddeployqtstep.cpp2
-rw-r--r--src/plugins/clangcodemodel/clangcodemodelplugin.cpp9
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp13
-rw-r--r--src/plugins/clangcodemodel/clangcompletionassistprocessor.h1
-rw-r--r--src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp7
-rw-r--r--src/plugins/clangcodemodel/clangutils.cpp97
-rw-r--r--src/plugins/clangcodemodel/clangutils.h2
-rw-r--r--src/plugins/clangformat/ClangFormat.json.in2
-rw-r--r--src/plugins/clangformat/clangformatbaseindenter.cpp185
-rw-r--r--src/plugins/clangformat/clangformatbaseindenter.h1
-rw-r--r--src/plugins/clangformat/clangformatconfigwidget.cpp87
-rw-r--r--src/plugins/clangformat/clangformatconfigwidget.ui14
-rw-r--r--src/plugins/clangformat/clangformatconstants.h2
-rw-r--r--src/plugins/clangformat/clangformatindenter.cpp2
-rw-r--r--src/plugins/clangformat/clangformatplugin.cpp55
-rw-r--r--src/plugins/clangformat/clangformatsettings.cpp13
-rw-r--r--src/plugins/clangformat/clangformatsettings.h6
-rw-r--r--src/plugins/clangformat/clangformatutils.cpp259
-rw-r--r--src/plugins/clangformat/clangformatutils.h4
-rw-r--r--src/plugins/clangtools/clangtidyclazytool.cpp4
-rw-r--r--src/plugins/coreplugin/find/searchresulttreeview.cpp15
-rw-r--r--src/plugins/coreplugin/find/searchresulttreeview.h2
-rw-r--r--src/plugins/coreplugin/helpitem.h3
-rw-r--r--src/plugins/coreplugin/locator/locatorwidget.cpp8
-rw-r--r--src/plugins/coreplugin/outputpanemanager.cpp8
-rw-r--r--src/plugins/cpptools/clangdiagnosticconfigswidget.cpp10
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp11
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.h1
-rw-r--r--src/plugins/cpptools/cppfilesettingspage.ui4
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.cpp2
-rw-r--r--src/plugins/debugger/console/console.h2
-rw-r--r--src/plugins/debugger/debuggeritemmanager.cpp3
-rw-r--r--src/plugins/debugger/debuggerkitinformation.cpp19
-rw-r--r--src/plugins/debugger/debuggermainwindow.cpp12
-rw-r--r--src/plugins/debugger/debuggerruncontrol.cpp12
-rw-r--r--src/plugins/debugger/lldb/lldbengine.cpp27
-rw-r--r--src/plugins/debugger/lldb/lldbengine.h1
-rw-r--r--src/plugins/help/helpplugin.cpp2
-rw-r--r--src/plugins/languageclient/client.cpp18
-rw-r--r--src/plugins/languageclient/client.h1
-rw-r--r--src/plugins/languageclient/languageclientinterface.cpp2
-rw-r--r--src/plugins/languageclient/languageclientinterface.h2
-rw-r--r--src/plugins/languageclient/languageclientmanager.cpp17
-rw-r--r--src/plugins/languageclient/languageclientsettings.cpp4
-rw-r--r--src/plugins/languageclient/languageclientutils.cpp11
-rw-r--r--src/plugins/nim/settings/nimtoolssettingswidget.ui3
-rw-r--r--src/plugins/perfprofiler/perftracepointdialog.cpp2
-rw-r--r--src/plugins/perfprofiler/perftracepointdialog.h2
-rw-r--r--src/plugins/plugins.pro5
-rw-r--r--src/plugins/projectexplorer/devicesupport/desktopdevicefactory.h2
-rw-r--r--src/plugins/projectexplorer/kit.cpp6
-rw-r--r--src/plugins/projectexplorer/kitmanager.cpp4
-rw-r--r--src/plugins/projectexplorer/msvctoolchain.cpp2
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp8
-rw-r--r--src/plugins/pythoneditor/pythoneditorplugin.cpp4
-rw-r--r--src/plugins/qmldesigner/designercore/include/qmltimeline.h2
-rw-r--r--src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp2
-rw-r--r--src/plugins/qmldesigner/designersettings.h1
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineanimationform.ui21
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineconstants.h10
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineform.ui13
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.h4
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.h2
-rw-r--r--src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp4
-rw-r--r--src/plugins/qmldesigner/qmldesignerplugin.cpp3
-rw-r--r--src/plugins/qmldesigner/settingspage.cpp9
-rw-r--r--src/plugins/qmldesigner/settingspage.ui16
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.cpp6
-rw-r--r--src/plugins/qtsupport/qtoutputformatter.cpp21
-rw-r--r--src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp2
-rw-r--r--src/plugins/texteditor/basehoverhandler.cpp2
-rw-r--r--src/plugins/texteditor/highlighter.cpp23
-rw-r--r--src/plugins/texteditor/highlightersettingspage.ui3
-rw-r--r--src/plugins/texteditor/texteditor.cpp7
-rw-r--r--src/plugins/texteditor/texteditor.h2
-rw-r--r--src/plugins/texteditor/texteditor.pro12
-rw-r--r--src/plugins/texteditor/texteditor_dependencies.pri18
-rw-r--r--src/shared/clang/clang_installation.pri11
-rw-r--r--src/shared/syntax/syntax_shared.pri21
-rw-r--r--src/tools/clangbackend/source/fulltokeninfo.cpp1
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp27
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp38
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h6
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h100
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h15
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependency.h13
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp24
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependencycollector.h8
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri9
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h134
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h3
-rw-r--r--src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h110
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.cpp21
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.h19
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreatorincludes.h40
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp22
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.h6
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtask.h10
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp4
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp4
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp (renamed from src/tools/clangpchmanagerbackend/source/projectparts.cpp)18
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsmanager.h (renamed from src/tools/clangpchmanagerbackend/source/projectparts.h)5
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h (renamed from src/tools/clangpchmanagerbackend/source/projectpartsinterface.h)10
-rw-r--r--src/tools/clangpchmanagerbackend/source/sourceentry.h52
-rw-r--r--src/tools/clangpchmanagerbackend/source/usedmacrofilter.h66
-rw-r--r--src/tools/clangrefactoringbackend/source/filestatus.h12
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.cpp18
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorage.h20
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorageinterface.h1
-rw-r--r--tests/unit/unittest/builddependenciesprovider-test.cpp51
-rw-r--r--tests/unit/unittest/builddependenciesstorage-test.cpp102
-rw-r--r--tests/unit/unittest/builddependencycollector-test.cpp264
-rw-r--r--tests/unit/unittest/clangformat-test.cpp220
-rw-r--r--tests/unit/unittest/commandlinebuilder-test.cpp15
-rw-r--r--tests/unit/unittest/data/highlightingmarks.cpp9
-rw-r--r--tests/unit/unittest/filepathstorage-test.cpp26
-rw-r--r--tests/unit/unittest/gtest-creator-printing.cpp38
-rw-r--r--tests/unit/unittest/gtest-creator-printing.h2
-rw-r--r--tests/unit/unittest/mockbuilddependenciesstorage.h13
-rw-r--r--tests/unit/unittest/mockprojectparts.h4
-rw-r--r--tests/unit/unittest/mocksqlitedatabase.h4
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.cpp7
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.h7
-rw-r--r--tests/unit/unittest/mocksqlitewritestatement.h18
-rw-r--r--tests/unit/unittest/mocksymbolstorage.h3
-rw-r--r--tests/unit/unittest/pchcreator-test.cpp60
-rw-r--r--tests/unit/unittest/pchmanagerserver-test.cpp35
-rw-r--r--tests/unit/unittest/pchtaskgenerator-test.cpp4
-rw-r--r--tests/unit/unittest/pchtasksmerger-test.cpp4
-rw-r--r--tests/unit/unittest/projectparts-test.cpp4
-rw-r--r--tests/unit/unittest/refactoringdatabaseinitializer-test.cpp27
-rw-r--r--tests/unit/unittest/symbolindexer-test.cpp63
-rw-r--r--tests/unit/unittest/symbolscollector-test.cpp2
-rw-r--r--tests/unit/unittest/symbolstorage-test.cpp14
-rw-r--r--tests/unit/unittest/tokenprocessor-test.cpp18
-rw-r--r--tests/unit/unittest/usedmacrocollector-test.cpp2
-rw-r--r--tests/unit/unittest/usedmacrofilter-test.cpp43
154 files changed, 2209 insertions, 1066 deletions
diff --git a/.clang-format b/.clang-format
index 953e0b44cd..97f7f2b234 100644
--- a/.clang-format
+++ b/.clang-format
@@ -8,6 +8,8 @@
# Use ../../tests/manual/clang-format-for-qtc/test.cpp for documenting problems
# or testing changes.
#
+# In case you update this configuration please also update the qtcStyle() in src\plugins\clangformat\clangformatutils.cpp
+#
# [1] https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
# [2] https://clang.llvm.org/docs/ClangFormatStyleOptions.html
#
diff --git a/README.md b/README.md
index eaa60b0a19..44867703f3 100644
--- a/README.md
+++ b/README.md
@@ -34,9 +34,10 @@ Prerequisites:
* Python 3.5 or later (optional, needed for the python enabled debug helper)
* On Mac OS X: latest Xcode
* On Linux: g++ 5.3 or later
-* LLVM/Clang 6.0.0 or later (optional, needed for the Clang Code Model, see the
- section "Get LLVM/Clang for the Clang Code Model")
- * CMake (only for manual builds of LLVM/Clang)
+* LLVM/Clang 7.0.0 or later (optional, needed for the Clang Code Model, Clang Tools, ClangFormat,
+ Clang PCH Manager and Clang Refactoring plugins, see the section
+ "Get LLVM/Clang for the Clang Code Model")
+* CMake (only for manual builds of LLVM/Clang)
* Qbs 1.7.x (optional, sources also contain Qbs itself)
The installed toolchains have to match the one Qt was compiled with.
@@ -49,6 +50,10 @@ You can build Qt Creator with
export QBS_INSTALL_DIR=/path/to/qbs
# Optional, needed for the Python enabled dumper on Windows
set PYTHON_INSTALL_DIR=C:\path\to\python
+ # Optional, needed to use system KSyntaxHighlighting:
+ set KSYNTAXHIGHLIGHTING_LIB_DIR to folder holding the KSyntaxHighlighting library
+ # if automatic deducing of include folder fails set KSYNTAXHIGHLIGHTING_INCLUDE_DIR as well
+ # both variables can also be passed as qmake variables
cd $SOURCE_DIRECTORY
qmake -r
@@ -220,7 +225,7 @@ or using shadow builds.
## Get LLVM/Clang for the Clang Code Model
The Clang Code Model depends on the LLVM/Clang libraries. The currently
-supported LLVM/Clang version is 6.0.
+supported LLVM/Clang version is 7.0.
### Prebuilt LLVM/Clang packages
@@ -247,9 +252,9 @@ GCC 4 binaries. On Ubuntu, you can download the package from
http://apt.llvm.org/ with:
wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
- sudo apt-add-repository "deb http://apt.llvm.org/`lsb_release -cs`/ llvm-toolchain-`lsb_release -cs`-6.0 main"
+ sudo apt-add-repository "deb http://apt.llvm.org/`lsb_release -cs`/ llvm-toolchain-`lsb_release -cs`-7.0 main"
sudo apt-get update
- sudo apt-get install llvm-6.0 libclang-6.0-dev
+ sudo apt-get install llvm-7.0 libclang-7.0-dev
There is a workaround to set _GLIBCXX_USE_CXX11_ABI to 1 or 0, but we recommend
to download the package from http://apt.llvm.org/.
diff --git a/dist/changes-4.9.0.md b/dist/changes-4.9.0.md
index 5bc79fca88..1397bfe03c 100644
--- a/dist/changes-4.9.0.md
+++ b/dist/changes-4.9.0.md
@@ -52,6 +52,10 @@ QMake Projects
* Fixed updating of `LD_LIBRARY_PATH` environment variable (QTCREATORBUG-21475)
* Fixed updating of project tree in case of wildcards in corresponding QMake
variable (QTCREATORBUG-21603)
+* Fixed issues with project tree when files are directly added to `RESOURCES`
+ (QTCREATORBUG-20103)
+* Fixed that importing build unnecessarily created temporary kit
+ (QTCREATORBUG-18153)
CMake Projects
@@ -78,6 +82,8 @@ C++ Support
* Clang Code Model
* Added buttons for copying and ignoring diagnostics to tooltip
* Fixed issue with high memory consumption (QTCREATORBUG-19543)
+ * Fixed inconsistency between `Follow Symbol` and `Ctrl + Click`
+ (QTCREATORBUG-21637)
* Clang Format
* Added option to format code instead of only indenting code
@@ -98,6 +104,9 @@ Nim Support
Debugging
+* Fixed that debugger toolbar could force large minimum window size
+ (QTCREATORBUG-21885)
+* Added pretty printing of `QSizePolicy`
* GDB
* Added support for rvalue references in function arguments
* LLDB
@@ -167,6 +176,7 @@ Windows
* Added support for MSVC 2019
* Changed toolchain detection to use `vswhere` by default, which is recommended
by Microsoft
+* Fixed issue with UNC paths in `.pro` files (QTCREATORBUG-21881)
Linux
diff --git a/qtcreator.pro b/qtcreator.pro
index 71be6dac37..e5f2951634 100644
--- a/qtcreator.pro
+++ b/qtcreator.pro
@@ -109,15 +109,19 @@ linux {
macx {
APPBUNDLE = "$$OUT_PWD/bin/$${IDE_APP_TARGET}.app"
- BINDIST_SOURCE = "$$OUT_PWD/bin/$${IDE_APP_TARGET}.app"
+ BINDIST_SOURCE.release = "$$OUT_PWD/bin/$${IDE_APP_TARGET}.app"
+ BINDIST_SOURCE.debug = "$$OUT_PWD/bin"
+ BINDIST_EXCLUDE_ARG.debug = "--exclude-toplevel"
deployqt.commands = $$PWD/scripts/deployqtHelper_mac.sh \"$${APPBUNDLE}\" \"$$[QT_INSTALL_BINS]\" \"$$[QT_INSTALL_TRANSLATIONS]\" \"$$[QT_INSTALL_PLUGINS]\" \"$$[QT_INSTALL_IMPORTS]\" \"$$[QT_INSTALL_QML]\"
codesign.commands = codesign --deep -s \"$(SIGNING_IDENTITY)\" $(SIGNING_FLAGS) \"$${APPBUNDLE}\"
dmg.commands = python -u \"$$PWD/scripts/makedmg.py\" \"$${BASENAME}.dmg\" \"Qt Creator\" \"$$IDE_SOURCE_TREE\" \"$$OUT_PWD/bin\"
#dmg.depends = deployqt
QMAKE_EXTRA_TARGETS += codesign dmg
} else {
- BINDIST_SOURCE = "$(INSTALL_ROOT)$$QTC_PREFIX"
- BINDIST_EXCLUDE_ARG = "--exclude-toplevel"
+ BINDIST_SOURCE.release = "$(INSTALL_ROOT)$$QTC_PREFIX"
+ BINDIST_EXCLUDE_ARG.release = "--exclude-toplevel"
+ BINDIST_SOURCE.debug = $${BINDIST_SOURCE.release}
+ BINDIST_EXCLUDE_ARG.debug = $${BINDIST_EXCLUDE_ARG.release}
deployqt.commands = python -u $$PWD/scripts/deployqt.py -i \"$(INSTALL_ROOT)$$QTC_PREFIX/bin/$${IDE_APP_TARGET}\" \"$(QMAKE)\"
deployqt.depends = install
win32 {
@@ -140,9 +144,9 @@ isEmpty(INSTALLER_ARCHIVE_FROM_ENV) {
INSTALLER_ARCHIVE_DEBUG = $$INSTALLER_ARCHIVE
INSTALLER_ARCHIVE_DEBUG ~= s/(.*)[.]7z/\1-debug.7z
-bindist.commands = python -u $$PWD/scripts/createDistPackage.py $$OUT_PWD/$${BASENAME}.7z \"$$BINDIST_SOURCE\"
-bindist_installer.commands = python -u $$PWD/scripts/createDistPackage.py $$BINDIST_EXCLUDE_ARG $${INSTALLER_ARCHIVE} \"$$BINDIST_SOURCE\"
-bindist_debug.commands = python -u $$PWD/scripts/createDistPackage.py --debug $$BINDIST_EXCLUDE_ARG $${INSTALLER_ARCHIVE_DEBUG} \"$$BINDIST_SOURCE\"
+bindist.commands = python -u $$PWD/scripts/createDistPackage.py $$OUT_PWD/$${BASENAME}.7z \"$${BINDIST_SOURCE.release}\"
+bindist_installer.commands = python -u $$PWD/scripts/createDistPackage.py $${BINDIST_EXCLUDE_ARG.release} $${INSTALLER_ARCHIVE} \"$${BINDIST_SOURCE.release}\"
+bindist_debug.commands = python -u $$PWD/scripts/createDistPackage.py --debug $${BINDIST_EXCLUDE_ARG.debug} $${INSTALLER_ARCHIVE_DEBUG} \"$${BINDIST_SOURCE.debug}\"
win32 {
deployqt.commands ~= s,/,\\\\,g
diff --git a/scripts/flake2tasks.py b/scripts/flake2tasks.py
new file mode 100755
index 0000000000..a98cbf69ec
--- /dev/null
+++ b/scripts/flake2tasks.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+############################################################################
+#
+# Copyright (C) 2019 The Qt Company Ltd.
+# Contact: https://www.qt.io/licensing/
+#
+# This file is part of Qt Creator.
+#
+# Commercial License Usage
+# Licensees holding valid commercial Qt licenses may use this file in
+# accordance with the commercial license agreement provided with the
+# Software or, alternatively, in accordance with the terms contained in
+# a written agreement between you and The Qt Company. For licensing terms
+# and conditions see https://www.qt.io/terms-conditions. For further
+# information use the contact form at https://www.qt.io/contact-us.
+#
+# GNU General Public License Usage
+# Alternatively, this file may be used under the terms of the GNU
+# General Public License version 3 as published by the Free Software
+# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+# included in the packaging of this file. Please review the following
+# information to ensure the GNU General Public License requirements will
+# be met: https://www.gnu.org/licenses/gpl-3.0.html.
+#
+############################################################################
+
+'''
+flake2tasks.py - Convert flake8 warnings into Qt Creator task files.
+
+SYNOPSIS
+
+ flake2tasks.py < logfile > taskfile
+'''
+
+import sys
+import re
+
+if __name__ == '__main__':
+ pattern = re.compile(r'^([^:]+):(\d+):\d+: E\d+ (.*)$')
+ while True:
+ line = sys.stdin.readline().rstrip()
+ if not line:
+ break
+ match = pattern.match(line)
+ if match:
+ file_name = match.group(1).replace('\\', '/')
+ line_number = match.group(2)
+ text = match.group(3)
+ output = "{}\t{}\twarn\t{}".format(file_name, line_number, text)
+ print(output)
diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py
index a961569cd0..cf19c1eac8 100644
--- a/share/qtcreator/debugger/lldbbridge.py
+++ b/share/qtcreator/debugger/lldbbridge.py
@@ -957,6 +957,12 @@ class Dumper(DumperBase):
return
self.report('pid="%s"' % self.process.GetProcessID())
self.reportState('enginerunandinferiorrunok')
+ if self.target is not None:
+ broadcaster = self.target.GetBroadcaster()
+ listener = self.debugger.GetListener()
+ broadcaster.AddListener(listener, lldb.SBTarget.eBroadcastBitBreakpointChanged)
+ listener.StartListeningForEvents(broadcaster, lldb.SBTarget.eBroadcastBitBreakpointChanged)
+
def loop(self):
event = lldb.SBEvent()
@@ -1116,6 +1122,11 @@ class Dumper(DumperBase):
# logview pane feature.
self.report('token(\"%s\")' % args["token"])
+
+ def reportBreakpointUpdate(self, bp):
+ self.report('breakpointmodified={%s}' % self.describeBreakpoint(bp))
+
+
def readRawMemory(self, address, size):
if size == 0:
return bytes()
@@ -1288,7 +1299,20 @@ class Dumper(DumperBase):
self.process.Kill()
self.reportResult('', args)
+
+ def handleBreakpointEvent(self, event):
+ eventType = lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event)
+ # handle only the resolved locations for now..
+ if eventType & lldb.eBreakpointEventTypeLocationsResolved:
+ bp = lldb.SBBreakpoint.GetBreakpointFromEvent(event)
+ if bp is not None:
+ self.reportBreakpointUpdate(bp)
+
+
def handleEvent(self, event):
+ if lldb.SBBreakpoint.EventIsBreakpointEvent(event):
+ self.handleBreakpointEvent(event)
+ return
out = lldb.SBStream()
event.GetDescription(out)
#warn("EVENT: %s" % event)
diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
index 0f1ce91cf7..16c2646ce5 100644
--- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
+++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json
@@ -3,7 +3,7 @@
"supportedProjectTypes": [ "PythonProject" ],
"id": "U.QtForPythonApplicationEmpty",
"category": "F.Application",
- "trDescription": "Creates a Qt for Python application that only the main code for a QApplication",
+ "trDescription": "Creates a Qt for Python application that contains only the main code for a QApplication.",
"trDisplayName": "Qt for Python - Empty",
"trDisplayCategory": "Application",
"icon": "icon.png",
diff --git a/src/app/app.pro b/src/app/app.pro
index 89b9554a9f..712563419e 100644
--- a/src/app/app.pro
+++ b/src/app/app.pro
@@ -5,8 +5,9 @@ TEMPLATE = app
CONFIG += qtc_runnable sliced_bundle
TARGET = $$IDE_APP_TARGET
DESTDIR = $$IDE_APP_PATH
-VERSION = $$QTCREATOR_VERSION
QT -= testlib
+# work around QTBUG-74265
+win32: VERSION=
HEADERS += ../tools/qtcreatorcrashhandler/crashhandlersetup.h
SOURCES += main.cpp ../tools/qtcreatorcrashhandler/crashhandlersetup.cpp
diff --git a/src/libs/clangsupport/commandlinebuilder.h b/src/libs/clangsupport/commandlinebuilder.h
index 7367f08036..9de1da68d3 100644
--- a/src/libs/clangsupport/commandlinebuilder.h
+++ b/src/libs/clangsupport/commandlinebuilder.h
@@ -51,6 +51,7 @@ public:
commandLine.reserve(1024);
addCompiler(projectInfo.language);
+ disableWarnings();
addToolChainArguments(toolChainArguments);
addExtraFlags();
addLanguage(projectInfo, sourceType);
@@ -74,6 +75,8 @@ public:
commandLine.emplace_back("clang");
}
+ void disableWarnings() { commandLine.emplace_back("-w"); }
+
void addToolChainArguments(const Utils::SmallStringVector &toolChainArguments)
{
for (Utils::SmallStringView argument : toolChainArguments)
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
index cce203f0d4..f6d64a81d3 100644
--- a/src/libs/clangsupport/refactoringdatabaseinitializer.h
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -143,6 +143,8 @@ public:
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);
+ table.addColumn("pchCreationTimeStamp", Sqlite::ColumnType::Integer);
+ table.addColumn("hasMissingIncludes", Sqlite::ColumnType::Integer);
table.addUniqueIndex({sourceIdColumn, projectPartIdColumn});
table.addIndex({projectPartIdColumn});
@@ -168,11 +170,11 @@ public:
Sqlite::Table table;
table.setUseIfNotExists(true);
table.setName("fileStatuses");
- table.addColumn("sourceId", Sqlite::ColumnType::Integer, Sqlite::Contraint::PrimaryKey);
+ table.addColumn("sourceId",
+ Sqlite::ColumnType::Integer,
+ Sqlite::Contraint::PrimaryKey);
table.addColumn("size", Sqlite::ColumnType::Integer);
table.addColumn("lastModified", Sqlite::ColumnType::Integer);
- table.addColumn("buildDependencyTimeStamp", Sqlite::ColumnType::Integer);
- table.addColumn("isInPrecompiledHeader", Sqlite::ColumnType::Integer);
table.initialize(database);
}
diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp
index e176cbde35..6df396d8cf 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.cpp
+++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp
@@ -264,7 +264,7 @@ int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor) const
break;
} else if (tk.is(T_LPAREN) || tk.is(T_LBRACE)) {
return scanner.startPosition() + tk.utf16charsBegin();
- } else if (tk.is(T_RPAREN)) {
+ } else if (tk.is(T_RPAREN) || tk.is(T_RBRACE)) {
int matchingBrace = scanner.startOfMatchingBrace(index);
if (matchingBrace == index) // If no matching brace found
diff --git a/src/libs/libs.pro b/src/libs/libs.pro
index 8bc99461a7..26495bbbf0 100644
--- a/src/libs/libs.pro
+++ b/src/libs/libs.pro
@@ -31,9 +31,27 @@ for(l, SUBDIRS) {
}
SUBDIRS += \
- utils/process_stub.pro \
- 3rdparty/syntax-highlighting \
- 3rdparty/syntax-highlighting/data
+ utils/process_stub.pro
+
+isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR): KSYNTAXHIGHLIGHTING_LIB_DIR=$$(KSYNTAXHIGHLIGHTING_LIB_DIR)
+!isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) {
+ # enable short information message
+ KSYNTAX_WARN_ON = 1
+}
+
+include(../shared/syntax/syntax_shared.pri)
+isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) {
+ SUBDIRS += \
+ 3rdparty/syntax-highlighting \
+ 3rdparty/syntax-highlighting/data
+
+ equals(KSYNTAX_WARN_ON, 1) {
+ message("Either KSYNTAXHIGHLIGHTING_LIB_DIR does not exist or include path could not be deduced.")
+ unset(KSYNTAX_WARN_ON)
+ }
+} else {
+ message("Using KSyntaxHighlighting provided at $${KSYNTAXHIGHLIGHTING_LIB_DIR}.")
+}
win32:SUBDIRS += utils/process_ctrlc_stub.pro
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index a38a2fa906..ea43a4dec8 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -748,8 +748,8 @@ void Check::endVisit(UiObjectInitializer *)
{
m_propertyStack.pop();
m_typeStack.pop();
- UiObjectDefinition *objectDenition = cast<UiObjectDefinition *>(parent());
- if (objectDenition && objectDenition->qualifiedTypeNameId->name == "Component")
+ UiObjectDefinition *objectDefinition = cast<UiObjectDefinition *>(parent());
+ if (objectDefinition && objectDefinition->qualifiedTypeNameId->name == "Component")
m_idStack.pop();
UiObjectBinding *objectBinding = cast<UiObjectBinding *>(parent());
if (objectBinding && objectBinding->qualifiedTypeNameId->name == "Component")
diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp
index 48e965d6fa..a769484735 100644
--- a/src/libs/ssh/sshremoteprocess.cpp
+++ b/src/libs/ssh/sshremoteprocess.cpp
@@ -69,7 +69,7 @@ SshRemoteProcess::SshRemoteProcess(const QByteArray &command, const QStringList
connect(this, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this] {
QString error;
if (exitStatus() == QProcess::CrashExit)
- error = tr("The ssh binary crashed: %1").arg(errorString());
+ error = tr("The ssh process crashed: %1").arg(errorString());
else if (exitCode() == 255)
error = tr("Remote process crashed.");
emit done(error);
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index 708595aa4d..a476cd8d89 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -311,9 +311,10 @@ QString FileUtils::normalizePathName(const QString &name)
if (FAILED(hr))
return name;
TCHAR buffer[MAX_PATH];
- if (!SHGetPathFromIDList(file, buffer))
- return name;
- return QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const ushort *>(buffer)));
+ const bool success = SHGetPathFromIDList(file, buffer);
+ ILFree(file);
+ return success ? QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast<const ushort *>(buffer)))
+ : name;
#elif defined(Q_OS_OSX)
return Internal::normalizePathName(name);
#else // do not try to handle case-insensitive file systems on Linux
diff --git a/src/libs/utils/jsontreeitem.cpp b/src/libs/utils/jsontreeitem.cpp
index a70f5631ec..16da8e803e 100644
--- a/src/libs/utils/jsontreeitem.cpp
+++ b/src/libs/utils/jsontreeitem.cpp
@@ -63,9 +63,9 @@ QVariant Utils::JsonTreeItem::data(int column, int role) const
if (column == 2)
return typeName(m_value.type());
if (m_value.isObject())
- return QString('[' + QString::number(m_value.toObject().size()) + ' ' + tr("Items") + ']');
+ return QString('[' + tr("%n Items", nullptr, m_value.toObject().size()) + ']');
if (m_value.isArray())
- return QString('[' + QString::number(m_value.toArray().size()) + ' ' + tr("Items") + ']');
+ return QString('[' + tr("%n Items", nullptr, m_value.toArray().size()) + ']');
return m_value.toVariant();
}
diff --git a/src/libs/utils/textutils.cpp b/src/libs/utils/textutils.cpp
index 0d8009fef8..ba10ca56ae 100644
--- a/src/libs/utils/textutils.cpp
+++ b/src/libs/utils/textutils.cpp
@@ -171,7 +171,8 @@ LineColumn utf16LineColumn(const QByteArray &utf8Buffer, int utf8Offset)
lineColumn.line = static_cast<int>(
std::count(utf8Buffer.begin(), utf8Buffer.begin() + utf8Offset, '\n'))
+ 1;
- const int startOfLineOffset = utf8Buffer.lastIndexOf('\n', utf8Offset - 1) + 1;
+ const int startOfLineOffset = utf8Offset ? (utf8Buffer.lastIndexOf('\n', utf8Offset - 1) + 1)
+ : 0;
lineColumn.column = QString::fromUtf8(
utf8Buffer.mid(startOfLineOffset, utf8Offset - startOfLineOffset))
.length()
@@ -181,7 +182,9 @@ LineColumn utf16LineColumn(const QByteArray &utf8Buffer, int utf8Offset)
QString utf16LineTextInUtf8Buffer(const QByteArray &utf8Buffer, int currentUtf8Offset)
{
- const int lineStartUtf8Offset = utf8Buffer.lastIndexOf('\n', currentUtf8Offset - 1) + 1;
+ const int lineStartUtf8Offset = currentUtf8Offset
+ ? (utf8Buffer.lastIndexOf('\n', currentUtf8Offset - 1) + 1)
+ : 0;
const int lineEndUtf8Offset = utf8Buffer.indexOf('\n', currentUtf8Offset);
return QString::fromUtf8(
utf8Buffer.mid(lineStartUtf8Offset, lineEndUtf8Offset - lineStartUtf8Offset));
diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp
index 97b8e5de5b..8ba6012875 100644
--- a/src/plugins/android/androiddeployqtstep.cpp
+++ b/src/plugins/android/androiddeployqtstep.cpp
@@ -101,7 +101,7 @@ public:
setSummaryText(displayName());
auto uninstallPreviousPackage = new QCheckBox(this);
- uninstallPreviousPackage->setText(tr("Uninstall previous package"));
+ uninstallPreviousPackage->setText(AndroidDeployQtStep::tr("Uninstall previous package"));
uninstallPreviousPackage->setChecked(step->uninstallPreviousPackage() > AndroidDeployQtStep::Keep);
uninstallPreviousPackage->setEnabled(step->uninstallPreviousPackage() != AndroidDeployQtStep::ForceUnintall);
diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
index 11de94c395..a4a1591cf4 100644
--- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
+++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp
@@ -68,13 +68,12 @@ void ClangCodeModelPlugin::generateCompilationDB() {
using namespace CppTools;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
- if (!project)
+ if (!project || !project->activeTarget())
return;
- m_generatorWatcher.setFuture(QtConcurrent::run(
- &Utils::generateCompilationDB,
- project->projectDirectory(),
- CppModelManager::instance()->projectInfo(project)));
+ m_generatorWatcher.setFuture(
+ QtConcurrent::run(&Utils::generateCompilationDB,
+ CppModelManager::instance()->projectInfo(project)));
}
static bool isDBGenerationEnabled(ProjectExplorer::Project *project)
diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
index db34c904d4..6f1397c487 100644
--- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
+++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp
@@ -214,6 +214,9 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions(const CodeComple
setAsyncProposalAvailable(createFunctionHintProposal(completions));
return;
}
+
+ if (!m_fallbackToNormalCompletion)
+ return;
// else: Proceed with a normal completion in case:
// 1) it was not a function call, but e.g. a function declaration like "void f("
// 2) '{' meant not a constructor call.
@@ -286,6 +289,14 @@ static QByteArray modifyInput(QTextDocument *doc, int endOfExpression) {
return modifiedInput;
}
+static QChar lastPrecedingNonWhitespaceChar(const ClangCompletionAssistInterface *interface)
+{
+ int pos = interface->position();
+ while (pos >= 0 && interface->characterAt(pos).isSpace())
+ --pos;
+ return pos >= 0 ? interface->characterAt(pos) : QChar::Null;
+}
+
IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
{
ClangCompletionContextAnalyzer analyzer(m_interface.data(), m_interface->languageFeatures());
@@ -323,6 +334,8 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper()
}
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: {
m_sentRequestType = FunctionHintCompletion;
+ if (lastPrecedingNonWhitespaceChar(m_interface.data()) == ',')
+ m_fallbackToNormalCompletion = false;
m_requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray(),
analyzer.functionNameStart());
break;
diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h
index 03711f0fa8..5e8c772235 100644
--- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h
+++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h
@@ -97,6 +97,7 @@ private:
CompletionRequestType m_sentRequestType = NormalCompletion;
bool m_requestSent = false;
bool m_addSnippets = false; // For type == Type::NormalCompletion
+ bool m_fallbackToNormalCompletion = true;
};
} // namespace Internal
diff --git a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp
index ad48a60685..a2c32a537a 100644
--- a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp
+++ b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp
@@ -110,6 +110,8 @@ int ClangCompletionContextAnalyzer::startOfFunctionCall(int endOfOperator) const
functionNameSelector.setPosition(functionNameStart);
functionNameSelector.setPosition(index, QTextCursor::KeepAnchor);
const QString functionName = functionNameSelector.selectedText().trimmed();
+ if (functionName.isEmpty() && m_completionOperator == T_LBRACE)
+ return endOfOperator;
return functionName.isEmpty() ? -1 : functionNameStart;
}
@@ -139,7 +141,10 @@ void ClangCompletionContextAnalyzer::handleCommaInFunctionCall()
const int start = expressionUnderCursor.startOfFunctionCall(textCursor);
m_positionEndOfExpression = start;
m_positionForProposal = start + 1; // After '(' of function call
- m_completionOperator = T_LPAREN;
+ if (m_interface->characterAt(start) == '(')
+ m_completionOperator = T_LPAREN;
+ else
+ m_completionOperator = T_LBRACE;
}
}
diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp
index 481b0774f8..fa42dedf2d 100644
--- a/src/plugins/clangcodemodel/clangutils.cpp
+++ b/src/plugins/clangcodemodel/clangutils.cpp
@@ -34,12 +34,13 @@
#include <coreplugin/idocument.h>
#include <cpptools/baseeditordocumentparser.h>
#include <cpptools/compileroptionsbuilder.h>
+#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cppmodelmanager.h>
+#include <cpptools/cpptoolsreuse.h>
#include <cpptools/editordocumenthandle.h>
#include <cpptools/projectpart.h>
-#include <cpptools/cppcodemodelsettings.h>
-#include <cpptools/cpptoolsreuse.h>
#include <projectexplorer/buildconfiguration.h>
+#include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h>
@@ -300,12 +301,24 @@ QString diagnosticCategoryPrefixRemoved(const QString &text)
return text;
}
-static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart)
+static ::Utils::FileName compilerPath(const CppTools::ProjectPart &projectPart)
{
ProjectExplorer::Target *target = projectPart.project->activeTarget();
if (!target)
return ::Utils::FileName();
+ ProjectExplorer::ToolChain *toolchain = ProjectExplorer::ToolChainKitAspect::toolChain(
+ target->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID);
+
+ return toolchain->compilerCommand();
+}
+
+static ::Utils::FileName buildDirectory(const ProjectExplorer::Project &project)
+{
+ ProjectExplorer::Target *target = project.activeTarget();
+ if (!target)
+ return ::Utils::FileName();
+
ProjectExplorer::BuildConfiguration *buildConfig = target->activeBuildConfiguration();
if (!buildConfig)
return ::Utils::FileName();
@@ -313,42 +326,84 @@ static ::Utils::FileName buildDirectory(const CppTools::ProjectPart &projectPart
return buildConfig->buildDirectory();
}
-static QJsonObject createFileObject(CompilerOptionsBuilder &optionsBuilder,
- const ProjectFile &projFile,
- const ::Utils::FileName &buildDir)
+static QStringList projectPartArguments(const ProjectPart &projectPart)
{
- const ProjectFile::Kind kind = ProjectFile::classify(projFile.path);
- optionsBuilder.updateFileLanguage(kind);
+ QStringList args;
+ args << compilerPath(projectPart).toString();
+ args << "-c";
+ if (projectPart.toolchainType != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
+ args << "--target=" + projectPart.toolChainTargetTriple;
+ args << (projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit
+ ? QLatin1String("-m64")
+ : QLatin1String("-m32"));
+ }
+ args << projectPart.compilerFlags;
+ for (const ProjectExplorer::HeaderPath &headerPath : projectPart.headerPaths) {
+ if (headerPath.type == ProjectExplorer::HeaderPathType::User) {
+ args << "-I" + headerPath.path;
+ } else if (headerPath.type == ProjectExplorer::HeaderPathType::System) {
+ args << (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
+ ? "-I"
+ : "-isystem")
+ + headerPath.path;
+ }
+ }
+ for (const ProjectExplorer::Macro &macro : projectPart.projectMacros) {
+ args.append(QString::fromUtf8(
+ macro.toKeyValue(macro.type == ProjectExplorer::MacroType::Define ? "-D" : "-U")));
+ }
+ return args;
+}
+
+static QJsonObject createFileObject(const ::Utils::FileName &buildDir,
+ const QStringList &arguments,
+ const ProjectPart &projectPart,
+ const ProjectFile &projFile)
+{
QJsonObject fileObject;
fileObject["file"] = projFile.path;
- QJsonArray args = QJsonArray::fromStringList(optionsBuilder.options());
- args.prepend(kind == ProjectFile::CXXSource ? "clang++" : "clang");
+ QJsonArray args = QJsonArray::fromStringList(arguments);
+
+ const ProjectFile::Kind kind = ProjectFile::classify(projFile.path);
+ if (projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
+ || projectPart.toolchainType == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
+ if (ProjectFile::isC(kind))
+ args.append("/TC");
+ else if (ProjectFile::isCxx(kind))
+ args.append("/TP");
+ } else {
+ QStringList langOption
+ = createLanguageOptionGcc(kind,
+ projectPart.languageExtensions
+ & ::Utils::LanguageExtension::ObjectiveC);
+ for (const QString &langOptionPart : langOption)
+ args.append(langOptionPart);
+ }
args.append(QDir::toNativeSeparators(projFile.path));
fileObject["arguments"] = args;
fileObject["directory"] = buildDir.toString();
return fileObject;
}
-void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo)
+void generateCompilationDB(CppTools::ProjectInfo projectInfo)
{
- QFile compileCommandsFile(projectDir.toString() + "/compile_commands.json");
+ const ::Utils::FileName buildDir = buildDirectory(*projectInfo.project());
+ QTC_ASSERT(!buildDir.isEmpty(), return;);
+ QDir dir(buildDir.toString());
+ if (!dir.exists())
+ dir.mkpath(dir.path());
+ QFile compileCommandsFile(buildDir.toString() + "/compile_commands.json");
const bool fileOpened = compileCommandsFile.open(QIODevice::WriteOnly | QIODevice::Truncate);
if (!fileOpened)
return;
compileCommandsFile.write("[");
- for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
- const ::Utils::FileName buildDir = buildDirectory(*projectPart);
-
- CompilerOptionsBuilder optionsBuilder(*projectPart,
- UseSystemHeader::No,
- UseTweakedHeaderPaths::No);
- optionsBuilder.build(CppTools::ProjectFile::Unclassified,
- CppTools::UsePrecompiledHeaders::No);
+ for (ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
+ const QStringList args = projectPartArguments(*projectPart);
for (const ProjectFile &projFile : projectPart->files) {
- const QJsonObject json = createFileObject(optionsBuilder, projFile, buildDir);
+ const QJsonObject json = createFileObject(buildDir, args, *projectPart, projFile);
if (compileCommandsFile.size() > 1)
compileCommandsFile.write(",");
compileCommandsFile.write('\n' + QJsonDocument(json).toJson().trimmed());
diff --git a/src/plugins/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h
index 4db869896b..8ced14f5ad 100644
--- a/src/plugins/clangcodemodel/clangutils.h
+++ b/src/plugins/clangcodemodel/clangutils.h
@@ -70,7 +70,7 @@ QString diagnosticCategoryPrefixRemoved(const QString &text);
::Utils::CodeModelIcon::Type iconTypeForToken(const ClangBackEnd::TokenInfoContainer &token);
-void generateCompilationDB(::Utils::FileName projectDir, CppTools::ProjectInfo projectInfo);
+void generateCompilationDB(CppTools::ProjectInfo projectInfo);
class DiagnosticTextInfo
{
diff --git a/src/plugins/clangformat/ClangFormat.json.in b/src/plugins/clangformat/ClangFormat.json.in
index 1c818c2f9e..f270fea580 100644
--- a/src/plugins/clangformat/ClangFormat.json.in
+++ b/src/plugins/clangformat/ClangFormat.json.in
@@ -2,7 +2,7 @@
\"Name\" : \"ClangFormat\",
\"Version\" : \"$$QTCREATOR_VERSION\",
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
- \"Experimental\" : true,
+ \"DisabledByDefault\" : true,
\"Vendor\" : \"The Qt Company Ltd\",
\"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
\"License\" : [ \"Commercial Usage\",
diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp
index a53eb50adb..dcb5edaeb1 100644
--- a/src/plugins/clangformat/clangformatbaseindenter.cpp
+++ b/src/plugins/clangformat/clangformatbaseindenter.cpp
@@ -29,9 +29,10 @@
#include <utils/algorithm.h>
#include <utils/fileutils.h>
-#include <utils/textutils.h>
#include <utils/qtcassert.h>
+#include <utils/textutils.h>
+#include <QDebug>
#include <QTextDocument>
namespace ClangFormat {
@@ -126,9 +127,85 @@ void trimRHSWhitespace(const QTextBlock &block)
cursor.endEditBlock();
}
+QTextBlock reverseFindLastEmptyBlock(QTextBlock start)
+{
+ if (start.position() > 0) {
+ start = start.previous();
+ while (start.position() > 0 && start.text().trimmed().isEmpty())
+ start = start.previous();
+ if (!start.text().trimmed().isEmpty())
+ start = start.next();
+ }
+ return start;
+}
+
+enum class CharacterContext { AfterComma, LastAfterComma, NewStatement, Continuation, Unknown };
+
+QChar findFirstNonWhitespaceCharacter(const QTextBlock &currentBlock)
+{
+ const QTextDocument *doc = currentBlock.document();
+ int currentPos = currentBlock.position();
+ while (currentPos < doc->characterCount() && doc->characterAt(currentPos).isSpace())
+ ++currentPos;
+ return currentPos < doc->characterCount() ? doc->characterAt(currentPos) : QChar::Null;
+}
+
+CharacterContext characterContext(const QTextBlock &currentBlock,
+ const QTextBlock &previousNonEmptyBlock)
+{
+ const QString prevLineText = previousNonEmptyBlock.text().trimmed();
+ const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock);
+ if (prevLineText.endsWith(',')) {
+ // We don't need to add comma in case it's the last argument.
+ if (firstNonWhitespaceChar == '}' || firstNonWhitespaceChar == ')')
+ return CharacterContext::LastAfterComma;
+ return CharacterContext::AfterComma;
+ }
+
+ if (prevLineText.endsWith(';') || prevLineText.endsWith('{') || prevLineText.endsWith('}')
+ || firstNonWhitespaceChar == QChar::Null) {
+ return CharacterContext::NewStatement;
+ }
+
+ return CharacterContext::Continuation;
+}
+
+bool nextBlockExistsAndEmpty(const QTextBlock &currentBlock)
+{
+ QTextBlock nextBlock = currentBlock.next();
+ if (!nextBlock.isValid() || nextBlock.position() == currentBlock.position())
+ return false;
+
+ return nextBlock.text().trimmed().isEmpty();
+}
+
+QByteArray dummyTextForContext(CharacterContext context, bool closingBraceBlock)
+{
+ if (closingBraceBlock
+ && (context == CharacterContext::NewStatement
+ || context == CharacterContext::Continuation)) {
+ return QByteArray();
+ }
+
+ switch (context) {
+ case CharacterContext::Unknown:
+ QTC_ASSERT(false, return "";);
+ case CharacterContext::AfterComma:
+ return "a,";
+ case CharacterContext::NewStatement:
+ return "a;";
+ case CharacterContext::Continuation:
+ case CharacterContext::LastAfterComma:
+ return "& a &";
+ }
+}
+
// Add extra text in case of the empty line or the line starting with ')'.
// Track such extra pieces of text in isInsideModifiedLine().
-int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool secondTry)
+int forceIndentWithExtraText(QByteArray &buffer,
+ CharacterContext &charContext,
+ const QTextBlock &block,
+ bool secondTry)
{
const QString blockText = block.text();
int firstNonWhitespace = Utils::indexOf(blockText,
@@ -143,26 +220,33 @@ int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool s
const bool closingParenBlock = firstNonWhitespace >= 0
&& blockText.at(firstNonWhitespace) == ')';
+ const bool closingBraceBlock = firstNonWhitespace >= 0
+ && blockText.at(firstNonWhitespace) == '}';
int extraLength = 0;
- if (firstNonWhitespace < 0 || closingParenBlock) {
- //This extra text works for the most cases.
- QByteArray dummyText("a;a;");
-
- // Search for previous character
- QTextBlock prevBlock = block.previous();
- bool prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
- while (prevBlockIsEmpty) {
- prevBlock = prevBlock.previous();
- prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
+ QByteArray dummyText;
+ if (firstNonWhitespace < 0 && charContext != CharacterContext::Unknown
+ && nextBlockExistsAndEmpty(block)) {
+ // If the next line is also empty it's safer to use a comment line.
+ dummyText = "//";
+ } else if (firstNonWhitespace < 0 || closingParenBlock || closingBraceBlock) {
+ if (charContext == CharacterContext::LastAfterComma) {
+ charContext = CharacterContext::AfterComma;
+ } else if (charContext == CharacterContext::Unknown || firstNonWhitespace >= 0) {
+ QTextBlock lastBlock = reverseFindLastEmptyBlock(block);
+ if (lastBlock.position() > 0)
+ lastBlock = lastBlock.previous();
+
+ // If we don't know yet the dummy text, let's guess it and use for this line and before.
+ charContext = characterContext(block, lastBlock);
}
- if (closingParenBlock || prevBlock.text().endsWith(','))
- dummyText = "&& a";
- buffer.insert(utf8Offset, dummyText);
- extraLength += dummyText.length();
+ dummyText = dummyTextForContext(charContext, closingBraceBlock);
}
+ buffer.insert(utf8Offset, dummyText);
+ extraLength += dummyText.length();
+
if (secondTry) {
int nextLinePos = buffer.indexOf('\n', utf8Offset);
if (nextLinePos < 0)
@@ -170,7 +254,7 @@ int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool s
if (nextLinePos > 0) {
// If first try was not successful try to put ')' in the end of the line to close possibly
- // unclosed parentheses.
+ // unclosed parenthesis.
// TODO: Does it help to add different endings depending on the context?
buffer.insert(nextLinePos, ')');
extraLength += 1;
@@ -300,18 +384,6 @@ bool doNotIndentInContext(QTextDocument *doc, int pos)
return false;
}
-QTextBlock reverseFindLastEmptyBlock(QTextBlock start)
-{
- if (start.position() > 0) {
- start = start.previous();
- while (start.position() > 0 && start.text().trimmed().isEmpty())
- start = start.previous();
- if (!start.text().trimmed().isEmpty())
- start = start.next();
- }
- return start;
-}
-
int formattingRangeStart(const QTextBlock &currentBlock,
const QByteArray &buffer,
int documentRevision)
@@ -355,23 +427,14 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer
rangeStart = formattingRangeStart(startBlock, buffer, lastSaveRevision());
adjustFormatStyleForLineBreak(style, replacementsToKeep);
- if (typedChar == QChar::Null) {
- if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore) {
- if (utf8Offset > 0) {
- buffer.insert(utf8Offset - 1, " //");
- utf8Offset += 3;
- }
+ if (replacementsToKeep == ReplacementsToKeep::OnlyIndent) {
+ CharacterContext currentCharContext = CharacterContext::Unknown;
+ // Iterate backwards to reuse the same dummy text for all empty lines.
+ for (int index = endBlock.blockNumber(); index >= startBlock.blockNumber(); --index) {
utf8Length += forceIndentWithExtraText(buffer,
- cursorPositionInEditor < 0
- ? endBlock
- : m_doc->findBlock(cursorPositionInEditor),
+ currentCharContext,
+ m_doc->findBlockByNumber(index),
secondTry);
- } else {
- for (int index = startBlock.blockNumber(); index <= endBlock.blockNumber(); ++index) {
- utf8Length += forceIndentWithExtraText(buffer,
- m_doc->findBlockByNumber(index),
- secondTry);
- }
}
}
@@ -432,9 +495,24 @@ TextEditor::Replacements ClangFormatBaseIndenter::format(
static_cast<unsigned int>(utf8RangeLength));
}
+ clang::format::FormatStyle style = styleForFile();
+ const std::string assumedFileName = m_fileName.toString().toStdString();
+ clang::tooling::Replacements clangReplacements = clang::format::sortIncludes(style,
+ buffer.data(),
+ ranges,
+ assumedFileName);
+ auto changedCode = clang::tooling::applyAllReplacements(buffer.data(), clangReplacements);
+ QTC_ASSERT(changedCode, {
+ qDebug() << QString::fromStdString(llvm::toString(changedCode.takeError()));
+ return TextEditor::Replacements();
+ });
+ ranges = clang::tooling::calculateRangesAfterReplacements(clangReplacements, ranges);
+
clang::format::FormattingAttemptStatus status;
- const clang::tooling::Replacements clangReplacements
- = reformat(styleForFile(), buffer.data(), ranges, m_fileName.toString().toStdString(), &status);
+ const clang::tooling::Replacements formatReplacements
+ = reformat(style, *changedCode, ranges, m_fileName.toString().toStdString(), &status);
+ clangReplacements = clangReplacements.merge(formatReplacements);
+
const TextEditor::Replacements toReplace = utf16Replacements(m_doc, buffer, clangReplacements);
applyReplacements(m_doc, toReplace);
@@ -443,7 +521,6 @@ TextEditor::Replacements ClangFormatBaseIndenter::format(
TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlock,
const QTextBlock &endBlock,
- const QByteArray &buffer,
const QChar &typedChar,
int cursorPositionInEditor)
{
@@ -461,10 +538,12 @@ TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlo
cursorPositionInEditor += startBlock.position() - startBlockPosition;
}
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
+
ReplacementsToKeep replacementsToKeep = ReplacementsToKeep::OnlyIndent;
if (formatWhileTyping()
&& (cursorPositionInEditor == -1 || cursorPositionInEditor >= startBlockPosition)
- && (typedChar == QChar::Null || typedChar == ';' || typedChar == '}')) {
+ && (typedChar == ';' || typedChar == '}')) {
// Format before current position only in case the cursor is inside the indented block.
// So if cursor position is less then the block position then the current line is before
// the indented block - don't trigger extra formatting in this case.
@@ -487,9 +566,7 @@ void ClangFormatBaseIndenter::indentBlocks(const QTextBlock &startBlock,
const QChar &typedChar,
int cursorPositionInEditor)
{
- const QByteArray buffer = m_doc->toPlainText().toUtf8();
- applyReplacements(m_doc,
- indentsFor(startBlock, endBlock, buffer, typedChar, cursorPositionInEditor));
+ applyReplacements(m_doc, indentsFor(startBlock, endBlock, typedChar, cursorPositionInEditor));
}
void ClangFormatBaseIndenter::indent(const QTextCursor &cursor,
@@ -533,15 +610,14 @@ int ClangFormatBaseIndenter::indentFor(const QTextBlock &block,
const TextEditor::TabSettings & /*tabSettings*/,
int cursorPositionInEditor)
{
- const QByteArray buffer = m_doc->toPlainText().toUtf8();
TextEditor::Replacements toReplace = indentsFor(block,
block,
- buffer,
QChar::Null,
cursorPositionInEditor);
if (toReplace.empty())
return -1;
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
return indentationForBlock(toReplace, buffer, block);
}
@@ -553,13 +629,12 @@ TextEditor::IndentationForBlock ClangFormatBaseIndenter::indentationForBlocks(
TextEditor::IndentationForBlock ret;
if (blocks.isEmpty())
return ret;
- const QByteArray buffer = m_doc->toPlainText().toUtf8();
TextEditor::Replacements toReplace = indentsFor(blocks.front(),
blocks.back(),
- buffer,
QChar::Null,
cursorPositionInEditor);
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
for (const QTextBlock &block : blocks)
ret.insert(block.blockNumber(), indentationForBlock(toReplace, buffer, block));
return ret;
diff --git a/src/plugins/clangformat/clangformatbaseindenter.h b/src/plugins/clangformat/clangformatbaseindenter.h
index b412b57d6d..87b5e0c927 100644
--- a/src/plugins/clangformat/clangformatbaseindenter.h
+++ b/src/plugins/clangformat/clangformatbaseindenter.h
@@ -81,7 +81,6 @@ private:
int cursorPositionInEditor);
TextEditor::Replacements indentsFor(QTextBlock startBlock,
const QTextBlock &endBlock,
- const QByteArray &buffer,
const QChar &typedChar,
int cursorPositionInEditor);
TextEditor::Replacements replacements(QByteArray buffer,
diff --git a/src/plugins/clangformat/clangformatconfigwidget.cpp b/src/plugins/clangformat/clangformatconfigwidget.cpp
index faaf6d937f..72e1778999 100644
--- a/src/plugins/clangformat/clangformatconfigwidget.cpp
+++ b/src/plugins/clangformat/clangformatconfigwidget.cpp
@@ -59,6 +59,24 @@ ClangFormatConfigWidget::ClangFormatConfigWidget(ProjectExplorer::Project *proje
{
m_ui->setupUi(this);
+ m_preview = new TextEditor::SnippetEditorWidget(this);
+ m_ui->horizontalLayout_2->addWidget(m_preview);
+ if (m_project) {
+ m_ui->applyButton->show();
+ hideGlobalCheckboxes();
+ m_ui->overrideDefault->setChecked(
+ m_project->namedSettings(Constants::OVERRIDE_FILE_ID).toBool());
+ } else {
+ m_ui->applyButton->hide();
+ showGlobalCheckboxes();
+ m_ui->overrideDefault->setChecked(ClangFormatSettings::instance().overrideDefaultFile());
+ }
+
+ connect(m_ui->overrideDefault, &QCheckBox::toggled, this, [this](bool checked) {
+ if (checked)
+ createStyleFileIfNeeded(!m_project);
+ initialize();
+ });
initialize();
}
@@ -81,15 +99,19 @@ void ClangFormatConfigWidget::showGlobalCheckboxes()
m_ui->formatOnSave->show();
}
+static bool projectConfigExists()
+{
+ return Utils::FileName::fromString(Core::ICore::userResourcePath())
+ .appendPath("clang-format")
+ .appendPath(currentProjectUniqueId())
+ .appendPath((Constants::SETTINGS_FILE_NAME))
+ .exists();
+}
+
void ClangFormatConfigWidget::initialize()
{
- m_ui->projectHasClangFormat->show();
- m_ui->clangFormatOptionsTable->show();
- m_ui->applyButton->show();
- hideGlobalCheckboxes();
+ m_ui->projectHasClangFormat->hide();
- m_preview = new TextEditor::SnippetEditorWidget(this);
- m_ui->horizontalLayout_2->addWidget(m_preview);
m_preview->setPlainText(QLatin1String(CppTools::Constants::DEFAULT_CODE_STYLE_SNIPPETS[0]));
m_preview->textDocument()->setIndenter(new ClangFormatIndenter(m_preview->document()));
m_preview->textDocument()->setFontSettings(TextEditor::TextEditorSettings::fontSettings());
@@ -103,21 +125,15 @@ void ClangFormatConfigWidget::initialize()
if (lastItem->spacerItem())
m_ui->verticalLayout->removeItem(lastItem);
- if (m_project
- && !m_project->projectDirectory().appendPath(Constants::SETTINGS_FILE_NAME).exists()) {
- m_ui->projectHasClangFormat->setText(tr("No .clang-format file for the project."));
+ if (!m_ui->overrideDefault->isChecked()) {
m_ui->clangFormatOptionsTable->hide();
- m_ui->applyButton->hide();
+ m_preview->hide();
m_ui->verticalLayout->addStretch(1);
-
- connect(m_ui->createFileButton, &QPushButton::clicked, this, [this]() {
- createStyleFileIfNeeded(false);
- initialize();
- });
return;
}
- m_ui->createFileButton->hide();
+ m_ui->clangFormatOptionsTable->show();
+ m_preview->show();
Utils::FileName fileName;
if (m_project) {
@@ -126,19 +142,13 @@ void ClangFormatConfigWidget::initialize()
fileName = m_project->projectFilePath().appendPath("snippet.cpp");
} else {
const Project *currentProject = SessionManager::startupProject();
- if (!currentProject
- || !currentProject->projectDirectory()
- .appendPath(Constants::SETTINGS_FILE_NAME)
- .exists()) {
+ if (!currentProject || !projectConfigExists()) {
m_ui->projectHasClangFormat->hide();
} else {
m_ui->projectHasClangFormat->setText(
- tr("Current project has its own .clang-format file "
+ tr("Current project has its own overridden .clang-format file "
"and can be configured in Projects > Code Style > C++."));
}
- createStyleFileIfNeeded(true);
- showGlobalCheckboxes();
- m_ui->applyButton->hide();
fileName = Utils::FileName::fromString(Core::ICore::userResourcePath())
.appendPath("snippet.cpp");
}
@@ -160,7 +170,7 @@ void ClangFormatConfigWidget::fillTable()
{
clang::format::FormatStyle style = m_project ? currentProjectStyle() : currentGlobalStyle();
- std::string configText = clang::format::configurationAsText(style);
+ const std::string configText = clang::format::configurationAsText(style);
m_ui->clangFormatOptionsTable->setPlainText(QString::fromStdString(configText));
}
@@ -168,13 +178,19 @@ ClangFormatConfigWidget::~ClangFormatConfigWidget() = default;
void ClangFormatConfigWidget::apply()
{
+ ClangFormatSettings &settings = ClangFormatSettings::instance();
if (!m_project) {
- ClangFormatSettings &settings = ClangFormatSettings::instance();
settings.setFormatCodeInsteadOfIndent(m_ui->formatAlways->isChecked());
settings.setFormatWhileTyping(m_ui->formatWhileTyping->isChecked());
settings.setFormatOnSave(m_ui->formatOnSave->isChecked());
- settings.write();
+ settings.setOverrideDefaultFile(m_ui->overrideDefault->isChecked());
+ } else {
+ m_project->setNamedSettings(Constants::OVERRIDE_FILE_ID, m_ui->overrideDefault->isChecked());
}
+ settings.write();
+
+ if (!m_ui->overrideDefault->isChecked())
+ return;
const QString text = m_ui->clangFormatOptionsTable->toPlainText();
clang::format::FormatStyle style;
@@ -184,16 +200,18 @@ void ClangFormatConfigWidget::apply()
QMessageBox::warning(this,
tr("Error in ClangFormat configuration"),
QString::fromStdString(error.message()));
- fillTable();
- updatePreview();
+ if (m_ui->overrideDefault->isChecked()) {
+ fillTable();
+ updatePreview();
+ }
return;
}
- QString filePath;
+ QString filePath = Core::ICore::userResourcePath();
if (m_project)
- filePath = m_project->projectDirectory().appendPath(Constants::SETTINGS_FILE_NAME).toString();
- else
- filePath = Core::ICore::userResourcePath() + "/" + Constants::SETTINGS_FILE_NAME;
+ filePath += "/clang-format/" + currentProjectUniqueId();
+ filePath += "/" + QLatin1String(Constants::SETTINGS_FILE_NAME);
+
QFile file(filePath);
if (!file.open(QFile::WriteOnly))
return;
@@ -201,7 +219,8 @@ void ClangFormatConfigWidget::apply()
file.write(text.toUtf8());
file.close();
- updatePreview();
+ if (m_ui->overrideDefault->isChecked())
+ updatePreview();
}
} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatconfigwidget.ui b/src/plugins/clangformat/clangformatconfigwidget.ui
index 41e40ef1fd..c8225981f5 100644
--- a/src/plugins/clangformat/clangformatconfigwidget.ui
+++ b/src/plugins/clangformat/clangformatconfigwidget.ui
@@ -55,6 +55,13 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="overrideDefault">
+ <property name="text">
+ <string>Override Clang Format configuration file</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPlainTextEdit" name="clangFormatOptionsTable"/>
@@ -64,13 +71,6 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QPushButton" name="createFileButton">
- <property name="text">
- <string>Create Clang Format Configuration File</string>
- </property>
- </widget>
- </item>
- <item>
<widget class="QPushButton" name="applyButton">
<property name="text">
<string>Apply</string>
diff --git a/src/plugins/clangformat/clangformatconstants.h b/src/plugins/clangformat/clangformatconstants.h
index 8b7cbcf9bd..2635dbedea 100644
--- a/src/plugins/clangformat/clangformatconstants.h
+++ b/src/plugins/clangformat/clangformatconstants.h
@@ -34,5 +34,7 @@ static const char SETTINGS_ID[] = "ClangFormat";
static const char FORMAT_CODE_INSTEAD_OF_INDENT_ID[] = "ClangFormat.FormatCodeInsteadOfIndent";
static const char FORMAT_WHILE_TYPING_ID[] = "ClangFormat.FormatWhileTyping";
static const char FORMAT_CODE_ON_SAVE_ID[] = "ClangFormat.FormatCodeOnSave";
+static const char OVERRIDE_FILE_ID[] = "ClangFormat.OverrideFile";
+static const char OPEN_CURRENT_CONFIG_ID[] = "ClangFormat.OpenCurrentConfig";
} // namespace Constants
} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatindenter.cpp b/src/plugins/clangformat/clangformatindenter.cpp
index 42cedb7b6c..381762ee7f 100644
--- a/src/plugins/clangformat/clangformatindenter.cpp
+++ b/src/plugins/clangformat/clangformatindenter.cpp
@@ -57,7 +57,7 @@ bool ClangFormatIndenter::formatWhileTyping() const
Utils::optional<TabSettings> ClangFormatIndenter::tabSettings() const
{
- FormatStyle style = currentProjectStyle();
+ FormatStyle style = styleForFile();
TabSettings tabSettings;
switch (style.UseTab) {
diff --git a/src/plugins/clangformat/clangformatplugin.cpp b/src/plugins/clangformat/clangformatplugin.cpp
index 932234f982..e82802ab30 100644
--- a/src/plugins/clangformat/clangformatplugin.cpp
+++ b/src/plugins/clangformat/clangformatplugin.cpp
@@ -26,16 +26,23 @@
#include "clangformatplugin.h"
#include "clangformatconfigwidget.h"
+#include "clangformatconstants.h"
#include "clangformatindenter.h"
+#include "clangformatutils.h"
#include <utils/qtcassert.h>
-#include <coreplugin/icore.h>
-#include <coreplugin/icontext.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
-#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/editormanager/ieditor.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/icore.h>
+#include <coreplugin/idocument.h>
+
+#include <cppeditor/cppeditorconstants.h>
#include <cpptools/cppcodestylepreferencesfactory.h>
#include <cpptools/cpptoolsconstants.h>
@@ -103,6 +110,48 @@ bool ClangFormatPlugin::initialize(const QStringList &arguments, QString *errorS
Q_UNUSED(errorString);
#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
replaceCppCodeStyle();
+
+ Core::ActionContainer *contextMenu = Core::ActionManager::actionContainer(
+ CppEditor::Constants::M_CONTEXT);
+ if (contextMenu) {
+ auto openClangFormatConfigAction
+ = new QAction(tr("Open Used .clang-format Configuration File"), this);
+ Core::Command *command
+ = Core::ActionManager::registerAction(openClangFormatConfigAction,
+ Constants::OPEN_CURRENT_CONFIG_ID);
+ contextMenu->addSeparator();
+ contextMenu->addAction(command);
+
+ if (Core::EditorManager::currentEditor()) {
+ const Core::IDocument *doc = Core::EditorManager::currentEditor()->document();
+ if (doc)
+ openClangFormatConfigAction->setData(doc->filePath().toString());
+ }
+
+ connect(openClangFormatConfigAction,
+ &QAction::triggered,
+ this,
+ [openClangFormatConfigAction]() {
+ const QString fileName = openClangFormatConfigAction->data().toString();
+ if (!fileName.isEmpty()) {
+ const QString clangFormatConfigPath = configForFile(
+ Utils::FileName::fromString(fileName));
+ Core::EditorManager::openEditor(clangFormatConfigPath);
+ }
+ });
+
+ connect(Core::EditorManager::instance(),
+ &Core::EditorManager::currentEditorChanged,
+ this,
+ [openClangFormatConfigAction](Core::IEditor *editor) {
+ if (!editor)
+ return;
+
+ const Core::IDocument *doc = editor->document();
+ if (doc)
+ openClangFormatConfigAction->setData(doc->filePath().toString());
+ });
+ }
#endif
return true;
}
diff --git a/src/plugins/clangformat/clangformatsettings.cpp b/src/plugins/clangformat/clangformatsettings.cpp
index 8be2b3cefe..8f70130ae3 100644
--- a/src/plugins/clangformat/clangformatsettings.cpp
+++ b/src/plugins/clangformat/clangformatsettings.cpp
@@ -46,6 +46,8 @@ ClangFormatSettings::ClangFormatSettings()
.toBool();
m_formatOnSave = settings->value(QLatin1String(Constants::FORMAT_CODE_ON_SAVE_ID), false)
.toBool();
+ m_overrideDefaultFile = settings->value(QLatin1String(Constants::OVERRIDE_FILE_ID), false)
+ .toBool();
settings->endGroup();
}
@@ -57,6 +59,7 @@ void ClangFormatSettings::write() const
m_formatCodeInsteadOfIndent);
settings->setValue(QLatin1String(Constants::FORMAT_WHILE_TYPING_ID), m_formatWhileTyping);
settings->setValue(QLatin1String(Constants::FORMAT_CODE_ON_SAVE_ID), m_formatOnSave);
+ settings->setValue(QLatin1String(Constants::OVERRIDE_FILE_ID), m_overrideDefaultFile);
settings->endGroup();
}
@@ -90,4 +93,14 @@ bool ClangFormatSettings::formatOnSave() const
return m_formatOnSave;
}
+void ClangFormatSettings::setOverrideDefaultFile(bool enable)
+{
+ m_overrideDefaultFile = enable;
+}
+
+bool ClangFormatSettings::overrideDefaultFile() const
+{
+ return m_overrideDefaultFile;
+}
+
} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatsettings.h b/src/plugins/clangformat/clangformatsettings.h
index 0ea9ed9747..9344cf34a9 100644
--- a/src/plugins/clangformat/clangformatsettings.h
+++ b/src/plugins/clangformat/clangformatsettings.h
@@ -25,6 +25,8 @@
#pragma once
+#include <QString>
+
namespace ClangFormat {
class ClangFormatSettings
@@ -43,10 +45,14 @@ public:
void setFormatOnSave(bool enable);
bool formatOnSave() const;
+
+ void setOverrideDefaultFile(bool enable);
+ bool overrideDefaultFile() const;
private:
bool m_formatCodeInsteadOfIndent = false;
bool m_formatWhileTyping = false;
bool m_formatOnSave = false;
+ bool m_overrideDefaultFile = false;
};
} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatutils.cpp b/src/plugins/clangformat/clangformatutils.cpp
index babe94da24..74c4165a34 100644
--- a/src/plugins/clangformat/clangformatutils.cpp
+++ b/src/plugins/clangformat/clangformatutils.cpp
@@ -26,6 +26,7 @@
#include "clangformatutils.h"
#include "clangformatconstants.h"
+#include "clangformatsettings.h"
#include <coreplugin/icore.h>
#include <cpptools/cppcodestylesettings.h>
@@ -33,6 +34,8 @@
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
+#include <QCryptographicHash>
+
using namespace clang;
using namespace format;
using namespace llvm;
@@ -42,6 +45,104 @@ using namespace TextEditor;
namespace ClangFormat {
+static clang::format::FormatStyle qtcStyle()
+{
+ clang::format::FormatStyle style = getLLVMStyle();
+ style.Language = FormatStyle::LK_Cpp;
+ style.AccessModifierOffset = -4;
+ style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
+ style.AlignConsecutiveAssignments = false;
+ style.AlignConsecutiveDeclarations = false;
+ style.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ style.AlignOperands = true;
+ style.AlignTrailingComments = true;
+ style.AllowAllParametersOfDeclarationOnNextLine = true;
+ style.AllowShortBlocksOnASingleLine = false;
+ style.AllowShortCaseLabelsOnASingleLine = false;
+ style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+ style.AllowShortIfStatementsOnASingleLine = false;
+ style.AllowShortLoopsOnASingleLine = false;
+ style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
+ style.AlwaysBreakBeforeMultilineStrings = false;
+ style.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
+ style.BinPackArguments = false;
+ style.BinPackParameters = false;
+ style.BraceWrapping.AfterClass = true;
+ style.BraceWrapping.AfterControlStatement = false;
+ style.BraceWrapping.AfterEnum = false;
+ style.BraceWrapping.AfterFunction = true;
+ style.BraceWrapping.AfterNamespace = false;
+ style.BraceWrapping.AfterObjCDeclaration = false;
+ style.BraceWrapping.AfterStruct = true;
+ style.BraceWrapping.AfterUnion = false;
+ style.BraceWrapping.BeforeCatch = false;
+ style.BraceWrapping.BeforeElse = false;
+ style.BraceWrapping.IndentBraces = false;
+ style.BraceWrapping.SplitEmptyFunction = false;
+ style.BraceWrapping.SplitEmptyRecord = false;
+ style.BraceWrapping.SplitEmptyNamespace = false;
+ style.BreakBeforeBinaryOperators = FormatStyle::BOS_All;
+ style.BreakBeforeBraces = FormatStyle::BS_Custom;
+ style.BreakBeforeTernaryOperators = true;
+ style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
+ style.BreakAfterJavaFieldAnnotations = false;
+ style.BreakStringLiterals = true;
+ style.ColumnLimit = 100;
+ style.CommentPragmas = "^ IWYU pragma:";
+ style.CompactNamespaces = false;
+ style.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
+ style.ConstructorInitializerIndentWidth = 4;
+ style.ContinuationIndentWidth = 4;
+ style.Cpp11BracedListStyle = true;
+ style.DerivePointerAlignment = false;
+ style.DisableFormat = false;
+ style.ExperimentalAutoDetectBinPacking = false;
+ style.FixNamespaceComments = true;
+ style.ForEachMacros = {"forever", "foreach", "Q_FOREACH", "BOOST_FOREACH"};
+ style.IncludeStyle.IncludeCategories = {{"^<Q.*", 200}};
+ style.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
+ style.IndentCaseLabels = false;
+ style.IndentWidth = 4;
+ style.IndentWrappedFunctionNames = false;
+ style.JavaScriptQuotes = FormatStyle::JSQS_Leave;
+ style.JavaScriptWrapImports = true;
+ style.KeepEmptyLinesAtTheStartOfBlocks = false;
+ // Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between.
+ style.MacroBlockBegin = "";
+ style.MacroBlockEnd = "";
+ style.MaxEmptyLinesToKeep = 1;
+ style.NamespaceIndentation = FormatStyle::NI_None;
+ style.ObjCBlockIndentWidth = 4;
+ style.ObjCSpaceAfterProperty = false;
+ style.ObjCSpaceBeforeProtocolList = true;
+ style.PenaltyBreakAssignment = 150;
+ style.PenaltyBreakBeforeFirstCallParameter = 300;
+ style.PenaltyBreakComment = 500;
+ style.PenaltyBreakFirstLessLess = 400;
+ style.PenaltyBreakString = 600;
+ style.PenaltyExcessCharacter = 50;
+ style.PenaltyReturnTypeOnItsOwnLine = 300;
+ style.PointerAlignment = FormatStyle::PAS_Right;
+ style.ReflowComments = false;
+ style.SortIncludes = true;
+ style.SortUsingDeclarations = true;
+ style.SpaceAfterCStyleCast = true;
+ style.SpaceAfterTemplateKeyword = false;
+ style.SpaceBeforeAssignmentOperators = true;
+ style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
+ style.SpaceInEmptyParentheses = false;
+ style.SpacesBeforeTrailingComments = 1;
+ style.SpacesInAngles = false;
+ style.SpacesInContainerLiterals = false;
+ style.SpacesInCStyleCastParentheses = false;
+ style.SpacesInParentheses = false;
+ style.SpacesInSquareBrackets = false;
+ style.Standard = FormatStyle::LS_Cpp11;
+ style.TabWidth = 4;
+ style.UseTab = FormatStyle::UT_Never;
+ return style;
+}
+
static void applyTabSettings(clang::format::FormatStyle &style, const TabSettings &settings)
{
style.IndentWidth = static_cast<unsigned>(settings.m_indentSize);
@@ -63,72 +164,86 @@ static void applyTabSettings(clang::format::FormatStyle &style, const TabSetting
}
}
-static void applyCppCodeStyleSettings(clang::format::FormatStyle &style,
- const CppCodeStyleSettings &settings)
+static bool useGlobalOverriddenSettings()
{
- style.IndentCaseLabels = settings.indentSwitchLabels;
- style.AlignOperands = settings.alignAssignments;
- style.NamespaceIndentation = FormatStyle::NI_None;
- if (settings.indentNamespaceBody)
- style.NamespaceIndentation = FormatStyle::NI_All;
+ return ClangFormatSettings::instance().overrideDefaultFile();
+}
- style.BraceWrapping.IndentBraces = false;
- if (settings.indentBlockBraces) {
- if (settings.indentClassBraces && settings.indentEnumBraces
- && settings.indentNamespaceBraces && settings.indentFunctionBraces) {
- style.BraceWrapping.IndentBraces = true;
- } else {
- style.BreakBeforeBraces = FormatStyle::BS_GNU;
- }
- }
+QString currentProjectUniqueId()
+{
+ const Project *project = SessionManager::startupProject();
+ if (!project)
+ return QString();
- if (settings.bindStarToIdentifier || settings.bindStarToRightSpecifier)
- style.PointerAlignment = FormatStyle::PAS_Right;
- else
- style.PointerAlignment = FormatStyle::PAS_Left;
+ return QString::fromUtf8(QCryptographicHash::hash(project->projectFilePath().toString().toUtf8(),
+ QCryptographicHash::Md5)
+ .toHex(0));
+}
+
+static bool useProjectOverriddenSettings()
+{
+ const Project *project = SessionManager::startupProject();
+ return project ? project->namedSettings(Constants::OVERRIDE_FILE_ID).toBool() : false;
+}
- style.AccessModifierOffset = settings.indentAccessSpecifiers
- ? 0
- : - static_cast<int>(style.IndentWidth);
+static Utils::FileName globalPath()
+{
+ return Utils::FileName::fromString(Core::ICore::userResourcePath());
}
static Utils::FileName projectPath()
{
const Project *project = SessionManager::startupProject();
if (project)
- return project->projectDirectory();
+ return globalPath().appendPath("clang-format").appendPath(currentProjectUniqueId());
return Utils::FileName();
}
-static Utils::FileName globalPath()
+static QString findConfig(Utils::FileName fileName)
{
- return Utils::FileName::fromString(Core::ICore::userResourcePath());
+ QDir parentDir(fileName.parentDir().toString());
+ while (!parentDir.exists(Constants::SETTINGS_FILE_NAME)
+ && !parentDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) {
+ if (!parentDir.cdUp())
+ return QString();
+ }
+
+ if (parentDir.exists(Constants::SETTINGS_FILE_NAME))
+ return parentDir.filePath(Constants::SETTINGS_FILE_NAME);
+ return parentDir.filePath(Constants::SETTINGS_FILE_ALT_NAME);
}
-static QString configForFile(Utils::FileName fileName)
+static QString configForFile(Utils::FileName fileName, bool checkForSettings)
{
- Utils::FileName topProjectPath = projectPath();
- if (topProjectPath.isEmpty())
- return QString();
+ QDir overrideDir;
+ if (!checkForSettings || useProjectOverriddenSettings()) {
+ overrideDir = projectPath().toString();
+ if (!overrideDir.isEmpty() && overrideDir.exists(Constants::SETTINGS_FILE_NAME))
+ return overrideDir.filePath(Constants::SETTINGS_FILE_NAME);
+ }
- QDir projectDir(fileName.parentDir().toString());
- while (!projectDir.exists(Constants::SETTINGS_FILE_NAME)
- && !projectDir.exists(Constants::SETTINGS_FILE_ALT_NAME)) {
- if (projectDir.path() == topProjectPath.toString()
- || !Utils::FileName::fromString(projectDir.path()).isChildOf(topProjectPath)
- || !projectDir.cdUp()) {
- return QString();
- }
+ if (!checkForSettings || useGlobalOverriddenSettings()) {
+ overrideDir = globalPath().toString();
+ if (!overrideDir.isEmpty() && overrideDir.exists(Constants::SETTINGS_FILE_NAME))
+ return overrideDir.filePath(Constants::SETTINGS_FILE_NAME);
}
- if (projectDir.exists(Constants::SETTINGS_FILE_NAME))
- return projectDir.filePath(Constants::SETTINGS_FILE_NAME);
- return projectDir.filePath(Constants::SETTINGS_FILE_ALT_NAME);
+ return findConfig(fileName);
+}
+
+QString configForFile(Utils::FileName fileName)
+{
+ return configForFile(fileName, true);
+}
+
+Utils::FileName assumedPathForConfig(const QString &configFile)
+{
+ Utils::FileName fileName = Utils::FileName::fromString(configFile);
+ return fileName.parentDir().appendPath("test.cpp");
}
-static clang::format::FormatStyle constructStyle(bool isGlobal,
- const QByteArray &baseStyle = QByteArray())
+static clang::format::FormatStyle constructStyle(const QByteArray &baseStyle = QByteArray())
{
if (!baseStyle.isEmpty()) {
// Try to get the style for this base style.
@@ -144,21 +259,7 @@ static clang::format::FormatStyle constructStyle(bool isGlobal,
// Fallthrough to the default style.
}
- FormatStyle style = getLLVMStyle();
- style.BreakBeforeBraces = FormatStyle::BS_Custom;
-
- const CppCodeStyleSettings codeStyleSettings = isGlobal
- ? CppCodeStyleSettings::currentGlobalCodeStyle()
- : CppCodeStyleSettings::currentProjectCodeStyle()
- .value_or(CppCodeStyleSettings::currentGlobalCodeStyle());
- const TabSettings tabSettings = isGlobal
- ? CppCodeStyleSettings::currentGlobalTabSettings()
- : CppCodeStyleSettings::currentProjectTabSettings();
-
- applyTabSettings(style, tabSettings);
- applyCppCodeStyleSettings(style, codeStyleSettings);
-
- return style;
+ return qtcStyle();
}
void createStyleFileIfNeeded(bool isGlobal)
@@ -169,9 +270,21 @@ void createStyleFileIfNeeded(bool isGlobal)
if (QFile::exists(configFile))
return;
+ QDir().mkpath(path.parentDir().toString());
+ if (!isGlobal) {
+ const Project *project = SessionManager::startupProject();
+ Utils::FileName possibleProjectConfig = project->rootProjectDirectory().appendPath(
+ Constants::SETTINGS_FILE_NAME);
+ if (possibleProjectConfig.exists()) {
+ // Just copy th .clang-format if current project has one.
+ QFile::copy(possibleProjectConfig.toString(), configFile);
+ return;
+ }
+ }
+
std::fstream newStyleFile(configFile.toStdString(), std::fstream::out);
if (newStyleFile.is_open()) {
- newStyleFile << clang::format::configurationAsText(constructStyle(isGlobal));
+ newStyleFile << clang::format::configurationAsText(constructStyle());
newStyleFile.close();
}
}
@@ -198,17 +311,13 @@ static QByteArray configBaseStyleName(const QString &configFile)
.trimmed();
}
-clang::format::FormatStyle styleForFile(Utils::FileName fileName)
+static clang::format::FormatStyle styleForFile(Utils::FileName fileName, bool checkForSettings)
{
- bool isGlobal = false;
- QString configFile = configForFile(fileName);
- if (configFile.isEmpty()) {
- Utils::FileName path = fileName = globalPath();
- fileName.appendPath(Constants::SAMPLE_FILE_NAME);
- createStyleFileIfNeeded(true);
- configFile = path.appendPath(Constants::SETTINGS_FILE_NAME).toString();
- }
+ QString configFile = configForFile(fileName, checkForSettings);
+ if (configFile.isEmpty())
+ return constructStyle();
+ fileName = assumedPathForConfig(configFile);
Expected<FormatStyle> style = format::getStyle("file",
fileName.toString().toStdString(),
"none");
@@ -219,17 +328,21 @@ clang::format::FormatStyle styleForFile(Utils::FileName fileName)
// do nothing
});
- return constructStyle(isGlobal, configBaseStyleName(configFile));
+ return constructStyle(configBaseStyleName(configFile));
}
-clang::format::FormatStyle currentProjectStyle()
+clang::format::FormatStyle styleForFile(Utils::FileName fileName)
{
- return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME));
+ return styleForFile(fileName, true);
}
-clang::format::FormatStyle currentGlobalStyle()
+clang::format::FormatStyle currentProjectStyle()
{
- return styleForFile(globalPath().appendPath(Constants::SAMPLE_FILE_NAME));
+ return styleForFile(projectPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
}
+clang::format::FormatStyle currentGlobalStyle()
+{
+ return styleForFile(globalPath().appendPath(Constants::SAMPLE_FILE_NAME), false);
}
+} // namespace ClangFormat
diff --git a/src/plugins/clangformat/clangformatutils.h b/src/plugins/clangformat/clangformatutils.h
index 41e2b5611f..bd53076943 100644
--- a/src/plugins/clangformat/clangformatutils.h
+++ b/src/plugins/clangformat/clangformatutils.h
@@ -25,6 +25,7 @@
#pragma once
+#include <coreplugin/id.h>
#include <utils/fileutils.h>
#include <clang/Format/Format.h>
@@ -37,10 +38,13 @@ namespace ClangFormat {
// Creates the style for the current project or the global style if needed.
void createStyleFileIfNeeded(bool isGlobal);
+QString currentProjectUniqueId();
+
clang::format::FormatStyle currentProjectStyle();
clang::format::FormatStyle currentGlobalStyle();
// Is the style from the matching .clang-format file or global one if it's not found.
+QString configForFile(Utils::FileName fileName);
clang::format::FormatStyle styleForFile(Utils::FileName fileName);
}
diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp
index 2dc381f6a3..43858cc865 100644
--- a/src/plugins/clangtools/clangtidyclazytool.cpp
+++ b/src/plugins/clangtools/clangtidyclazytool.cpp
@@ -452,12 +452,12 @@ void ClangTidyClazyTool::handleStateUpdate()
if (issuesFound)
message = tr("Running - %n diagnostics", nullptr, issuesFound);
else
- message = tr("Running - No diagnostics", nullptr, issuesFound);
+ message = tr("Running - No diagnostics");
} else {
if (issuesFound)
message = tr("Finished - %n diagnostics", nullptr, issuesFound);
else
- message = tr("Finished - No diagnostics", nullptr, issuesFound);
+ message = tr("Finished - No diagnostics");
}
Debugger::showPermanentStatusMessage(message);
diff --git a/src/plugins/coreplugin/find/searchresulttreeview.cpp b/src/plugins/coreplugin/find/searchresulttreeview.cpp
index 6a9b7067bf..0ca09fcefd 100644
--- a/src/plugins/coreplugin/find/searchresulttreeview.cpp
+++ b/src/plugins/coreplugin/find/searchresulttreeview.cpp
@@ -78,6 +78,21 @@ void SearchResultTreeView::addResults(const QList<SearchResultItem> &items, Sear
}
}
+void SearchResultTreeView::keyPressEvent(QKeyEvent *event)
+{
+ if ((event->key() == Qt::Key_Return
+ || event->key() == Qt::Key_Enter)
+ && event->modifiers() == 0
+ && currentIndex().isValid()
+ && state() != QAbstractItemView::EditingState) {
+ const SearchResultItem item
+ = model()->data(currentIndex(), ItemDataRoles::ResultItemRole).value<SearchResultItem>();
+ emit jumpToSearchResult(item);
+ return;
+ }
+ TreeView::keyPressEvent(event);
+}
+
void SearchResultTreeView::emitJumpToSearchResult(const QModelIndex &index)
{
if (model()->data(index, ItemDataRoles::IsGeneratedRole).toBool())
diff --git a/src/plugins/coreplugin/find/searchresulttreeview.h b/src/plugins/coreplugin/find/searchresulttreeview.h
index 961940fe01..eb11d29a7d 100644
--- a/src/plugins/coreplugin/find/searchresulttreeview.h
+++ b/src/plugins/coreplugin/find/searchresulttreeview.h
@@ -49,6 +49,8 @@ public:
SearchResultTreeModel *model() const;
void addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode);
+ void keyPressEvent(QKeyEvent *event) override;
+
signals:
void jumpToSearchResult(const SearchResultItem &item);
diff --git a/src/plugins/coreplugin/helpitem.h b/src/plugins/coreplugin/helpitem.h
index 15ff585ca8..c258eed0d8 100644
--- a/src/plugins/coreplugin/helpitem.h
+++ b/src/plugins/coreplugin/helpitem.h
@@ -84,10 +84,9 @@ public:
const Links &links() const;
const Links bestLinks() const;
const QString keyword() const;
-
-private:
bool isFuzzyMatch() const;
+private:
QUrl m_helpUrl;
QStringList m_helpIds;
QString m_docMark;
diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp
index 2421bd776a..994c9e5d0e 100644
--- a/src/plugins/coreplugin/locator/locatorwidget.cpp
+++ b/src/plugins/coreplugin/locator/locatorwidget.cpp
@@ -252,6 +252,14 @@ void LocatorModel::addEntries(const QList<LocatorFilterEntry> &entries)
CompletionList::CompletionList(QWidget *parent)
: Utils::TreeView(parent)
{
+ // on macOS and Windows the popup doesn't really get focus, so fake the selection color
+ // which would then just be a very light gray, but should look as if it had focus
+ QPalette p = palette();
+ p.setBrush(QPalette::Inactive,
+ QPalette::Highlight,
+ p.brush(QPalette::Normal, QPalette::Highlight));
+ setPalette(p);
+
setItemDelegate(new CompletionDelegate(this));
setRootIsDecorated(false);
setUniformRowHeights(true);
diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp
index 3f19d4b9b9..eb411bdaa9 100644
--- a/src/plugins/coreplugin/outputpanemanager.cpp
+++ b/src/plugins/coreplugin/outputpanemanager.cpp
@@ -507,7 +507,6 @@ void OutputPaneManager::showPage(int idx, int flags)
ensurePageVisible(idx);
IOutputPane *out = g_outputPanes.at(idx).pane;
- out->visibilityChanged(true);
if (flags & IOutputPane::WithFocus) {
if (out->canFocus())
out->setFocus();
@@ -538,7 +537,10 @@ void OutputPaneManager::setCurrentIndex(int idx)
m_outputWidgetPane->setCurrentIndex(idx);
m_opToolBarWidgets->setCurrentIndex(idx);
- IOutputPane *pane = g_outputPanes.at(idx).pane;
+ OutputPaneData &data = g_outputPanes[idx];
+ IOutputPane *pane = data.pane;
+ data.button->show();
+ data.buttonVisible = true;
pane->visibilityChanged(true);
bool canNavigate = pane->canNavigate();
@@ -574,8 +576,6 @@ void OutputPaneManager::popupMenu()
data.button->hide();
data.buttonVisible = false;
} else {
- data.button->show();
- data.buttonVisible = true;
showPage(idx, IOutputPane::ModeSwitch);
}
}
diff --git a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp
index e19a94513d..4f03a681f0 100644
--- a/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp
+++ b/src/plugins/cpptools/clangdiagnosticconfigswidget.cpp
@@ -860,11 +860,11 @@ void ClangDiagnosticConfigsWidget::syncClazyChecksGroupBox()
return !m_clazySortFilterProxyModel->filterAcceptsRow(index.row(), index.parent());
};
const bool hasEnabledButHidden = m_clazyTreeModel->hasEnabledButNotVisibleChecks(isHidden);
- const QString title = hasEnabledButHidden ? tr("Checks (%1 enabled, some are filtered out)")
- : tr("Checks (%1 enabled)");
-
- const QStringList checks = m_clazyTreeModel->enabledChecks();
- m_clazyChecks->checksGroupBox->setTitle(title.arg(checks.count()));
+ const int checksCount = m_clazyTreeModel->enabledChecks().count();
+ const QString title = hasEnabledButHidden ? tr("Checks (%n enabled, some are filtered out)",
+ nullptr, checksCount)
+ : tr("Checks (%n enabled)", nullptr, checksCount);
+ m_clazyChecks->checksGroupBox->setTitle(title);
}
void ClangDiagnosticConfigsWidget::updateConfig(const ClangDiagnosticConfig &config)
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index e5685dc5e0..8dfe0c7977 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -172,7 +172,7 @@ void CompilerOptionsBuilder::addSyntaxOnly()
isClStyle() ? add("/Zs") : add("-fsyntax-only");
}
-static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
+QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
{
QStringList options;
@@ -741,6 +741,15 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
continue;
}
+ if (option.startsWith("/Y", Qt::CaseSensitive)
+ || (option.startsWith("/F", Qt::CaseSensitive) && option != "/F")) {
+ // Precompiled header flags.
+ // Skip also the next option if it's not glued to the current one.
+ if (option.size() > 3)
+ skipNext = true;
+ continue;
+ }
+
// Check whether a language version is already used.
QString theOption = option;
if (theOption.startsWith("-std=")) {
diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h
index 03564ab616..349279710a 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.h
+++ b/src/plugins/cpptools/compileroptionsbuilder.h
@@ -40,6 +40,7 @@ enum class UseBuildSystemWarnings : char { Yes, No };
CPPTOOLS_EXPORT QStringList XclangArgs(const QStringList &args);
CPPTOOLS_EXPORT QStringList clangArgsForCl(const QStringList &args);
+CPPTOOLS_EXPORT QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt);
class CPPTOOLS_EXPORT CompilerOptionsBuilder
{
diff --git a/src/plugins/cpptools/cppfilesettingspage.ui b/src/plugins/cpptools/cppfilesettingspage.ui
index 9edf2cd5da..7bb13449ac 100644
--- a/src/plugins/cpptools/cppfilesettingspage.ui
+++ b/src/plugins/cpptools/cppfilesettingspage.ui
@@ -99,10 +99,10 @@ These prefixes are used in addition to current file name on Switch Header/Source
<item row="7" column="1">
<widget class="QCheckBox" name="headerPragmaOnceCheckBox">
<property name="toolTip">
- <string>Uses #pragma once instead of #ifndef include guards.</string>
+ <string>Uses &quot;#pragma once&quot; instead of &quot;#ifndef&quot; include guards.</string>
</property>
<property name="text">
- <string>Use '#pragma once' instead of '#ifndef' guards</string>
+ <string>Use &quot;#pragma once&quot; instead of &quot;#ifndef&quot; guards</string>
</property>
</widget>
</item>
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index 8068c27d0b..d2ca6d5d0b 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -211,7 +211,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
expander->registerVariable(
"Cpp:PragmaOnce",
- tr("Insert #pragma once instead of #ifndef include guards into header file"),
+ tr("Insert \"#pragma once\" instead of \"#ifndef\" include guards into header file"),
[] { return usePragmaOnce() ? QString("true") : QString(); });
return true;
diff --git a/src/plugins/debugger/console/console.h b/src/plugins/debugger/console/console.h
index c46add0a86..4690283a34 100644
--- a/src/plugins/debugger/console/console.h
+++ b/src/plugins/debugger/console/console.h
@@ -58,7 +58,7 @@ public:
QWidget *outputWidget(QWidget *) override;
QList<QWidget *> toolBarWidgets() const override;
- QString displayName() const override { return tr("Debugger Console"); }
+ QString displayName() const override { return tr("QML Debugger Console"); }
int priorityInStatusBar() const override;
void clearContents() override;
void visibilityChanged(bool visible) override;
diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp
index adc81bee69..4a7fb5d4a3 100644
--- a/src/plugins/debugger/debuggeritemmanager.cpp
+++ b/src/plugins/debugger/debuggeritemmanager.cpp
@@ -748,7 +748,8 @@ void DebuggerItemManagerPrivate::autoDetectGdbOrLldbDebuggers()
dir.setPath(base.toFileInfo().absoluteFilePath());
foreach (const QString &entry, dir.entryList()) {
if (entry.startsWith("lldb-platform-")
- || entry.startsWith("lldb-gdbserver-")) {
+ || entry.startsWith("lldb-gdbserver-")
+ || entry.startsWith("lldb-mi-")) {
continue;
}
suspects.append(FileName::fromString(dir.absoluteFilePath(entry)));
diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp
index b85962bd0e..9783184346 100644
--- a/src/plugins/debugger/debuggerkitinformation.cpp
+++ b/src/plugins/debugger/debuggerkitinformation.cpp
@@ -152,24 +152,7 @@ DebuggerKitAspect::DebuggerKitAspect()
setPriority(28000);
}
-QVariant DebuggerKitAspect::defaultValue(const Kit *k) const
-{
- const Abi toolChainAbi = ToolChainKitAspect::targetAbi(k);
- const Utils::FileNameList paths = Environment::systemEnvironment().path();
- QVariant nextBestFit;
- for (const DebuggerItem &item : DebuggerItemManager::debuggers()) {
- for (const Abi &targetAbi : item.abis()) {
- if (targetAbi.isCompatibleWith(toolChainAbi)) {
- if (paths.contains(item.command()))
- return item.id(); // prefer debuggers found in PATH over those found elsewhere
- if (nextBestFit.isNull())
- nextBestFit = item.id();
- }
- }
- }
-
- return nextBestFit;
-}
+QVariant DebuggerKitAspect::defaultValue(const Kit *) const { return QVariant(); }
void DebuggerKitAspect::setup(Kit *k)
{
diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp
index 096c03db16..0ddb983dbe 100644
--- a/src/plugins/debugger/debuggermainwindow.cpp
+++ b/src/plugins/debugger/debuggermainwindow.cpp
@@ -119,6 +119,7 @@ public:
void resetCurrentPerspective();
int indexInChooser(Perspective *perspective) const;
void fixupLayoutIfNeeded();
+ void updatePerspectiveChooserWidth();
DebuggerMainWindow *q = nullptr;
Perspective *m_currentPerspective = nullptr;
@@ -416,10 +417,17 @@ void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective)
fixupLayoutIfNeeded();
}
+ updatePerspectiveChooserWidth();
+}
+
+void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
+{
+ Perspective *perspective = m_currentPerspective;
int index = indexInChooser(m_currentPerspective);
if (index == -1) {
- if (Perspective *parent = Perspective::findPerspective(m_currentPerspective->d->m_parentPerspectiveId))
- index = indexInChooser(parent);
+ perspective = Perspective::findPerspective(m_currentPerspective->d->m_parentPerspectiveId);
+ if (perspective)
+ index = indexInChooser(perspective);
}
if (index != -1) {
diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp
index 5bb4845073..19b4011338 100644
--- a/src/plugins/debugger/debuggerruncontrol.cpp
+++ b/src/plugins/debugger/debuggerruncontrol.cpp
@@ -61,6 +61,7 @@
#include <utils/temporarydirectory.h>
#include <utils/temporaryfile.h>
#include <utils/url.h>
+#include <utils/winutils.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
@@ -565,6 +566,17 @@ void DebuggerRunTool::start()
if (!fixupParameters())
return;
+ if (m_runParameters.cppEngineType == CdbEngineType
+ && Utils::is64BitWindowsBinary(m_runParameters.inferior.executable)
+ && !Utils::is64BitWindowsBinary(m_runParameters.debugger.executable)) {
+ reportFailure(
+ DebuggerPlugin::tr(
+ "%1 is a 64 bit executable which can not be debugged by a 32 bit Debugger.\n"
+ "Please select a 64 bit Debugger in the kit settings for this kit.")
+ .arg(m_runParameters.inferior.executable));
+ return;
+ }
+
Utils::globalMacroExpander()->registerFileVariables(
"DebuggedExecutable", tr("Debugged executable"),
[this] { return m_runParameters.inferior.executable; }
diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp
index f0c7642257..9b4f6056f3 100644
--- a/src/plugins/debugger/lldb/lldbengine.cpp
+++ b/src/plugins/debugger/lldb/lldbengine.cpp
@@ -395,6 +395,8 @@ void LldbEngine::handleResponse(const QString &response)
handleOutputNotification(item);
else if (name == "pid")
notifyInferiorPid(item.toProcessHandle());
+ else if (name == "breakpointmodified")
+ handleInterpreterBreakpointModified(item);
}
}
@@ -607,6 +609,31 @@ void LldbEngine::handleOutputNotification(const GdbMi &output)
showMessage(data, ch);
}
+void LldbEngine::handleInterpreterBreakpointModified(const GdbMi &bpItem)
+{
+ QTC_ASSERT(bpItem.childCount(), return);
+ QString id = bpItem.childAt(0).m_data;
+
+ Breakpoint bp = breakHandler()->findBreakpointByResponseId(id);
+ if (!bp) // FIXME adapt whole bp handling and turn into soft assert
+ return;
+
+ // this function got triggered by a lldb internal breakpoint event
+ // avoid asserts regarding unexpected state transitions
+ switch (bp->state()) {
+ case BreakpointInsertionRequested: // was a pending bp
+ bp->gotoState(BreakpointInsertionProceeding, BreakpointInsertionRequested);
+ break;
+ case BreakpointInserted: // was an inserted, gets updated now
+ bp->gotoState(BreakpointUpdateRequested, BreakpointInserted);
+ notifyBreakpointChangeProceeding(bp);
+ break;
+ default:
+ break;
+ }
+ updateBreakpointData(bp, bpItem, false);
+}
+
void LldbEngine::loadSymbols(const QString &moduleName)
{
Q_UNUSED(moduleName)
diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h
index f06798dd39..6c5b3c2c21 100644
--- a/src/plugins/debugger/lldb/lldbengine.h
+++ b/src/plugins/debugger/lldb/lldbengine.h
@@ -120,6 +120,7 @@ private:
void handleStateNotification(const GdbMi &item);
void handleLocationNotification(const GdbMi &location);
void handleOutputNotification(const GdbMi &output);
+ void handleInterpreterBreakpointModified(const GdbMi &item);
void handleResponse(const QString &data);
void updateAll() override;
diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp
index 7abdee2c7c..a887dc5371 100644
--- a/src/plugins/help/helpplugin.cpp
+++ b/src/plugins/help/helpplugin.cpp
@@ -657,7 +657,7 @@ void HelpPluginPrivate::showContextHelp(const HelpItem &contextHelp)
.arg(contextHelp.helpIds().join(", "))
.arg(HelpPlugin::tr("No documentation available.")));
}
- } else if (links.size() == 1) {
+ } else if (links.size() == 1 && !contextHelp.isFuzzyMatch()) {
showHelpUrl(links.front().second, LocalHelpManager::contextHelpOption());
} else {
QMap<QString, QUrl> map;
diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp
index efd4c8fb6f..5553e58ecc 100644
--- a/src/plugins/languageclient/client.cpp
+++ b/src/plugins/languageclient/client.cpp
@@ -208,17 +208,6 @@ void Client::openDocument(Core::IDocument *document)
connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
m_resetAssistProvider.remove(textDocument);
});
- if (BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(textDocument)) {
- if (QPointer<TextEditorWidget> widget = editor->editorWidget()) {
- connect(widget, &TextEditorWidget::cursorPositionChanged, this, [this, widget](){
- // TODO This would better be a compressing timer
- QTimer::singleShot(50, this, [this, widget]() {
- if (widget)
- cursorPositionChanged(widget);
- });
- });
- }
- }
}
m_openedDocument.append(document->filePath());
@@ -344,7 +333,7 @@ void Client::documentContentsChanged(Core::IDocument *document)
if (textDocument) {
using namespace TextEditor;
- if (BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(textDocument))
+ for (BaseTextEditor *editor : BaseTextEditor::textEditorsForDocument(textDocument))
if (TextEditorWidget *widget = editor->editorWidget())
widget->setRefactorMarkers(RefactorMarker::filterOutType(widget->refactorMarkers(), id()));
requestDocumentSymbols(textDocument);
@@ -766,6 +755,11 @@ const DynamicCapabilities &Client::dynamicCapabilities() const
return m_dynamicCapabilities;
}
+const BaseClientInterface *Client::clientInterface() const
+{
+ return m_clientInterface.data();
+}
+
void Client::log(const ShowMessageParams &message,
Core::MessageManager::PrintToOutputPaneFlag flag)
{
diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h
index 2d92424f42..635512fa28 100644
--- a/src/plugins/languageclient/client.h
+++ b/src/plugins/languageclient/client.h
@@ -147,6 +147,7 @@ public:
const LanguageServerProtocol::ServerCapabilities &capabilities() const;
const DynamicCapabilities &dynamicCapabilities() const;
+ const BaseClientInterface *clientInterface() const;
signals:
void initialized(LanguageServerProtocol::ServerCapabilities capabilities);
diff --git a/src/plugins/languageclient/languageclientinterface.cpp b/src/plugins/languageclient/languageclientinterface.cpp
index b67db95dde..0598061720 100644
--- a/src/plugins/languageclient/languageclientinterface.cpp
+++ b/src/plugins/languageclient/languageclientinterface.cpp
@@ -110,7 +110,7 @@ StdIOClientInterface::~StdIOClientInterface()
Utils::SynchronousProcess::stopProcess(m_process);
}
-bool StdIOClientInterface::needsRestart(const StdIOSettings *settings)
+bool StdIOClientInterface::needsRestart(const StdIOSettings *settings) const
{
return m_executable != settings->m_executable || m_arguments != settings->m_arguments;
}
diff --git a/src/plugins/languageclient/languageclientinterface.h b/src/plugins/languageclient/languageclientinterface.h
index 3dc2602d52..182965ab88 100644
--- a/src/plugins/languageclient/languageclientinterface.h
+++ b/src/plugins/languageclient/languageclientinterface.h
@@ -74,7 +74,7 @@ public:
StdIOClientInterface &operator=(const StdIOClientInterface &) = delete;
StdIOClientInterface &operator=(StdIOClientInterface &&) = delete;
- bool needsRestart(const StdIOSettings *settings);
+ bool needsRestart(const StdIOSettings *settings) const;
bool start() override;
diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp
index b097f25a37..1cd162dc51 100644
--- a/src/plugins/languageclient/languageclientmanager.cpp
+++ b/src/plugins/languageclient/languageclientmanager.cpp
@@ -125,7 +125,10 @@ void LanguageClientManager::deleteClient(Client *client)
QTC_ASSERT(client, return);
client->disconnect();
managerInstance->m_clients.removeAll(client);
- client->deleteLater();
+ if (managerInstance->m_shuttingDown)
+ delete client;
+ else
+ client->deleteLater();
}
void LanguageClientManager::shutdown()
@@ -210,6 +213,18 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor)
(const QTextCursor &cursor){
findUsages(filePath, cursor);
});
+ connect(widget, &TextEditorWidget::cursorPositionChanged, this, [this, widget](){
+ // TODO This would better be a compressing timer
+ QTimer::singleShot(50, this,
+ [this, widget = QPointer<TextEditorWidget>(widget)]() {
+ if (widget) {
+ for (Client *client : this->reachableClients()) {
+ if (client->isSupportedDocument(widget->textDocument()))
+ client->cursorPositionChanged(widget);
+ }
+ }
+ });
+ });
}
}
}
diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp
index 276fac15fc..a337a72b7b 100644
--- a/src/plugins/languageclient/languageclientsettings.cpp
+++ b/src/plugins/languageclient/languageclientsettings.cpp
@@ -491,7 +491,9 @@ bool StdIOSettings::needsRestart() const
{
if (BaseSettings::needsRestart())
return true;
- if (auto stdIOInterface = qobject_cast<StdIOClientInterface *>(m_client))
+ if (m_client.isNull())
+ return false;
+ if (auto stdIOInterface = qobject_cast<const StdIOClientInterface *>(m_client->clientInterface()))
return stdIOInterface->needsRestart(this);
return false;
}
diff --git a/src/plugins/languageclient/languageclientutils.cpp b/src/plugins/languageclient/languageclientutils.cpp
index f81be2427c..7a28c5e3a9 100644
--- a/src/plugins/languageclient/languageclientutils.cpp
+++ b/src/plugins/languageclient/languageclientutils.cpp
@@ -133,12 +133,10 @@ void updateCodeActionRefactoringMarker(Client *client,
TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFileName());
if (!doc)
return;
- BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(doc);
- if (!editor)
+ const QVector<BaseTextEditor *> editors = BaseTextEditor::textEditorsForDocument(doc);
+ if (editors.isEmpty())
return;
- TextEditorWidget *editorWidget = editor->editorWidget();
-
const QList<Diagnostic> &diagnostics = action.diagnostics().value_or(QList<Diagnostic>());
RefactorMarkers markers;
@@ -181,7 +179,10 @@ void updateCodeActionRefactoringMarker(Client *client,
marker.cursor = endOfLineCursor(diagnostic.range().start().toTextCursor(doc->document()));
markers << marker;
}
- editorWidget->setRefactorMarkers(markers + editorWidget->refactorMarkers());
+ for (BaseTextEditor *editor : editors) {
+ if (TextEditorWidget *editorWidget = editor->editorWidget())
+ editorWidget->setRefactorMarkers(markers + editorWidget->refactorMarkers());
+ }
}
} // namespace LanguageClient
diff --git a/src/plugins/nim/settings/nimtoolssettingswidget.ui b/src/plugins/nim/settings/nimtoolssettingswidget.ui
index 7322c6a8ec..28c0d1ac31 100644
--- a/src/plugins/nim/settings/nimtoolssettingswidget.ui
+++ b/src/plugins/nim/settings/nimtoolssettingswidget.ui
@@ -10,9 +10,6 @@
<height>300</height>
</rect>
</property>
- <property name="windowTitle">
- <string>Form</string>
- </property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
diff --git a/src/plugins/perfprofiler/perftracepointdialog.cpp b/src/plugins/perfprofiler/perftracepointdialog.cpp
index 07a2c90551..5dc638bbbe 100644
--- a/src/plugins/perfprofiler/perftracepointdialog.cpp
+++ b/src/plugins/perfprofiler/perftracepointdialog.cpp
@@ -96,7 +96,7 @@ PerfTracePointDialog::~PerfTracePointDialog()
void PerfTracePointDialog::runScript()
{
- m_ui->label->setText(tr("Executing script ..."));
+ m_ui->label->setText(tr("Executing script..."));
m_ui->textEdit->setReadOnly(true);
m_ui->privilegesChooser->setEnabled(false);
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
diff --git a/src/plugins/perfprofiler/perftracepointdialog.h b/src/plugins/perfprofiler/perftracepointdialog.h
index 83e2199dad..ca5d4e2ae5 100644
--- a/src/plugins/perfprofiler/perftracepointdialog.h
+++ b/src/plugins/perfprofiler/perftracepointdialog.h
@@ -41,6 +41,8 @@ namespace Ui { class PerfTracePointDialog; }
class PerfTracePointDialog : public QDialog
{
+ Q_OBJECT
+
public:
PerfTracePointDialog();
~PerfTracePointDialog();
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 7b7b88967d..437f9d58ee 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -59,7 +59,6 @@ SUBDIRS = \
languageclient \
cppcheck \
compilationdatabaseprojectmanager \
- perfprofiler \
qmlpreview \
studiowelcome
@@ -70,9 +69,9 @@ qtHaveModule(serialport) {
}
qtHaveModule(quick) {
- SUBDIRS += qmlprofiler
+ SUBDIRS += qmlprofiler perfprofiler
} else {
- warning("QmlProfiler plugin has been disabled since the Qt Quick module is not available.")
+ warning("QmlProfiler and PerfProfiler plugins have been disabled since the Qt Quick module is not available.")
}
qtHaveModule(help) {
diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.h b/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.h
index 1ef030e67f..e69e284250 100644
--- a/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.h
+++ b/src/plugins/projectexplorer/devicesupport/desktopdevicefactory.h
@@ -32,6 +32,8 @@ namespace Internal {
class DesktopDeviceFactory : public IDeviceFactory
{
+ Q_OBJECT
+
public:
DesktopDeviceFactory();
};
diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp
index e92e66c5b2..cc0ca3a39f 100644
--- a/src/plugins/projectexplorer/kit.cpp
+++ b/src/plugins/projectexplorer/kit.cpp
@@ -275,11 +275,9 @@ void Kit::fix()
void Kit::setup()
{
KitGuard g(this);
- // Process the KitAspects in reverse order: They may only be based on other information
- // lower in the stack.
const QList<KitAspect *> aspects = KitManager::kitAspects();
- for (int i = aspects.count() - 1; i >= 0; --i)
- aspects.at(i)->setup(this);
+ for (KitAspect * const aspect : aspects)
+ aspect->setup(this);
}
void Kit::upgrade()
diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp
index 3d40aef1ef..07aa313fcc 100644
--- a/src/plugins/projectexplorer/kitmanager.cpp
+++ b/src/plugins/projectexplorer/kitmanager.cpp
@@ -71,10 +71,12 @@ class KitManagerPrivate
public:
Kit *m_defaultKit = nullptr;
bool m_initialized = false;
- std::vector<std::unique_ptr<KitAspect>> m_informationList;
std::vector<std::unique_ptr<Kit>> m_kitList;
std::unique_ptr<PersistentSettingsWriter> m_writer;
QSet<Id> m_irrelevantAspects;
+
+ // Sorted by priority, in descending order.
+ std::vector<std::unique_ptr<KitAspect>> m_informationList;
};
} // namespace Internal
diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp
index 8b8c571142..9c86a70686 100644
--- a/src/plugins/projectexplorer/msvctoolchain.cpp
+++ b/src/plugins/projectexplorer/msvctoolchain.cpp
@@ -1027,6 +1027,8 @@ bool static hasFlagEffectOnMacros(const QString &flag)
return false; // Skip include paths
if (f.startsWith("w", Qt::CaseInsensitive))
return false; // Skip warning options
+ if (f.startsWith("Y") || (f.startsWith("F") && f != "F"))
+ return false; // Skip pch-related flags
}
return true;
}
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index ed7c16bc1f..5d7d296e70 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -2045,8 +2045,12 @@ void ProjectExplorerPluginPrivate::updateWelcomePage()
void ProjectExplorerPluginPrivate::currentModeChanged(Id mode, Id oldMode)
{
- if (oldMode == Constants::MODE_SESSION)
- ICore::saveSettings();
+ if (oldMode == Constants::MODE_SESSION) {
+ // Saving settings directly in a mode change is not a good idea, since the mode change
+ // can be part of a bigger change. Save settings after that bigger change had a chance to
+ // complete.
+ QTimer::singleShot(0, ICore::instance(), &ICore::saveSettings);
+ }
if (mode == Core::Constants::MODE_WELCOME)
updateWelcomePage();
}
diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp
index 68a0431789..4d71670e7d 100644
--- a/src/plugins/pythoneditor/pythoneditorplugin.cpp
+++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp
@@ -363,7 +363,7 @@ static QStringList readLinesJson(const Utils::FileName &projectFile,
// This assumes te project file is formed with only one field called
// 'files' that has a list associated of the files to include in the project.
if (content.isEmpty()) {
- *errorMessage = PythonProject::tr("Unable read \"%1\": The file is empty.")
+ *errorMessage = PythonProject::tr("Unable to read \"%1\": The file is empty.")
.arg(projectFile.toUserOutput());
return lines;
}
@@ -372,7 +372,7 @@ static QStringList readLinesJson(const Utils::FileName &projectFile,
const QJsonDocument doc = QJsonDocument::fromJson(content, &error);
if (doc.isNull()) {
const int line = content.left(error.offset).count('\n') + 1;
- *errorMessage = PythonProject::tr("Unable parse %1:%2: %3")
+ *errorMessage = PythonProject::tr("Unable to parse \"%1\":%2: %3")
.arg(projectFile.toUserOutput()).arg(line)
.arg(error.errorString());
return lines;
diff --git a/src/plugins/qmldesigner/designercore/include/qmltimeline.h b/src/plugins/qmldesigner/designercore/include/qmltimeline.h
index a92a292119..c04fd454c0 100644
--- a/src/plugins/qmldesigner/designercore/include/qmltimeline.h
+++ b/src/plugins/qmldesigner/designercore/include/qmltimeline.h
@@ -71,10 +71,10 @@ public:
void toogleRecording(bool b) const;
void resetGroupRecording() const;
+ bool hasKeyframeGroup(const ModelNode &node, const PropertyName &propertyName) const;
private:
void addKeyframeGroupIfNotExists(const ModelNode &node, const PropertyName &propertyName);
- bool hasKeyframeGroup(const ModelNode &node, const PropertyName &propertyName) const;
QList<QmlTimelineKeyframeGroup> allKeyframeGroups() const;
};
diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
index 745fdc4d00..65ed482bfb 100644
--- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp
@@ -63,7 +63,7 @@ void QmlObjectNode::setVariantProperty(const PropertyName &name, const QVariant
timelineFrames.setValue(value, frame);
return;
- } else if (modelNode().hasId() && timelineIsActive()) {
+ } else if (modelNode().hasId() && timelineIsActive() && currentTimeline().hasKeyframeGroup(modelNode(), name)) {
QmlTimelineKeyframeGroup timelineFrames(currentTimeline().keyframeGroup(modelNode(), name));
Q_ASSERT(timelineFrames.isValid());
diff --git a/src/plugins/qmldesigner/designersettings.h b/src/plugins/qmldesigner/designersettings.h
index 9b73dc1faf..bdaa22bb4b 100644
--- a/src/plugins/qmldesigner/designersettings.h
+++ b/src/plugins/qmldesigner/designersettings.h
@@ -65,7 +65,6 @@ const char REFORMAT_UI_QML_FILES[] = "ReformatUiQmlFiles"; /* These setti
const char IGNORE_DEVICE_PIXEL_RATIO[] = "IgnoreDevicePixelRaio"; /* The settings can be used to turn off the feature, if there are serious issues */
const char STANDALONE_MODE[] = "StandAloneMode";
const char ENABLE_TIMELINEVIEW[] = "EnableTimelineView";
-const char ENABLE_TIMELINEVIEW_ENVVAR[] = "QTC_ENABLE_QTQUICKTIMELINE_EDITOR";
}
class DesignerSettings : public QHash<QByteArray, QVariant>
diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineanimationform.ui b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineanimationform.ui
index 8bc3e6c973..5d13cfa726 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineanimationform.ui
+++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineanimationform.ui
@@ -10,14 +10,11 @@
<height>176</height>
</rect>
</property>
- <property name="windowTitle">
- <string>Form</string>
- </property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="3">
<widget class="QLabel" name="label_16">
<property name="text">
- <string>Loops</string>
+ <string>Loops:</string>
</property>
</widget>
</item>
@@ -117,7 +114,7 @@
</size>
</property>
<property name="text">
- <string>Animation ID</string>
+ <string>Animation ID:</string>
</property>
</widget>
</item>
@@ -162,14 +159,14 @@
<item row="5" column="1">
<widget class="QLabel" name="label_23">
<property name="text">
- <string>Finished</string>
+ <string>Finished:</string>
</property>
</widget>
</item>
<item row="4" column="7">
<widget class="QLabel" name="label_17">
<property name="text">
- <string>Ping Pong</string>
+ <string>Ping pong</string>
</property>
</widget>
</item>
@@ -205,7 +202,7 @@
</size>
</property>
<property name="text">
- <string>Transition to state</string>
+ <string>Transition to state:</string>
</property>
</widget>
</item>
@@ -222,7 +219,7 @@
<bool>true</bool>
</property>
<property name="text">
- <string>Running in Base State</string>
+ <string>Running in base state</string>
</property>
</widget>
</item>
@@ -257,7 +254,7 @@
<item row="3" column="1">
<widget class="QLabel" name="label_12">
<property name="text">
- <string>Start Frame</string>
+ <string>Start frame:</string>
</property>
</widget>
</item>
@@ -290,14 +287,14 @@
<item row="3" column="7">
<widget class="QLabel" name="label_14">
<property name="text">
- <string>Duration</string>
+ <string>Duration:</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="label_13">
<property name="text">
- <string>End Frame</string>
+ <string>End frame:</string>
</property>
</widget>
</item>
diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineconstants.h b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineconstants.h
index 40e4900442..6c012beec1 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineconstants.h
+++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineconstants.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
@@ -46,13 +46,13 @@ const int priorityTimelineCategory = 110;
const char timelineCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Timeline");
const char timelineCopyKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
- "Copy All Keyframes from item");
+ "Copy All Keyframes");
const char timelinePasteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
- "Paste Keyframes to item");
+ "Paste Keyframes");
const char timelineInsertKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
- "Insert Keyframes for item");
+ "Add Keyframes at Current Frame");
const char timelineDeleteKeyframesDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
- "Delete All Keyframes for item");
+ "Delete All Keyframes");
const char timelineStatusBarFrameNumber[] = QT_TRANSLATE_NOOP("QmlDesignerTimeline", "Frame %1");
diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineform.ui b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineform.ui
index 5eea257be1..b8b47e4c70 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineform.ui
+++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelineform.ui
@@ -10,9 +10,6 @@
<height>170</height>
</rect>
</property>
- <property name="windowTitle">
- <string>Form</string>
- </property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="8" colspan="2">
<spacer name="horizontalSpacer_11">
@@ -84,7 +81,7 @@
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
- <string>Expression Binding</string>
+ <string>Expression binding:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
@@ -107,7 +104,7 @@
<item row="2" column="4">
<widget class="QLabel" name="label_7">
<property name="text">
- <string>End Frame</string>
+ <string>End frame:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
@@ -200,7 +197,7 @@
<bool>false</bool>
</property>
<property name="text">
- <string>Expression Binding</string>
+ <string>Expression binding</string>
</property>
</widget>
</item>
@@ -214,7 +211,7 @@
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
- <string>Timeline ID</string>
+ <string>Timeline ID:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
@@ -243,7 +240,7 @@
<item row="2" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
- <string>Start Frame</string>
+ <string>Start frame:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.h b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.h
index 5cd241b7a3..2b8c00c59b 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.h
+++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinepropertyitem.h
@@ -44,6 +44,8 @@ class TimelineToolButton;
class TimelineKeyframeItem : public TimelineMovableAbstractItem
{
+ Q_DECLARE_TR_FUNCTIONS(TimelineKeyframeItem)
+
public:
explicit TimelineKeyframeItem(TimelinePropertyItem *parent, const ModelNode &frame);
~TimelineKeyframeItem() override;
@@ -84,6 +86,8 @@ private:
class TimelinePropertyItem : public TimelineItem
{
+ Q_OBJECT
+
public:
enum { Type = TimelineConstants::timelinePropertyItemUserType };
diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.h b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.h
index 3c34ba3929..26db04f757 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.h
+++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesectionitem.h
@@ -40,6 +40,8 @@ class TimelineSectionItem;
class TimelineBarItem : public TimelineMovableAbstractItem
{
+ Q_DECLARE_TR_FUNCTIONS(TimelineBarItem)
+
enum class Location { Undefined, Center, Left, Right };
public:
diff --git a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp
index 6ce3731222..47426d9755 100644
--- a/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp
+++ b/src/plugins/qmldesigner/qmldesignerextension/timelineeditor/timelinesettingsmodel.cpp
@@ -103,7 +103,7 @@ QWidget *TimelineEditorDelegate::createEditor(QWidget *parent,
switch (index.column()) {
case TimelineSettingsModel::TimelineRow: {
QTC_ASSERT(comboBox, return widget);
- comboBox->addItem(tr("None"));
+ comboBox->addItem(TimelineSettingsModel::tr("None"));
for (const auto &timeline : timelineSettingsModel->timelineView()->getTimelines()) {
if (!timeline.modelNode().id().isEmpty())
comboBox->addItem(timeline.modelNode().id());
@@ -111,7 +111,7 @@ QWidget *TimelineEditorDelegate::createEditor(QWidget *parent,
} break;
case TimelineSettingsModel::AnimationRow: {
QTC_ASSERT(comboBox, return widget);
- comboBox->addItem(tr("None"));
+ comboBox->addItem(TimelineSettingsModel::tr("None"));
for (const auto &animation :
timelineSettingsModel->timelineView()->getAnimations(qmlTimeline)) {
if (!animation.id().isEmpty())
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp
index 09e10c3b0c..84b95cccc3 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.cpp
+++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp
@@ -194,8 +194,7 @@ bool QmlDesignerPlugin::delayedInitialize()
d->settings.fromSettings(Core::ICore::settings());
d->viewManager.registerViewTakingOwnership(new QmlDesigner::Internal::ConnectionView);
- if (DesignerSettings::getValue(DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool()
- || qEnvironmentVariableIsSet(DesignerSettingsKey::ENABLE_TIMELINEVIEW_ENVVAR))
+ if (DesignerSettings::getValue(DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool())
d->viewManager.registerViewTakingOwnership(new QmlDesigner::TimelineView);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::SourceTool);
d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::ColorTool);
diff --git a/src/plugins/qmldesigner/settingspage.cpp b/src/plugins/qmldesigner/settingspage.cpp
index e9bd2d1cb4..a7d6bc2bb0 100644
--- a/src/plugins/qmldesigner/settingspage.cpp
+++ b/src/plugins/qmldesigner/settingspage.cpp
@@ -159,6 +159,8 @@ DesignerSettings SettingsPageWidget::settings() const
m_ui.showPropertyEditorWarningsCheckBox->isChecked());
settings.insert(DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT,
m_ui.showWarnExceptionsCheckBox->isChecked());
+ settings.insert(DesignerSettingsKey::ENABLE_TIMELINEVIEW,
+ m_ui.featureTimelineEditorCheckBox->isChecked());
return settings;
}
@@ -224,9 +226,13 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings)
m_ui.controls2StyleComboBox->setCurrentText(m_ui.styleLineEdit->text());
+ m_ui.featureTimelineEditorCheckBox->setChecked(settings.value(
+ DesignerSettingsKey::ENABLE_TIMELINEVIEW).toBool());
+
if (settings.value(DesignerSettingsKey::STANDALONE_MODE).toBool()) {
m_ui.emulationGroupBox->hide();
m_ui.debugGroupBox->hide();
+ m_ui.featuresGroupBox->hide();
}
}
@@ -262,7 +268,8 @@ void SettingsPage::apply()
<< DesignerSettingsKey::PUPPET_KILL_TIMEOUT
<< DesignerSettingsKey::FORWARD_PUPPET_OUTPUT
<< DesignerSettingsKey::DEBUG_PUPPET
- << DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT;
+ << DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT
+ << DesignerSettingsKey::ENABLE_TIMELINEVIEW;
foreach (const QByteArray &key, restartNecessaryKeys) {
if (currentSettings.value(key) != newSettings.value(key)) {
diff --git a/src/plugins/qmldesigner/settingspage.ui b/src/plugins/qmldesigner/settingspage.ui
index 567f0f7d80..7da62b300a 100644
--- a/src/plugins/qmldesigner/settingspage.ui
+++ b/src/plugins/qmldesigner/settingspage.ui
@@ -411,6 +411,22 @@
</layout>
</item>
<item>
+ <widget class="QGroupBox" name="featuresGroupBox">
+ <property name="title">
+ <string>Features</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QCheckBox" name="featureTimelineEditorCheckBox">
+ <property name="text">
+ <string>Enable Timeline editor</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<widget class="QGroupBox" name="debugGroupBox">
<property name="title">
<string>Debugging</string>
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp
index 1df46d885b..a6e5850076 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -287,10 +287,10 @@ void QmlProfilerTool::updateRunActions()
d->m_startAction->setToolTip(tr("A QML Profiler analysis is still in progress."));
d->m_stopAction->setEnabled(true);
} else {
- QString whyNot = tr("Start QML Profiler analysis.");
+ QString tooltip = tr("Start QML Profiler analysis.");
bool canRun = ProjectExplorerPlugin::canRunStartupProject
- (ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, &whyNot);
- d->m_startAction->setToolTip(whyNot);
+ (ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, &tooltip);
+ d->m_startAction->setToolTip(tooltip);
d->m_startAction->setEnabled(canRun);
d->m_stopAction->setEnabled(false);
}
diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp
index 778d309600..2b7933ea8a 100644
--- a/src/plugins/qtsupport/qtoutputformatter.cpp
+++ b/src/plugins/qtsupport/qtoutputformatter.cpp
@@ -31,6 +31,7 @@
#include <utils/algorithm.h>
#include <utils/ansiescapecodehandler.h>
#include <utils/fileinprojectfinder.h>
+#include <utils/hostosinfo.h>
#include <utils/theme/theme.h>
#include <QPlainTextEdit>
@@ -412,16 +413,16 @@ void QtSupportPlugin::testQtOutputFormatter_data()
<< " Loc: [../TestProject/test.cpp(123)]"
<< 9 << 37 << "../TestProject/test.cpp(123)"
<< "../TestProject/test.cpp" << 123 << -1;
-
- QTest::newRow("Windows failed QTest link")
- << "..\\TestProject\\test.cpp(123) : failure location"
- << 0 << 28 << "..\\TestProject\\test.cpp(123)"
- << "..\\TestProject\\test.cpp" << 123 << -1;
-
- QTest::newRow("Windows failed QTest link with carriage return")
- << "..\\TestProject\\test.cpp(123) : failure location\r"
- << 0 << 28 << "..\\TestProject\\test.cpp(123)"
- << "..\\TestProject\\test.cpp" << 123 << -1;
+ if (HostOsInfo::isWindowsHost()) {
+ QTest::newRow("Windows failed QTest link")
+ << "..\\TestProject\\test.cpp(123) : failure location"
+ << 0 << 28 << "..\\TestProject\\test.cpp(123)"
+ << "../TestProject/test.cpp" << 123 << -1;
+ QTest::newRow("Windows failed QTest link with carriage return")
+ << "..\\TestProject\\test.cpp(123) : failure location\r"
+ << 0 << 28 << "..\\TestProject\\test.cpp(123)"
+ << "../TestProject/test.cpp" << 123 << -1;
+ }
}
void QtSupportPlugin::testQtOutputFormatter()
diff --git a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp
index 728aea666d..f525f777d0 100644
--- a/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp
+++ b/src/plugins/remotelinux/abstractremotelinuxdeployservice.cpp
@@ -203,7 +203,7 @@ void AbstractRemoteLinuxDeployService::handleDeviceSetupDone(bool success)
} else {
connect(d->connection, &SshConnection::connected,
this, &AbstractRemoteLinuxDeployService::handleConnected);
- emit progressMessage(tr("Connecting to device '%1' (%2)")
+ emit progressMessage(tr("Connecting to device \"%1\" (%2).")
.arg(deviceConfiguration()->displayName())
.arg(deviceConfiguration()->sshParameters().host()));
if (d->connection->state() == SshConnection::Unconnected)
diff --git a/src/plugins/texteditor/basehoverhandler.cpp b/src/plugins/texteditor/basehoverhandler.cpp
index 72e35ba5bb..92dae73d59 100644
--- a/src/plugins/texteditor/basehoverhandler.cpp
+++ b/src/plugins/texteditor/basehoverhandler.cpp
@@ -145,7 +145,7 @@ void BaseHoverHandler::decorateToolTip()
if (Qt::mightBeRichText(toolTip()))
setToolTip(toolTip().toHtmlEscaped());
- if (lastHelpItemIdentified().isValid()) {
+ if (lastHelpItemIdentified().isValid() && !lastHelpItemIdentified().isFuzzyMatch()) {
const QString &helpContents = lastHelpItemIdentified().extractContent(false);
if (!helpContents.isEmpty()) {
m_toolTip = toolTip().toHtmlEscaped();
diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp
index 4178dc7195..5b60b885ab 100644
--- a/src/plugins/texteditor/highlighter.cpp
+++ b/src/plugins/texteditor/highlighter.cpp
@@ -258,6 +258,16 @@ void Highlighter::handleShutdown()
delete highlightRepository();
}
+static bool isOpeningParenthesis(QChar c)
+{
+ return c == QLatin1Char('{') || c == QLatin1Char('[') || c == QLatin1Char('(');
+}
+
+static bool isClosingParenthesis(QChar c)
+{
+ return c == QLatin1Char('}') || c == QLatin1Char(']') || c == QLatin1Char(')');
+}
+
void Highlighter::highlightBlock(const QString &text)
{
if (!definition().isValid())
@@ -266,8 +276,21 @@ void Highlighter::highlightBlock(const QString &text)
KSyntaxHighlighting::State state = TextDocumentLayout::userData(block)->syntaxState();
state = highlightLine(text, state);
block = block.next();
+
+ Parentheses parentheses;
+ int pos = 0;
+ for (const QChar &c : text) {
+ if (isOpeningParenthesis(c))
+ parentheses.push_back(Parenthesis(Parenthesis::Opened, c, pos));
+ else if (isClosingParenthesis(c))
+ parentheses.push_back(Parenthesis(Parenthesis::Closed, c, pos));
+ pos++;
+ }
+ TextDocumentLayout::setParentheses(currentBlock(), parentheses);
+
if (block.isValid())
TextDocumentLayout::userData(block)->setSyntaxState(state);
+ formatSpaces(text);
}
void Highlighter::applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format)
diff --git a/src/plugins/texteditor/highlightersettingspage.ui b/src/plugins/texteditor/highlightersettingspage.ui
index fcd4919b12..7b1e6c9e0d 100644
--- a/src/plugins/texteditor/highlightersettingspage.ui
+++ b/src/plugins/texteditor/highlightersettingspage.ui
@@ -127,6 +127,9 @@
</item>
<item>
<widget class="QPushButton" name="resetCache">
+ <property name="toolTip">
+ <string>Reset definitions remembered for files that can be associated with more than one highlighter definition.</string>
+ </property>
<property name="text">
<string>Reset Remembered Definitions</string>
</property>
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index 36abfc01e2..3c4c8cd516 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -8508,13 +8508,14 @@ BaseTextEditor *BaseTextEditor::currentTextEditor()
return qobject_cast<BaseTextEditor *>(EditorManager::currentEditor());
}
-BaseTextEditor *BaseTextEditor::textEditorForDocument(TextDocument *textDocument)
+QVector<BaseTextEditor *> BaseTextEditor::textEditorsForDocument(TextDocument *textDocument)
{
+ QVector<BaseTextEditor *> ret;
for (IEditor *editor : Core::DocumentModel::editorsForDocument(textDocument)) {
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor))
- return textEditor;
+ ret << textEditor;
}
- return nullptr;
+ return ret;
}
TextEditorWidget *BaseTextEditor::editorWidget() const
diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h
index d792a1b12c..3d079bf77f 100644
--- a/src/plugins/texteditor/texteditor.h
+++ b/src/plugins/texteditor/texteditor.h
@@ -111,7 +111,7 @@ public:
virtual void finalizeInitialization() {}
static BaseTextEditor *currentTextEditor();
- static BaseTextEditor *textEditorForDocument(TextDocument *textDocument);
+ static QVector<BaseTextEditor *> textEditorsForDocument(TextDocument *textDocument);
TextEditorWidget *editorWidget() const;
TextDocument *textDocument() const;
diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro
index d5bf895ee4..29231afb82 100644
--- a/src/plugins/texteditor/texteditor.pro
+++ b/src/plugins/texteditor/texteditor.pro
@@ -2,7 +2,19 @@ DEFINES += TEXTEDITOR_LIBRARY
QT += gui-private network printsupport xml
CONFIG += exceptions
CONFIG += include_source_dir # For the highlighter autotest.
+
+include(../../shared/syntax/syntax_shared.pri)
+isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) | isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
+ QTC_LIB_DEPENDS += syntax-highlighting
+} else {
+ unix:!disable_external_rpath {
+ !macos: QMAKE_LFLAGS += -Wl,-z,origin
+ QMAKE_LFLAGS += -Wl,-rpath,$$shell_quote($${KSYNTAXHIGHLIGHTING_LIB_DIR})
+ }
+}
+
include(../../qtcreatorplugin.pri)
+
SOURCES += texteditorplugin.cpp \
plaintexteditorfactory.cpp \
textdocument.cpp \
diff --git a/src/plugins/texteditor/texteditor_dependencies.pri b/src/plugins/texteditor/texteditor_dependencies.pri
index c624e4cfb2..85ccb3ded7 100644
--- a/src/plugins/texteditor/texteditor_dependencies.pri
+++ b/src/plugins/texteditor/texteditor_dependencies.pri
@@ -2,7 +2,21 @@ QTC_PLUGIN_NAME = TextEditor
QTC_LIB_DEPENDS += \
aggregation \
extensionsystem \
- utils \
- syntax-highlighting
+ utils
+
QTC_PLUGIN_DEPENDS += \
coreplugin
+
+# needed for plugins that depend on TextEditor plugin
+include(../../shared/syntax/syntax_shared.pri)
+!isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR):!isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
+ INCLUDEPATH *= $${KSYNTAXHIGHLIGHTING_INCLUDE_DIR}
+ LIBS *= -L$$KSYNTAXHIGHLIGHTING_LIB_DIR -lKF5SyntaxHighlighting
+
+ linux {
+ QMAKE_LFLAGS += -Wl,-z,origin
+ QMAKE_LFLAGS += -Wl,-rpath,$$shell_quote($${KSYNTAXHIGHLIGHTING_LIB_DIR})
+ }
+} else {
+ QTC_LIB_DEPENDS += syntax-highlighting
+}
diff --git a/src/shared/clang/clang_installation.pri b/src/shared/clang/clang_installation.pri
index 6c820dc36d..8c75b6cc82 100644
--- a/src/shared/clang/clang_installation.pri
+++ b/src/shared/clang/clang_installation.pri
@@ -96,7 +96,16 @@ defineReplace(splitFlags) {
flag ~= s,-I\S*,,
flag ~= s,/D\S*,,
flag ~= s,/Z\S*,,
- result += $$split(flag, " ")
+ separate_flags = $$split(flag, " ")
+ for (separate_flag, separate_flags) {
+ starting_substr = $$str_member($$separate_flag, 0, 0)
+ win32:equals(starting_substr, "/") {
+ result += $$separate_flag
+ }
+ equals(starting_substr, "-") {
+ result += $$separate_flag
+ }
+ }
} else {
inside_quotes = 0
starting_substr = $$str_member($$flag, 0, 0)
diff --git a/src/shared/syntax/syntax_shared.pri b/src/shared/syntax/syntax_shared.pri
new file mode 100644
index 0000000000..a10ae45b5c
--- /dev/null
+++ b/src/shared/syntax/syntax_shared.pri
@@ -0,0 +1,21 @@
+# KSyntaxHighlighting uses a special folder structure (may contain target arch triple for the lib),
+# so expect lib folder to be specified by the user - generate include path based on this
+isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR): KSYNTAXHIGHLIGHTING_LIB_DIR=$$(KSYNTAXHIGHLIGHTING_LIB_DIR)
+isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR): KSYNTAXHIGHLIGHTING_INCLUDE_DIR=$$(KSYNTAXHIGHLIGHTING_INCLUDE_DIR)
+
+!isEmpty(KSYNTAXHIGHLIGHTING_LIB_DIR) {
+ !exists($$KSYNTAXHIGHLIGHTING_LIB_DIR) {
+ unset(KSYNTAXHIGHLIGHTING_LIB_DIR)
+ unset(KSYNTAXHIGHLIGHTING_INCLUDE_DIR)
+ } else {
+ isEmpty(KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
+ !linux: KSYNTAXHIGHLIGHTING_INCLUDE_DIR=$$absolute_path('../include/KF5/KSyntaxHighlighting/', $$KSYNTAXHIGHLIGHTING_LIB_DIR)
+ else: KSYNTAXHIGHLIGHTING_INCLUDE_DIR=$$absolute_path('../../include/KF5/KSyntaxHighlighting/', $$KSYNTAXHIGHLIGHTING_LIB_DIR)
+ }
+
+ !exists($$KSYNTAXHIGHLIGHTING_INCLUDE_DIR) {
+ unset(KSYNTAXHIGHLIGHTING_INCLUDE_DIR)
+ unset(KSYNTAXHIGHLIGHTING_LIB_DIR)
+ }
+ }
+}
diff --git a/src/tools/clangbackend/source/fulltokeninfo.cpp b/src/tools/clangbackend/source/fulltokeninfo.cpp
index eb57abbbe6..fd59d25766 100644
--- a/src/tools/clangbackend/source/fulltokeninfo.cpp
+++ b/src/tools/clangbackend/source/fulltokeninfo.cpp
@@ -181,6 +181,7 @@ void FullTokenInfo::variableKind(const Cursor &cursor)
{
TokenInfo::variableKind(cursor);
+ m_extraInfo.accessSpecifier = cursor.accessSpecifier();
m_extraInfo.storageClass = cursor.storageClass();
}
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
index 89567b8d38..3237aab2fb 100644
--- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
@@ -41,7 +41,7 @@
#include <precompiledheaderstorage.h>
#include <processormanager.h>
#include <progresscounter.h>
-#include <projectparts.h>
+#include <projectpartsmanager.h>
#include <filepathcaching.h>
#include <refactoringdatabaseinitializer.h>
#include <sqlitedatabase.h>
@@ -68,7 +68,7 @@ using ClangBackEnd::PchCreator;
using ClangBackEnd::PchManagerClientProxy;
using ClangBackEnd::PchManagerServer;
using ClangBackEnd::PrecompiledHeaderStorage;
-using ClangBackEnd::ProjectParts;
+using ClangBackEnd::ProjectPartsManager;
using ClangBackEnd::FilePathCache;
using ClangBackEnd::FilePathView;
using ClangBackEnd::TimeStamp;
@@ -138,12 +138,14 @@ public:
ClangBackEnd::Environment &environment,
Sqlite::Database &database,
PchManagerServer &pchManagerServer,
- ClangBackEnd::ClangPathWatcherInterface &pathWatcher)
- : ProcessorManager(generatedFiles),
- m_environment(environment),
- m_database(database),
- m_pchManagerServer(pchManagerServer),
- m_pathWatcher(pathWatcher)
+ ClangBackEnd::ClangPathWatcherInterface &pathWatcher,
+ ClangBackEnd::BuildDependenciesStorageInterface &buildDependenciesStorage)
+ : ProcessorManager(generatedFiles)
+ , m_environment(environment)
+ , m_database(database)
+ , m_pchManagerServer(pchManagerServer)
+ , m_pathWatcher(pathWatcher)
+ , m_buildDependenciesStorage(buildDependenciesStorage)
{}
protected:
@@ -152,7 +154,8 @@ protected:
return std::make_unique<PchCreator>(m_environment,
m_database,
*m_pchManagerServer.client(),
- m_pathWatcher);
+ m_pathWatcher,
+ m_buildDependenciesStorage);
}
private:
@@ -160,6 +163,7 @@ private:
Sqlite::Database &m_database;
ClangBackEnd::PchManagerServer &m_pchManagerServer;
ClangBackEnd::ClangPathWatcherInterface &m_pathWatcher;
+ ClangBackEnd::BuildDependenciesStorageInterface &m_buildDependenciesStorage;
};
struct Data // because we have a cycle dependency
@@ -175,13 +179,14 @@ struct Data // because we have a cycle dependency
ClangBackEnd::FilePathCaching filePathCache{database};
ClangPathWatcher<QFileSystemWatcher, QTimer> includeWatcher{filePathCache};
ApplicationEnvironment environment;
- ProjectParts projectParts;
+ ProjectPartsManager projectParts;
GeneratedFiles generatedFiles;
PchCreatorManager pchCreatorManager{generatedFiles,
environment,
database,
clangPchManagerServer,
- includeWatcher};
+ includeWatcher,
+ buildDependencyStorage};
PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
ClangBackEnd::ProgressCounter pchCreationProgressCounter{[&](int progress, int total) {
executeInLoop([&] {
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
index d58da0f27c..a2a7a813ac 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
@@ -55,19 +55,19 @@ OutputContainer setUnion(InputContainer1 &&input1,
BuildDependency BuildDependenciesProvider::create(const ProjectPartContainer &projectPart)
{
- SourceEntries includes = createSourceEntriesFromStorage(projectPart.sourcePathIds,
- projectPart.projectPartId);
+ auto sourcesAndProjectPart = createSourceEntriesFromStorage(
+ projectPart.sourcePathIds, projectPart.projectPartId);
- if (!m_modifiedTimeChecker.isUpToDate(includes)) {
+ if (!m_modifiedTimeChecker.isUpToDate(sourcesAndProjectPart.first)) {
BuildDependency buildDependency = m_generator.create(projectPart);
- storeBuildDependency(buildDependency);
+ storeBuildDependency(buildDependency, sourcesAndProjectPart.second);
return buildDependency;
}
- return createBuildDependencyFromStorage(std::move(includes));
-
+ return createBuildDependencyFromStorage(
+ std::move(sourcesAndProjectPart.first));
}
BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(
@@ -76,7 +76,7 @@ BuildDependency BuildDependenciesProvider::createBuildDependencyFromStorage(
BuildDependency buildDependency;
buildDependency.usedMacros = createUsedMacrosFromStorage(includes);
- buildDependency.includes = std::move(includes);
+ buildDependency.sources = std::move(includes);
return buildDependency;
}
@@ -101,16 +101,19 @@ UsedMacros BuildDependenciesProvider::createUsedMacrosFromStorage(const SourceEn
return usedMacros;
}
-SourceEntries BuildDependenciesProvider::createSourceEntriesFromStorage(
- const FilePathIds &sourcePathIds, Utils::SmallStringView projectPartId) const
-{
+std::pair<SourceEntries, int>
+BuildDependenciesProvider::createSourceEntriesFromStorage(
+ const FilePathIds &sourcePathIds,
+ Utils::SmallStringView projectPartName) const {
SourceEntries includes;
Sqlite::DeferredTransaction transaction(m_transactionBackend);
+ int projectPartId = m_storage.fetchProjectPartId(projectPartName);
+
for (FilePathId sourcePathId : sourcePathIds) {
- SourceEntries entries = m_storage.fetchDependSources(sourcePathId,
- projectPartId);
+ SourceEntries entries =
+ m_storage.fetchDependSources(sourcePathId, projectPartId);
SourceEntries mergedEntries = setUnion<SourceEntries>(includes, entries);
includes = std::move(mergedEntries);
@@ -118,15 +121,14 @@ SourceEntries BuildDependenciesProvider::createSourceEntriesFromStorage(
transaction.commit();
- return includes;
+ return {includes, projectPartId};
}
-void BuildDependenciesProvider::storeBuildDependency(const BuildDependency &buildDependency)
-{
+void BuildDependenciesProvider::storeBuildDependency(
+ const BuildDependency &buildDependency, int projectPartId) {
Sqlite::ImmediateTransaction transaction(m_transactionBackend);
-
- m_storage.updateSources(buildDependency.includes);
- m_storage.insertFileStatuses(buildDependency.fileStatuses);
+ m_storage.insertOrUpdateSources(buildDependency.sources, projectPartId);
+ m_storage.insertOrUpdateFileStatuses(buildDependency.fileStatuses);
m_storage.insertOrUpdateSourceDependencies(buildDependency.sourceDependencies);
m_storage.insertOrUpdateUsedMacros(buildDependency.usedMacros);
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
index 4a89ace732..2eb5210518 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
@@ -55,9 +55,9 @@ public:
private:
BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const;
UsedMacros createUsedMacrosFromStorage(const SourceEntries &includes) const;
- SourceEntries createSourceEntriesFromStorage(const FilePathIds &sourcePathIds,
- Utils::SmallStringView projectPartId) const;
- void storeBuildDependency(const BuildDependency &buildDependency);
+ std::pair<SourceEntries, int> createSourceEntriesFromStorage(
+ const FilePathIds &sourcePathIds, Utils::SmallStringView projectPartName) const;
+ void storeBuildDependency(const BuildDependency &buildDependency, int projectPartId);
private:
BuildDependenciesStorageInterface &m_storage;
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
index 324552bf99..3e6d00da3f 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h
@@ -53,25 +53,28 @@ public:
transaction.commit();
}
- void updateSources(const SourceEntries &sourceEntries) override
+ void insertOrUpdateSources(const SourceEntries &sourceEntries, int projectPartId) override
{
+ deleteAllProjectPartsSourcesWithProjectPartNameStatement.write(
+ projectPartId);
+
for (const SourceEntry &entry : sourceEntries) {
- updateBuildDependencyTimeStampStatement.write(static_cast<long long>(entry.lastModified),
- entry.sourceId.filePathId);
- updateSourceTypeStatement.write(static_cast<uchar>(entry.sourceType),
- entry.sourceId.filePathId);
+ insertOrUpdateProjectPartsSourcesStatement.write(
+ entry.sourceId.filePathId,
+ projectPartId,
+ static_cast<uchar>(entry.sourceType),
+ static_cast<uchar>(entry.hasMissingIncludes));
}
}
- void insertFileStatuses(const FileStatuses &fileStatuses) override
+ void insertOrUpdateFileStatuses(const FileStatuses &fileStatuses) override
{
- WriteStatement &statement = insertFileStatusesStatement;
+ WriteStatement &statement = insertOrUpdateFileStatusesStatement;
for (const FileStatus &fileStatus : fileStatuses)
statement.write(fileStatus.filePathId.filePathId,
fileStatus.size,
- fileStatus.lastModified,
- fileStatus.isInPrecompiledHeader);
+ fileStatus.lastModified);
}
long long fetchLowestLastModifiedTime(FilePathId sourceId) const override
@@ -85,7 +88,8 @@ public:
{
WriteStatement &insertStatement = insertIntoNewUsedMacrosStatement;
for (const UsedMacro &usedMacro : usedMacros)
- insertStatement.write(usedMacro.filePathId.filePathId, usedMacro.macroName);
+ insertStatement.write(usedMacro.filePathId.filePathId,
+ usedMacro.macroName);
syncNewUsedMacrosStatement.execute();
deleteOutdatedUsedMacrosStatement.execute();
@@ -104,18 +108,22 @@ public:
deleteNewSourceDependenciesStatement.execute();
}
- SourceEntries fetchDependSources(FilePathId sourceId,
- Utils::SmallStringView projectPartName) const override
+ int fetchProjectPartId(Utils::SmallStringView projectPartName) override
{
auto projectPartId = fetchProjectPartIdStatement.template value<int>(projectPartName);
- if (projectPartId) {
- return fetchSourceDependenciesStatement.template values<SourceEntry, 3>(
- 300,
- sourceId.filePathId,
- projectPartId.value());
- }
- return {};
+ if (projectPartId)
+ return projectPartId.value();
+
+ insertProjectPartNameStatement.write(projectPartName);
+
+ return static_cast<int>(database.lastInsertedRowId());
+ }
+
+ SourceEntries fetchDependSources(FilePathId sourceId, int projectPartId) const override
+ {
+ return fetchSourceDependenciesStatement.template values<SourceEntry, 4>(
+ 300, sourceId.filePathId, projectPartId);
}
UsedMacros fetchUsedMacros(FilePathId sourceId) const override
@@ -123,6 +131,17 @@ public:
return fetchUsedMacrosStatement.template values<UsedMacro, 2>(128, sourceId.filePathId);
}
+ void updatePchCreationTimeStamp(
+ long long pchCreationTimeStamp,
+ Utils::SmallStringView projectPartName) override {
+ Sqlite::ImmediateTransaction transaction{database};
+
+ updatePchCreationTimeStampStatement.write(pchCreationTimeStamp,
+ projectPartName);
+
+ transaction.commit();
+ }
+
static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
{
QJsonDocument document;
@@ -207,10 +226,11 @@ public:
"INSERT INTO newSourceDependencies(sourceId, dependencySourceId) VALUES (?,?)",
database
};
- WriteStatement insertFileStatusesStatement{
- "INSERT OR REPLACE INTO fileStatuses(sourceId, size, lastModified, isInPrecompiledHeader) VALUES (?,?,?,?)",
- database
- };
+ WriteStatement insertOrUpdateFileStatusesStatement{
+ "INSERT INTO fileStatuses(sourceId, size, lastModified) VALUES "
+ "(?001,?002,?003) ON "
+ "CONFLICT(sourceId) DO UPDATE SET size = ?002, lastModified = ?003",
+ database};
WriteStatement syncNewSourceDependenciesStatement{
"INSERT INTO sourceDependencies(sourceId, dependencySourceId) SELECT sourceId, dependencySourceId FROM newSourceDependencies WHERE NOT EXISTS (SELECT sourceId FROM sourceDependencies WHERE sourceDependencies.sourceId == newSourceDependencies.sourceId AND sourceDependencies.dependencySourceId == newSourceDependencies.dependencySourceId)",
database
@@ -223,25 +243,37 @@ public:
"DELETE FROM newSourceDependencies",
database
};
- WriteStatement updateBuildDependencyTimeStampStatement{
- "UPDATE fileStatuses SET buildDependencyTimeStamp = ? WHERE sourceId == ?",
- database
- };
- WriteStatement updateSourceTypeStatement{
- "UPDATE projectPartsSources SET sourceType = ? WHERE sourceId == ?",
- database
- };
+ WriteStatement insertOrUpdateProjectPartsSourcesStatement{
+ "INSERT INTO projectPartsSources(sourceId, projectPartId, "
+ "sourceType, hasMissingIncludes) VALUES (?001, ?002, ?003, ?004) ON "
+ "CONFLICT(sourceId, projectPartId) DO UPDATE SET sourceType = ?003, "
+ "hasMissingIncludes = ?004",
+ database};
mutable ReadStatement fetchSourceDependenciesStatement{
- "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, collectedDependencies WHERE sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT sourceId, buildDependencyTimeStamp, sourceType FROM collectedDependencies NATURAL JOIN projectPartsSources NATURAL JOIN fileStatuses WHERE projectPartId = ? ORDER BY sourceId",
- database
- };
+ "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION "
+ "SELECT dependencySourceId FROM sourceDependencies, "
+ "collectedDependencies WHERE sourceDependencies.sourceId == "
+ "collectedDependencies.sourceId) SELECT sourceId, "
+ "pchCreationTimeStamp, sourceType, hasMissingIncludes FROM "
+ "collectedDependencies NATURAL JOIN projectPartsSources WHERE "
+ "projectPartId = ? ORDER BY sourceId",
+ database};
mutable ReadStatement fetchProjectPartIdStatement{
"SELECT projectPartId FROM projectParts WHERE projectPartName = ?",
database
};
+ WriteStatement insertProjectPartNameStatement{
+ "INSERT INTO projectParts(projectPartName) VALUES (?)", database};
mutable ReadStatement fetchUsedMacrosStatement{
"SELECT macroName, sourceId FROM usedMacros WHERE sourceId = ? ORDER BY sourceId, macroName",
database
};
+ WriteStatement updatePchCreationTimeStampStatement{
+ "UPDATE projectPartsSources SET pchCreationTimeStamp = ?001 WHERE "
+ "projectPartId = (SELECT "
+ "projectPartId FROM projectParts WHERE projectPartName = ?002)",
+ database};
+ WriteStatement deleteAllProjectPartsSourcesWithProjectPartNameStatement{
+ "DELETE FROM projectPartsSources WHERE projectPartId = ?", database};
};
}
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
index 445afa052f..4edc47fce1 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h
@@ -33,6 +33,8 @@
#include <sourcedependency.h>
#include <usedmacro.h>
+#include <utils/optional.h>
+
namespace ClangBackEnd {
class BuildDependenciesStorageInterface
@@ -42,13 +44,20 @@ public:
BuildDependenciesStorageInterface(const BuildDependenciesStorageInterface &) = delete;
BuildDependenciesStorageInterface &operator=(const BuildDependenciesStorageInterface &) = delete;
- virtual void updateSources(const SourceEntries &sourceIds) = 0;
+ virtual void insertOrUpdateSources(const SourceEntries &sourceIds,
+ int projectPartId) = 0;
virtual void insertOrUpdateUsedMacros(const UsedMacros &usedMacros) = 0;
- virtual void insertFileStatuses(const FileStatuses &fileStatuses) = 0;
+ virtual void
+ insertOrUpdateFileStatuses(const FileStatuses &fileStatuses) = 0;
virtual void insertOrUpdateSourceDependencies(const SourceDependencies &sourceDependencies) = 0;
virtual long long fetchLowestLastModifiedTime(FilePathId sourceId) const = 0;
- virtual SourceEntries fetchDependSources(FilePathId sourceId, Utils::SmallStringView projectPartId) const = 0;
+ virtual SourceEntries fetchDependSources(FilePathId sourceId,
+ int projectPartId) const = 0;
virtual UsedMacros fetchUsedMacros(FilePathId sourceId) const = 0;
+ virtual int fetchProjectPartId(Utils::SmallStringView projectPartName) = 0;
+ virtual void updatePchCreationTimeStamp(long long pchCreationTimeStamp,
+ Utils::SmallStringView projectPartName)
+ = 0;
protected:
~BuildDependenciesStorageInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/builddependency.h b/src/tools/clangpchmanagerbackend/source/builddependency.h
index 1b649e3118..6725254e30 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependency.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependency.h
@@ -37,7 +37,7 @@ class BuildDependency
public:
void clear()
{
- includes.clear();
+ sources.clear();
usedMacros.clear();
sourceFiles.clear();
fileStatuses.clear();
@@ -46,14 +46,15 @@ public:
friend bool operator==(const BuildDependency &first, const BuildDependency &second)
{
- return first.includes == second.includes && first.usedMacros == second.usedMacros
- && first.sourceFiles == second.sourceFiles
- && first.sourceDependencies == second.sourceDependencies
- && first.fileStatuses == second.fileStatuses;
+ return first.sources == second.sources &&
+ first.usedMacros == second.usedMacros &&
+ first.sourceFiles == second.sourceFiles &&
+ first.sourceDependencies == second.sourceDependencies &&
+ first.fileStatuses == second.fileStatuses;
}
public:
- SourceEntries includes;
+ SourceEntries sources;
UsedMacros usedMacros;
FilePathIds sourceFiles;
SourceDependencies sourceDependencies;
diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp
index b3ebbc75ad..1d08442c51 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp
+++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp
@@ -45,8 +45,27 @@ FilePathIds operator+(const FilePathIds &first, const FilePathIds &second)
return result;
}
+
+FilePaths operator+(FilePaths &&first, FilePaths &&second) {
+ FilePaths result = std::move(first);
+
+ std::copy(second.begin(), second.end(), std::back_inserter(result));
+
+ return result;
}
+FilePaths generatedFilePaths(const V2::FileContainers &containers) {
+ FilePaths paths;
+ paths.reserve(containers.size());
+ std::transform(containers.begin(),
+ containers.end(),
+ std::back_inserter(paths),
+ [](const auto &container) { return container.filePath; });
+ return paths;
+}
+
+} // namespace
+
BuildDependency BuildDependencyCollector::create(const ProjectPartContainer &projectPart)
{
CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector>
@@ -54,8 +73,9 @@ BuildDependency BuildDependencyCollector::create(const ProjectPartContainer &pro
addFiles(projectPart.sourcePathIds, std::move(builder.commandLine));
- setExcludedFilePaths(
- m_filePathCache.filePaths(projectPart.headerPathIds + projectPart.sourcePathIds));
+ setExcludedFilePaths(m_filePathCache.filePaths(projectPart.headerPathIds +
+ projectPart.sourcePathIds) +
+ generatedFilePaths(m_generatedFiles.fileContainers()));
addUnsavedFiles(m_generatedFiles.fileContainers());
diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.h b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h
index c5e41e9190..f8aaa8f07c 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependencycollector.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h
@@ -83,11 +83,11 @@ public:
return m_buildDependency.sourceDependencies;
}
- const SourceEntries &includeIds()
- {
- std::sort(m_buildDependency.includes.begin(), m_buildDependency.includes.end());
+ const SourceEntries &sourceEntries() {
+ std::sort(m_buildDependency.sources.begin(),
+ m_buildDependency.sources.end());
- return std::move(m_buildDependency.includes);
+ return std::move(m_buildDependency.sources);
}
private:
diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
index 94d9540bea..61bcedc262 100644
--- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
+++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
@@ -3,20 +3,19 @@ INCLUDEPATH += $$PWD
SOURCES += \
$$PWD/builddependenciesprovider.cpp \
$$PWD/pchmanagerserver.cpp \
- $$PWD/projectparts.cpp \
$$PWD/pchtaskgenerator.cpp \
$$PWD/pchtasksmerger.cpp \
- $$PWD/pchtaskqueue.cpp
+ $$PWD/pchtaskqueue.cpp \
+ $$PWD/projectpartsmanager.cpp
HEADERS += \
- $$PWD/pchcreatorincludes.h \
$$PWD/pchmanagerserver.h \
$$PWD/clangpchmanagerbackend_global.h \
$$PWD/pchnotcreatederror.h \
$$PWD/environment.h \
- $$PWD/projectparts.h \
$$PWD/pchcreatorinterface.h \
- $$PWD/projectpartsinterface.h \
+ $$PWD/projectpartsmanager.h \
+ $$PWD/projectpartsmanagerinterface.h \
$$PWD/queueinterface.h \
$$PWD/processormanagerinterface.h \
$$PWD/processorinterface.h \
diff --git a/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h
index 980d065fdb..f3b365d8d5 100644
--- a/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h
+++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h
@@ -109,36 +109,46 @@ public:
clang::SrcMgr::CharacteristicKind fileType) override
{
clang::FileID currentFileId = m_sourceManager->getFileID(hashLocation);
- if (file && currentFileId != m_mainFileId) {
- addSourceDependency(file, hashLocation);
- auto fileUID = file->getUID();
- auto sourceFileUID = m_sourceManager
- ->getFileEntryForID(m_sourceManager->getFileID(hashLocation))
- ->getUID();
- auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID);
- if (notAlreadyIncluded.first) {
- m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
- FilePath filePath = filePathFromFile(file);
- if (!filePath.empty()) {
- FilePathId includeId = m_filePathCache.filePathId(filePath);
-
- time_t lastModified = file->getModificationTime();
-
- SourceType sourceType = SourceType::UserInclude;
- if (isSystem(fileType)) {
- if (isInSystemHeader(hashLocation))
- sourceType = SourceType::SystemInclude;
- else
- sourceType = SourceType::TopSystemInclude;
- } else if (isNotInExcludedIncludeUID(fileUID)) {
- if (isInExcludedIncludeUID(sourceFileUID))
- sourceType = SourceType::TopProjectInclude;
- else
- sourceType = SourceType::ProjectInclude;
+ if (file) {
+ if (currentFileId != m_mainFileId) {
+ addSourceDependency(file, hashLocation);
+ auto fileUID = file->getUID();
+ auto sourceFileUID =
+ m_sourceManager
+ ->getFileEntryForID(
+ m_sourceManager->getFileID(hashLocation))
+ ->getUID();
+ auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID);
+ if (notAlreadyIncluded.first) {
+ m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second,
+ fileUID);
+ FilePath filePath = filePathFromFile(file);
+ if (!filePath.empty()) {
+ FilePathId includeId =
+ m_filePathCache.filePathId(filePath);
+
+ time_t lastModified = file->getModificationTime();
+
+ SourceType sourceType = SourceType::UserInclude;
+ if (isSystem(fileType)) {
+ if (isInSystemHeader(hashLocation))
+ sourceType = SourceType::SystemInclude;
+ else
+ sourceType = SourceType::TopSystemInclude;
+ } else if (isNotInExcludedIncludeUID(fileUID)) {
+ if (isInExcludedIncludeUID(sourceFileUID))
+ sourceType = SourceType::TopProjectInclude;
+ else
+ sourceType = SourceType::ProjectInclude;
+ }
+
+ addSource({includeId, sourceType, lastModified});
}
-
- addInclude({includeId, sourceType, lastModified});
}
+ } else {
+ addSource({m_filePathCache.filePathId(filePathFromFile(file)),
+ SourceType::Source,
+ file->getModificationTime()});
}
} else {
auto sourceFileId = filePathId(hashLocation);
@@ -194,10 +204,10 @@ public:
void appendContainsMissingIncludes(const FilePathIds &dependentSourceFilesWithMissingIncludes)
{
- auto split = m_containsMissingIncludes
- .insert(m_containsMissingIncludes.end(),
- dependentSourceFilesWithMissingIncludes.begin(),
- dependentSourceFilesWithMissingIncludes.end());
+ auto split = m_containsMissingIncludes.insert(
+ m_containsMissingIncludes.end(),
+ dependentSourceFilesWithMissingIncludes.begin(),
+ dependentSourceFilesWithMissingIncludes.end());
std::inplace_merge(m_containsMissingIncludes.begin(),
split,
m_containsMissingIncludes.end());
@@ -207,11 +217,13 @@ public:
{
FilePathIds filteredDependentSourceFilesWithMissingIncludes;
filteredDependentSourceFilesWithMissingIncludes.reserve(dependentSourceFilesWithMissingIncludes.size());
- std::set_difference(dependentSourceFilesWithMissingIncludes.begin(),
- dependentSourceFilesWithMissingIncludes.end(),
- m_containsMissingIncludes.begin(),
- m_containsMissingIncludes.end(),
- std::back_inserter(filteredDependentSourceFilesWithMissingIncludes));
+ std::set_difference(
+ dependentSourceFilesWithMissingIncludes.begin(),
+ dependentSourceFilesWithMissingIncludes.end(),
+ m_containsMissingIncludes.begin(),
+ m_containsMissingIncludes.end(),
+ std::back_inserter(
+ filteredDependentSourceFilesWithMissingIncludes));
dependentSourceFilesWithMissingIncludes = filteredDependentSourceFilesWithMissingIncludes;
}
@@ -255,8 +267,7 @@ public:
sourceDependencies);
}
- void removeSourceWithMissingIncludesFromIncludes()
- {
+ void removeSourceWithMissingIncludesFromSources() {
class Compare
{
public:
@@ -270,17 +281,16 @@ public:
}
};
- auto &includes = m_buildDependency.includes;
- SourceEntries newIncludes;
- newIncludes.reserve(includes.size());
- std::set_difference(includes.begin(),
- includes.end(),
- m_containsMissingIncludes.begin(),
- m_containsMissingIncludes.end(),
- std::back_inserter(newIncludes),
- Compare{});
-
- m_buildDependency.includes = newIncludes;
+ SourceEntryReferences sourcesWithMissingIncludes;
+ sourcesWithMissingIncludes.reserve(m_containsMissingIncludes.size());
+ std::set_intersection(m_buildDependency.sources.begin(),
+ m_buildDependency.sources.end(),
+ m_containsMissingIncludes.begin(),
+ m_containsMissingIncludes.end(),
+ std::back_inserter(sourcesWithMissingIncludes),
+ Compare{});
+ for (SourceEntryReference entry : sourcesWithMissingIncludes)
+ entry.get().hasMissingIncludes = HasMissingIncludes::Yes;
}
SourceDependencies sourceDependenciesSortedByDependendFilePathId() const
@@ -296,12 +306,12 @@ public:
void filterOutIncludesWithMissingIncludes()
{
- sortAndMakeUnique(m_containsMissingIncludes);;
+ sortAndMakeUnique(m_containsMissingIncludes);
collectSourceWithMissingIncludes(m_containsMissingIncludes,
sourceDependenciesSortedByDependendFilePathId());
- removeSourceWithMissingIncludesFromIncludes();
+ removeSourceWithMissingIncludesFromSources();
}
void ensureDirectory(const QString &directory, const QString &fileName)
@@ -339,16 +349,16 @@ public:
return FilePath::fromNativeFilePath(absolutePath(file->getName()));
}
- void addInclude(SourceEntry sourceEntry)
- {
- auto &includes = m_buildDependency.includes;
- auto found = std::lower_bound(includes.begin(),
- includes.end(),
- sourceEntry,
- [](auto first, auto second) { return first < second; });
-
- if (found == includes.end() || *found != sourceEntry)
- includes.emplace(found, sourceEntry);
+ void addSource(SourceEntry sourceEntry) {
+ auto &sources = m_buildDependency.sources;
+ auto found = std::lower_bound(
+ sources.begin(),
+ sources.end(),
+ sourceEntry,
+ [](auto first, auto second) { return first < second; });
+
+ if (found == sources.end() || *found != sourceEntry)
+ sources.emplace(found, sourceEntry);
}
private:
diff --git a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h
index 90108bd76b..b8ea406df0 100644
--- a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h
+++ b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h
@@ -92,8 +92,7 @@ public:
m_fileStatuses.emplace(found,
id,
fileEntry->getSize(),
- fileEntry->getModificationTime(),
- fileEntry->isInPCH());
+ fileEntry->getModificationTime());
}
}
diff --git a/src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h b/src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h
index 88d5f140d5..d641de054c 100644
--- a/src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h
+++ b/src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h
@@ -75,21 +75,68 @@ public:
private:
bool compareEntries(const SourceEntries &sourceEntries) const
{
+ class CompareSourceId
+ {
+ public:
+ bool operator()(SourceTimeStamp first, SourceTimeStamp second) {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(SourceEntry first, SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(SourceTimeStamp first, SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(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));
-
- return std::equal(currentSourceTimeStamp.begin(),
- currentSourceTimeStamp.end(),
- sourceEntries.begin(),
- sourceEntries.end(),
- [](SourceTimeStamp first, SourceTimeStamp second) {
- return first.lastModified <= second.lastModified;
- });
+ std::back_inserter(currentSourceTimeStamp),
+ CompareSourceId{});
+
+ class CompareTime
+ {
+ public:
+ bool operator()(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.lastModified <= second.lastModified;
+ }
+
+ bool operator()(SourceEntry first, SourceEntry second)
+ {
+ return first.pchCreationTimeStamp <=
+ second.pchCreationTimeStamp;
+ }
+
+ bool operator()(SourceTimeStamp first, SourceEntry second)
+ {
+ return first.lastModified <= second.pchCreationTimeStamp;
+ }
+
+ bool operator()(SourceEntry first, SourceTimeStamp second)
+ {
+ return first.pchCreationTimeStamp <= second.lastModified;
+ }
+ };
+
+ return std::lexicographical_compare(currentSourceTimeStamp.begin(),
+ currentSourceTimeStamp.end(),
+ sourceEntries.begin(),
+ sourceEntries.end(),
+ CompareTime{});
}
void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const
@@ -102,8 +149,8 @@ private:
}
auto split = sourceTimeStamps.insert(sourceTimeStamps.end(),
- m_currentSourceTimeStamps.begin(),
- m_currentSourceTimeStamps.end());
+ m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end());
std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end());
m_currentSourceTimeStamps = sourceTimeStamps;
@@ -111,14 +158,49 @@ private:
SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const
{
- SourceTimeStamps newTimeStamps;
- newTimeStamps.reserve(sourceEntries.size() + m_currentSourceTimeStamps.size());
+ SourceEntries newSourceEntries;
+ newSourceEntries.reserve(sourceEntries.size());
+
+ class CompareSourceId
+ {
+ public:
+ bool operator()(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(SourceEntry first, SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(SourceTimeStamp first, SourceEntry second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ bool operator()(SourceEntry first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+ };
std::set_difference(sourceEntries.begin(),
sourceEntries.end(),
m_currentSourceTimeStamps.begin(),
m_currentSourceTimeStamps.end(),
- std::back_inserter(newTimeStamps));
+ std::back_inserter(newSourceEntries),
+ CompareSourceId{});
+
+ SourceTimeStamps newTimeStamps;
+ newTimeStamps.reserve(newSourceEntries.size());
+
+ std::transform(newSourceEntries.begin(),
+ newSourceEntries.end(),
+ std::back_inserter(newTimeStamps),
+ [](SourceEntry entry) {
+ return SourceTimeStamp{entry.sourceId, {}};
+ });
return newTimeStamps;
}
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
index b8227ce964..3f858b50ee 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
@@ -31,6 +31,7 @@
#include "generatepchactionfactory.h"
#include "pchnotcreatederror.h"
+#include <builddependenciesstorageinterface.h>
#include <clangpathwatcherinterface.h>
#include <filepathcachinginterface.h>
#include <generatedfiles.h>
@@ -110,7 +111,7 @@ Utils::SmallStringVector PchCreator::generateClangCompilerArguments(const PchTas
void PchCreator::generatePch(PchTask &&pchTask)
{
- long long lastModified = QDateTime::currentSecsSinceEpoch();
+ m_projectPartPch.lastModified = QDateTime::currentSecsSinceEpoch();
auto content = generatePchIncludeFileContent(pchTask.includes);
auto pchOutputPath = generatePchFilePath();
@@ -123,9 +124,8 @@ void PchCreator::generatePch(PchTask &&pchTask)
m_projectPartPch.projectPartId = pchTask.projectPartId();
if (success) {
- m_allInclues = pchTask.allIncludes;
+ m_sources = pchTask.sources;
m_projectPartPch.pchPath = std::move(pchOutputPath);
- m_projectPartPch.lastModified = lastModified;
}
}
@@ -163,18 +163,21 @@ void PchCreator::clear()
{
m_clangTool = ClangTool{};
m_projectPartPch = {};
+ m_sources.clear();
}
void PchCreator::doInMainThreadAfterFinished()
{
- FilePathIds existingIncludes;
- existingIncludes.reserve(m_allInclues.size());
- std::set_difference(m_allInclues.begin(),
- m_allInclues.end(),
+ FilePathIds existingSources;
+ existingSources.reserve(m_sources.size());
+ std::set_difference(m_sources.begin(),
+ m_sources.end(),
m_generatedFilePathIds.begin(),
m_generatedFilePathIds.end(),
- std::back_inserter(existingIncludes));
- m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingIncludes}});
+ std::back_inserter(existingSources));
+ m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified,
+ m_projectPartPch.projectPartId);
+ m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingSources}});
m_pchManagerClient.precompiledHeadersUpdated(ProjectPartPchs{m_projectPartPch});
}
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h
index 73f185176d..f1fadcd33a 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.h
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h
@@ -27,7 +27,6 @@
#include "pchcreatorinterface.h"
-#include "pchcreatorincludes.h"
#include "idpaths.h"
#include "sourceentry.h"
#include "clangtool.h"
@@ -49,6 +48,7 @@ class Environment;
class GeneratedFiles;
class PchManagerClientInterface;
class ClangPathWatcherInterface;
+class BuildDependenciesStorageInterface;
class PchCreator final : public PchCreatorInterface
{
@@ -56,12 +56,12 @@ public:
PchCreator(Environment &environment,
Sqlite::Database &database,
PchManagerClientInterface &pchManagerClient,
- ClangPathWatcherInterface &clangPathwatcher)
- : m_filePathCache(database)
- , m_environment(environment)
- , m_pchManagerClient(pchManagerClient)
- , m_clangPathwatcher(clangPathwatcher)
- {}
+ ClangPathWatcherInterface &clangPathwatcher,
+ BuildDependenciesStorageInterface &buildDependenciesStorage)
+ : m_filePathCache(database), m_environment(environment),
+ m_pchManagerClient(pchManagerClient),
+ m_clangPathwatcher(clangPathwatcher),
+ m_buildDependenciesStorage(buildDependenciesStorage) {}
void generatePch(PchTask &&pchTask) override;
const ProjectPartPch &projectPartPch() override;
@@ -85,16 +85,19 @@ public:
return m_clangTool;
}
+ const FilePathIds &sources() const { return m_sources; }
+
private:
mutable std::mt19937_64 randomNumberGenator{std::random_device{}()};
ClangTool m_clangTool;
ProjectPartPch m_projectPartPch;
FilePathCaching m_filePathCache;
- FilePathIds m_allInclues;
+ FilePathIds m_sources;
FilePathIds m_generatedFilePathIds;
Environment &m_environment;
PchManagerClientInterface &m_pchManagerClient;
ClangPathWatcherInterface &m_clangPathwatcher;
+ BuildDependenciesStorageInterface &m_buildDependenciesStorage;
bool m_isUsed = false;
};
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreatorincludes.h b/src/tools/clangpchmanagerbackend/source/pchcreatorincludes.h
deleted file mode 100644
index 6854c59907..0000000000
--- a/src/tools/clangpchmanagerbackend/source/pchcreatorincludes.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include <filepathid.h>
-
-namespace ClangBackEnd {
-
-class PchCreatorIncludes
-{
-public:
- FilePathIds includeIds;
- FilePathIds topIncludeIds;
- FilePathIds topSystemIncludeIds;
-};
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
index 999da26448..89ad912640 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
@@ -42,12 +42,12 @@ namespace ClangBackEnd {
PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
PchTaskGeneratorInterface &pchTaskGenerator,
- ProjectPartsInterface &projectParts,
+ ProjectPartsManagerInterface &projectParts,
GeneratedFilesInterface &generatedFiles)
- : m_fileSystemWatcher(fileSystemWatcher),
- m_pchTaskGenerator(pchTaskGenerator),
- m_projectParts(projectParts),
- m_generatedFiles(generatedFiles)
+ : m_fileSystemWatcher(fileSystemWatcher)
+ , m_pchTaskGenerator(pchTaskGenerator)
+ , m_projectPartsManager(projectParts)
+ , m_generatedFiles(generatedFiles)
{
m_fileSystemWatcher.setNotifier(this);
}
@@ -61,13 +61,13 @@ void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
{
m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments);
- ProjectPartContainers newProjectParts = m_projectParts.update(message.takeProjectsParts());
+ ProjectPartContainers newProjectParts = m_projectPartsManager.update(message.takeProjectsParts());
if (m_generatedFiles.isValid()) {
m_pchTaskGenerator.addProjectParts(std::move(newProjectParts),
std::move(message.toolChainArguments));
} else {
- m_projectParts.updateDeferred(newProjectParts);
+ m_projectPartsManager.updateDeferred(newProjectParts);
}
}
@@ -75,7 +75,7 @@ void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)
{
m_fileSystemWatcher.removeIds(message.projectsPartIds);
- m_projectParts.remove(message.projectsPartIds);
+ m_projectPartsManager.remove(message.projectsPartIds);
m_pchTaskGenerator.removeProjectParts(message.projectsPartIds);
@@ -102,7 +102,7 @@ void PchManagerServer::updateGeneratedFiles(UpdateGeneratedFilesMessage &&messag
m_generatedFiles.update(message.takeGeneratedFiles());
if (m_generatedFiles.isValid()) {
- ProjectPartContainers deferredProjectParts = m_projectParts.deferredUpdates();
+ ProjectPartContainers deferredProjectParts = m_projectPartsManager.deferredUpdates();
ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(
projectPartIds(deferredProjectParts));
@@ -123,8 +123,8 @@ void PchManagerServer::pathsWithIdsChanged(const Utils::SmallStringVector &ids)
ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(ids);
for (ArgumentsEntry &entry : entries) {
- m_pchTaskGenerator.addProjectParts(
- m_projectParts.projects(entry.ids), std::move(entry.arguments));
+ m_pchTaskGenerator.addProjectParts(m_projectPartsManager.projects(entry.ids),
+ std::move(entry.arguments));
}
}
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
index bf6b5bd7e7..9cf8aa8321 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
@@ -29,7 +29,7 @@
#include "clangpathwatchernotifier.h"
#include "pchcreatorinterface.h"
#include "pchmanagerserverinterface.h"
-#include "projectpartsinterface.h"
+#include "projectpartsmanagerinterface.h"
#include "toolchainargumentscache.h"
#include <generatedfilesinterface.h>
@@ -48,7 +48,7 @@ class PchManagerServer : public PchManagerServerInterface,
public:
PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
PchTaskGeneratorInterface &pchTaskGenerator,
- ProjectPartsInterface &projectParts,
+ ProjectPartsManagerInterface &projectParts,
GeneratedFilesInterface &generatedFiles);
void end() override;
@@ -66,7 +66,7 @@ public:
private:
ClangPathWatcherInterface &m_fileSystemWatcher;
PchTaskGeneratorInterface &m_pchTaskGenerator;
- ProjectPartsInterface &m_projectParts;
+ ProjectPartsManagerInterface &m_projectPartsManager;
GeneratedFilesInterface &m_generatedFiles;
ToolChainsArgumentsCache m_toolChainsArgumentsCache;
};
diff --git a/src/tools/clangpchmanagerbackend/source/pchtask.h b/src/tools/clangpchmanagerbackend/source/pchtask.h
index c94d7ac816..528d6e63f1 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtask.h
+++ b/src/tools/clangpchmanagerbackend/source/pchtask.h
@@ -41,7 +41,7 @@ class PchTask
public:
PchTask(Utils::SmallString &&projectPartId,
FilePathIds &&includes,
- FilePathIds &&allIncludes,
+ FilePathIds &&sources,
CompilerMacros &&compilerMacros,
Utils::SmallStringVector &&usedMacros,
Utils::SmallStringVector toolChainArguments,
@@ -52,7 +52,7 @@ public:
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
: projectPartIds({projectPartId})
, includes(includes)
- , allIncludes(allIncludes)
+ , sources(sources)
, compilerMacros(compilerMacros)
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
@@ -64,7 +64,7 @@ public:
PchTask(Utils::SmallStringVector &&projectPartIds,
FilePathIds &&includes,
- FilePathIds &&allIncludes,
+ FilePathIds &&sources,
CompilerMacros &&compilerMacros,
Utils::SmallStringVector &&usedMacros,
Utils::SmallStringVector toolChainArguments,
@@ -75,7 +75,7 @@ public:
Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
: projectPartIds(std::move(projectPartIds))
, includes(includes)
- , allIncludes(allIncludes)
+ , sources(sources)
, compilerMacros(compilerMacros)
, systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
, projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
@@ -104,7 +104,7 @@ public:
FilePath systemPchPath;
Utils::SmallStringVector projectPartIds;
FilePathIds includes;
- FilePathIds allIncludes;
+ FilePathIds sources;
CompilerMacros compilerMacros;
IncludeSearchPaths systemIncludeSearchPaths;
IncludeSearchPaths projectIncludeSearchPaths;
diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp
index aab3bfe7d4..a44fc91b16 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp
@@ -45,7 +45,7 @@ void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts,
for (auto &projectPart : projectParts) {
BuildDependency buildDependency = m_buildDependenciesProvider.create(projectPart);
- UsedMacroFilter filter{buildDependency.includes,
+ UsedMacroFilter filter{buildDependency.sources,
buildDependency.usedMacros,
projectPart.compilerMacros};
@@ -62,7 +62,7 @@ void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts,
projectPart.languageExtension},
PchTask{std::move(projectPart.projectPartId),
std::move(filter.topProjectIncludes),
- std::move(filter.allIncludes),
+ std::move(filter.sources),
std::move(filter.projectCompilerMacros),
std::move(filter.projectUsedMacros),
projectPart.toolChainArguments,
diff --git a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp
index 50851a838a..65d1a3e9fe 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp
@@ -96,8 +96,8 @@ bool PchTasksMerger::mergePchTasks(PchTask &firstTask, PchTask &secondTask)
firstTask.projectPartIds = merge(std::move(firstTask.projectPartIds),
std::move(secondTask.projectPartIds));
firstTask.includes = merge(std::move(firstTask.includes), std::move(secondTask.includes));
- firstTask.allIncludes = merge(std::move(firstTask.allIncludes),
- std::move(secondTask.allIncludes));
+ firstTask.sources = merge(std::move(firstTask.sources),
+ std::move(secondTask.sources));
firstTask.compilerMacros = std::move(macros);
firstTask.systemIncludeSearchPaths = mergeIncludeSearchPaths(
std::move(firstTask.systemIncludeSearchPaths),
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.cpp b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp
index e8df25e104..8333ed9674 100644
--- a/src/tools/clangpchmanagerbackend/source/projectparts.cpp
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp
@@ -23,7 +23,7 @@
**
****************************************************************************/
-#include "projectparts.h"
+#include "projectpartsmanager.h"
#include <projectpartcontainer.h>
@@ -33,7 +33,7 @@ namespace ClangBackEnd {
inline namespace Pch {
-ProjectPartContainers ProjectParts::update(ProjectPartContainers &&projectsParts)
+ProjectPartContainers ProjectPartsManager::update(ProjectPartContainers &&projectsParts)
{
auto updatedProjectPartContainers = newProjectParts(std::move(projectsParts));
@@ -42,7 +42,7 @@ ProjectPartContainers ProjectParts::update(ProjectPartContainers &&projectsParts
return updatedProjectPartContainers;
}
-void ProjectParts::remove(const Utils::SmallStringVector &ids)
+void ProjectPartsManager::remove(const Utils::SmallStringVector &ids)
{
auto shouldRemove = [&] (const ProjectPartContainer &projectPart) {
return std::find(ids.begin(), ids.end(), projectPart.projectPartId) != ids.end();
@@ -52,7 +52,7 @@ void ProjectParts::remove(const Utils::SmallStringVector &ids)
m_projectParts.erase(newEnd, m_projectParts.end());
}
-ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector &projectPartIds) const
+ProjectPartContainers ProjectPartsManager::projects(const Utils::SmallStringVector &projectPartIds) const
{
ProjectPartContainers projectPartsWithIds;
@@ -66,7 +66,7 @@ ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector &pro
return projectPartsWithIds;
}
-void ProjectParts::updateDeferred(const ProjectPartContainers &deferredProjectsParts)
+void ProjectPartsManager::updateDeferred(const ProjectPartContainers &deferredProjectsParts)
{
using ProjectPartContainerReferences = std::vector<std::reference_wrapper<ProjectPartContainer>>;
@@ -86,7 +86,7 @@ void ProjectParts::updateDeferred(const ProjectPartContainers &deferredProjectsP
projectPart.updateIsDeferred = true;
}
-ProjectPartContainers ProjectParts::deferredUpdates()
+ProjectPartContainers ProjectPartsManager::deferredUpdates()
{
ProjectPartContainers deferredProjectParts;
deferredProjectParts.reserve(m_projectParts.size());
@@ -102,7 +102,7 @@ ProjectPartContainers ProjectParts::deferredUpdates()
return deferredProjectParts;
}
-ProjectPartContainers ProjectParts::newProjectParts(ProjectPartContainers &&projectsParts) const
+ProjectPartContainers ProjectPartsManager::newProjectParts(ProjectPartContainers &&projectsParts) const
{
ProjectPartContainers updatedProjectPartContainers;
updatedProjectPartContainers.reserve(projectsParts.size());
@@ -116,7 +116,7 @@ ProjectPartContainers ProjectParts::newProjectParts(ProjectPartContainers &&proj
return updatedProjectPartContainers;
}
-void ProjectParts::mergeProjectParts(const ProjectPartContainers &projectsParts)
+void ProjectPartsManager::mergeProjectParts(const ProjectPartContainers &projectsParts)
{
ProjectPartContainers newProjectParts;
newProjectParts.reserve(m_projectParts.size() + projectsParts.size());
@@ -135,7 +135,7 @@ void ProjectParts::mergeProjectParts(const ProjectPartContainers &projectsParts)
m_projectParts = newProjectParts;
}
-const ProjectPartContainers &ProjectParts::projectParts() const
+const ProjectPartContainers &ProjectPartsManager::projectParts() const
{
return m_projectParts;
}
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.h b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h
index 4df413ce6f..2b3c43ebc8 100644
--- a/src/tools/clangpchmanagerbackend/source/projectparts.h
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h
@@ -27,15 +27,14 @@
#include "clangpchmanagerbackend_global.h"
-#include <projectpartsinterface.h>
+#include <projectpartsmanagerinterface.h>
#include <utils/smallstringvector.h>
namespace ClangBackEnd {
inline namespace Pch {
-
-class ProjectParts final : public ProjectPartsInterface
+class ProjectPartsManager final : public ProjectPartsManagerInterface
{
public:
ProjectPartContainers update(ProjectPartContainers &&projectsParts) override;
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h b/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h
index d37673af10..f99674ddda 100644
--- a/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h
@@ -29,12 +29,12 @@
namespace ClangBackEnd {
-class ProjectPartsInterface
+class ProjectPartsManagerInterface
{
public:
- ProjectPartsInterface() = default;
- ProjectPartsInterface(const ProjectPartsInterface &) = delete;
- ProjectPartsInterface &operator=(const ProjectPartsInterface &) = delete;
+ ProjectPartsManagerInterface() = default;
+ ProjectPartsManagerInterface(const ProjectPartsManagerInterface &) = delete;
+ ProjectPartsManagerInterface &operator=(const ProjectPartsManagerInterface &) = delete;
virtual ProjectPartContainers update(ProjectPartContainers &&projectsParts) = 0;
virtual void remove(const Utils::SmallStringVector &projectPartIds) = 0;
@@ -42,7 +42,7 @@ public:
virtual void updateDeferred(const ProjectPartContainers &projectsParts) = 0;
virtual ProjectPartContainers deferredUpdates() = 0;
protected:
- ~ProjectPartsInterface() = default;
+ ~ProjectPartsManagerInterface() = default;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/sourceentry.h b/src/tools/clangpchmanagerbackend/source/sourceentry.h
index e903baf3f6..5c45db6bde 100644
--- a/src/tools/clangpchmanagerbackend/source/sourceentry.h
+++ b/src/tools/clangpchmanagerbackend/source/sourceentry.h
@@ -31,19 +31,22 @@
namespace ClangBackEnd {
-enum class SourceType : unsigned char
-{
+enum class SourceType : unsigned char {
TopProjectInclude,
TopSystemInclude,
UserInclude,
ProjectInclude,
- SystemInclude
+ SystemInclude,
+ Source
};
+enum class HasMissingIncludes : unsigned char { No, Yes };
+
class TimeStamp
{
using int64 = long long;
public:
+ TimeStamp() = default;
TimeStamp(int64 value)
: value(value)
{}
@@ -58,7 +61,6 @@ public:
class SourceTimeStamp
{
-protected:
using int64 = long long;
public:
SourceTimeStamp(int sourceId, int64 lastModified)
@@ -103,37 +105,47 @@ public:
using SourceTimeStamps = std::vector<SourceTimeStamp>;
-class SourceEntry : public SourceTimeStamp
+class SourceEntry
{
+ using int64 = long long;
public:
- SourceEntry(int sourceId, int64 lastModified, int sourceType)
- : SourceTimeStamp(sourceId, lastModified)
- , sourceType(static_cast<SourceType>(sourceType))
- {}
-
- SourceEntry(FilePathId sourceId, SourceType sourceType, TimeStamp lastModified)
- : SourceTimeStamp(sourceId, lastModified)
- , sourceType(sourceType)
- {}
-
- friend bool operator<(SourceEntry first, SourceEntry second)
- {
+ SourceEntry(int sourceId,
+ int64 pchCreationTimeStamp,
+ int sourceType,
+ int hasMissingIncludes)
+ : pchCreationTimeStamp(pchCreationTimeStamp), sourceId(sourceId),
+ sourceType(static_cast<SourceType>(sourceType)),
+ hasMissingIncludes(
+ static_cast<HasMissingIncludes>(hasMissingIncludes)) {}
+
+ SourceEntry(FilePathId sourceId,
+ SourceType sourceType,
+ TimeStamp pchCreationTimeStamp,
+ HasMissingIncludes hasMissingIncludes = HasMissingIncludes::No)
+ : pchCreationTimeStamp(pchCreationTimeStamp), sourceId(sourceId),
+ sourceType(sourceType), hasMissingIncludes(hasMissingIncludes) {}
+
+ friend bool operator<(SourceEntry first, SourceEntry second) {
return first.sourceId < second.sourceId;
}
friend bool operator==(SourceEntry first, SourceEntry second)
{
return first.sourceId == second.sourceId && first.sourceType == second.sourceType
- && first.lastModified == second.lastModified;
+ && first.pchCreationTimeStamp == second.pchCreationTimeStamp;
}
friend bool operator!=(SourceEntry first, SourceEntry second) { return !(first == second); }
public:
+ TimeStamp pchCreationTimeStamp;
+ FilePathId sourceId;
SourceType sourceType = SourceType::UserInclude;
+ HasMissingIncludes hasMissingIncludes = HasMissingIncludes::No;
};
using SourceEntries = std::vector<SourceEntry>;
-
-}
+using SourceEntryReference = std::reference_wrapper<SourceEntry>;
+using SourceEntryReferences = std::vector<SourceEntryReference>;
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
index 6042895325..9db3c683b9 100644
--- a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
+++ b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
@@ -87,23 +87,22 @@ public:
UsedMacroFilter(const SourceEntries &includes,
const UsedMacros &usedMacros,
- const CompilerMacros &compilerMacros)
- {
- filterIncludes(includes);
+ const CompilerMacros &compilerMacros) {
+ filterSources(includes);
systemUsedMacros = filterUsedMarcos(usedMacros, systemIncludes);
projectUsedMacros = filterUsedMarcos(usedMacros, projectIncludes);
filter(compilerMacros);
}
- void filterIncludes(const SourceEntries &includes)
- {
- systemIncludes.reserve(includes.size());
- projectIncludes.reserve(includes.size());
- topSystemIncludes.reserve(includes.size() / 10);
- topProjectIncludes.reserve(includes.size() / 10);
+ void filterSources(const SourceEntries &sources) {
+ systemIncludes.reserve(sources.size());
+ projectIncludes.reserve(sources.size());
+ topSystemIncludes.reserve(sources.size() / 10);
+ topProjectIncludes.reserve(sources.size() / 10);
+ this->sources.reserve(sources.size());
- for (SourceEntry include : includes)
- filterInclude(include);
+ for (SourceEntry source : sources)
+ filterSource(source);
}
void filter(const CompilerMacros &compilerMacros)
@@ -121,28 +120,31 @@ public:
}
private:
- void filterInclude(SourceEntry include)
- {
- switch (include.sourceType) {
- case SourceType::TopSystemInclude:
- topSystemIncludes.emplace_back(include.sourceId);
- systemIncludes.emplace_back(include.sourceId);
- break;
- case SourceType::SystemInclude:
- systemIncludes.emplace_back(include.sourceId);
- break;
- case SourceType::TopProjectInclude:
- topProjectIncludes.emplace_back(include.sourceId);
- projectIncludes.emplace_back(include.sourceId);
- break;
- case SourceType::ProjectInclude:
- projectIncludes.emplace_back(include.sourceId);
- break;
- case SourceType::UserInclude:
- break;
+ void filterSource(SourceEntry source) {
+ if (source.hasMissingIncludes == HasMissingIncludes::Yes)
+ return;
+
+ switch (source.sourceType) {
+ case SourceType::TopSystemInclude:
+ topSystemIncludes.emplace_back(source.sourceId);
+ systemIncludes.emplace_back(source.sourceId);
+ break;
+ case SourceType::SystemInclude:
+ systemIncludes.emplace_back(source.sourceId);
+ break;
+ case SourceType::TopProjectInclude:
+ topProjectIncludes.emplace_back(source.sourceId);
+ projectIncludes.emplace_back(source.sourceId);
+ break;
+ case SourceType::ProjectInclude:
+ projectIncludes.emplace_back(source.sourceId);
+ break;
+ case SourceType::UserInclude:
+ case SourceType::Source:
+ break;
}
- allIncludes.emplace_back(include.sourceId);
+ sources.emplace_back(source.sourceId);
}
static Utils::SmallStringVector filterUsedMarcos(const UsedMacros &usedMacros,
@@ -209,7 +211,7 @@ private:
}
public:
- FilePathIds allIncludes;
+ FilePathIds sources;
FilePathIds projectIncludes;
FilePathIds systemIncludes;
FilePathIds topProjectIncludes;
diff --git a/src/tools/clangrefactoringbackend/source/filestatus.h b/src/tools/clangrefactoringbackend/source/filestatus.h
index 9ade546294..da2be4a304 100644
--- a/src/tools/clangrefactoringbackend/source/filestatus.h
+++ b/src/tools/clangrefactoringbackend/source/filestatus.h
@@ -36,15 +36,8 @@ namespace ClangBackEnd {
class FileStatus
{
public:
- FileStatus(FilePathId filePathId,
- off_t size,
- std::time_t lastModified,
- bool isInPrecompiledHeader)
- : filePathId(filePathId),
- size(size),
- lastModified(lastModified),
- isInPrecompiledHeader(isInPrecompiledHeader)
- {}
+ FileStatus(FilePathId filePathId, off_t size, std::time_t lastModified)
+ : filePathId(filePathId), size(size), lastModified(lastModified) {}
friend
bool operator==(const FileStatus &first, const FileStatus &second)
@@ -64,7 +57,6 @@ public:
FilePathId filePathId;
off_t size;
std::time_t lastModified;
- bool isInPrecompiledHeader;
};
using FileStatuses = std::vector<FileStatus>;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
index 6928e49712..aee8344fc9 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -120,8 +120,7 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
std::vector<SymbolIndexerTask> symbolIndexerTask;
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
- auto indexing = [projectPartId,
- arguments = commandLineBuilder.commandLine,
+ auto indexing = [arguments = commandLineBuilder.commandLine,
sourcePathId,
this](SymbolsCollectorInterface &symbolsCollector) {
symbolsCollector.setFile(sourcePathId, arguments);
@@ -134,12 +133,9 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
symbolsCollector.sourceLocations());
- m_symbolStorage.updateProjectPartSources(projectPartId,
- symbolsCollector.sourceFiles());
-
m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
- m_buildDependencyStorage.insertFileStatuses(symbolsCollector.fileStatuses());
+ m_buildDependencyStorage.insertOrUpdateFileStatuses(symbolsCollector.fileStatuses());
m_buildDependencyStorage.insertOrUpdateSourceDependencies(
symbolsCollector.sourceDependencies());
@@ -193,10 +189,8 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
CommandLineBuilder<ProjectPartArtefact, Utils::SmallStringVector>
builder{artefact, artefact.toolChainArguments, InputFileType::Source, {}, {}, pchPath};
- auto indexing = [projectPartId = artefact.projectPartId,
- arguments = builder.commandLine,
- filePathId,
- this](SymbolsCollectorInterface &symbolsCollector) {
+ auto indexing = [arguments = builder.commandLine, filePathId, this](
+ SymbolsCollectorInterface &symbolsCollector) {
symbolsCollector.setFile(filePathId, arguments);
bool success = symbolsCollector.collectSymbols();
@@ -207,11 +201,9 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
symbolsCollector.sourceLocations());
- m_symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
-
m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
- m_buildDependencyStorage.insertFileStatuses(symbolsCollector.fileStatuses());
+ m_buildDependencyStorage.insertOrUpdateFileStatuses(symbolsCollector.fileStatuses());
m_buildDependencyStorage.insertOrUpdateSourceDependencies(
symbolsCollector.sourceDependencies());
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h
index 3b7141c783..798fa26dd0 100644
--- a/src/tools/clangrefactoringbackend/source/symbolstorage.h
+++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h
@@ -112,17 +112,6 @@ public:
return statement.template value<ProjectPartArtefact, 8>(projectPartName);
}
- void updateProjectPartSources(int projectPartId,
- const FilePathIds &sourceFilePathIds) override
- {
- WriteStatement &deleteStatement = m_deleteAllProjectPartsSourcesWithProjectPartIdStatement;
- deleteStatement.write(projectPartId);
-
- WriteStatement &insertStatement = m_insertProjectPartSourcesStatement;
- for (const FilePathId &sourceFilePathId : sourceFilePathIds)
- insertStatement.write(projectPartId, sourceFilePathId.filePathId);
- }
-
static Utils::SmallString toJson(const Utils::SmallStringVector &strings)
{
QJsonDocument document;
@@ -322,14 +311,7 @@ public:
"SELECT projectPartId FROM projectParts WHERE projectPartName = ?",
m_database
};
- WriteStatement m_deleteAllProjectPartsSourcesWithProjectPartIdStatement{
- "DELETE FROM projectPartsSources WHERE projectPartId = ?",
- m_database
- };
- WriteStatement m_insertProjectPartSourcesStatement{
- "INSERT INTO projectPartsSources(projectPartId, sourceId) VALUES (?,?)",
- m_database
- };
+
mutable ReadStatement m_getCompileArgumentsForFileIdStatement{
"SELECT toolChainArguments FROM projectParts WHERE projectPartId = (SELECT projectPartId "
"FROM projectPartsSources WHERE sourceId = ?)",
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
index 5f2e6c30e6..210f66f7da 100644
--- a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
@@ -61,7 +61,6 @@ public:
Utils::LanguageVersion languageVersion,
Utils::LanguageExtension languageExtension)
= 0;
- virtual void updateProjectPartSources(int projectPartId, const FilePathIds &sourceFilePathIds) = 0;
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
FilePathId sourceId) const = 0;
virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
diff --git a/tests/unit/unittest/builddependenciesprovider-test.cpp b/tests/unit/unittest/builddependenciesprovider-test.cpp
index 2a5372c55d..b69965cc56 100644
--- a/tests/unit/unittest/builddependenciesprovider-test.cpp
+++ b/tests/unit/unittest/builddependenciesprovider-test.cpp
@@ -99,9 +99,7 @@ protected:
UsedMacros thirdUsedMacros{{"SAN", 10}};
FilePathIds sourceFiles{1, 3, 8};
ClangBackEnd::SourceDependencies sourceDependencies{{1, 3}, {1, 8}};
- ClangBackEnd::FileStatuses fileStatuses{{1, 21, 12, false},
- {3, 21, 12, false},
- {8, 21, 12, false}};
+ ClangBackEnd::FileStatuses fileStatuses{{1, 21, 12}, {3, 21, 12}, {8, 21, 12}};
BuildDependency buildDependency{
secondSources,
secondUsedMacros,
@@ -117,7 +115,9 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromStorageIfTime
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockBuildDependenciesStorage,
- fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1")))
+ fetchProjectPartId(TypedEq<Utils::SmallStringView>("ProjectPart1")))
+ .WillOnce(Return(11));
+ EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, 11))
.WillRepeatedly(Return(firstSources));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true));
@@ -132,15 +132,24 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromStorageIfTime
TEST_F(BuildDependenciesProvider, FetchDependSourcesFromStorage)
{
- ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(firstSources));
- ON_CALL(mockBuildDependenciesStorage, fetchDependSources({3}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(secondSources));
- ON_CALL(mockBuildDependenciesStorage, fetchDependSources({4}, TypedEq<Utils::SmallStringView>("ProjectPart2"))).WillByDefault(Return(thirdSources));
+ ON_CALL(mockBuildDependenciesStorage,
+ fetchProjectPartId(TypedEq<Utils::SmallStringView>("ProjectPart2")))
+ .WillByDefault(Return(11));
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, 11)).WillByDefault(Return(firstSources));
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({3}, 11)).WillByDefault(Return(secondSources));
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({4}, 11)).WillByDefault(Return(thirdSources));
ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(true));
auto buildDependency = provider.create(projectPart2);
- ASSERT_THAT(buildDependency.includes, ElementsAre(HasSourceId(1), HasSourceId(2), HasSourceId(3), HasSourceId(4), HasSourceId(8), HasSourceId(10)));
+ ASSERT_THAT(buildDependency.sources,
+ ElementsAre(HasSourceId(1),
+ HasSourceId(2),
+ HasSourceId(3),
+ HasSourceId(4),
+ HasSourceId(8),
+ HasSourceId(10)));
}
TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromGeneratorIfTimeStampsAreNotUpToDate)
@@ -149,15 +158,17 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromGeneratorIfTi
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockBuildDependenciesStorage,
- fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1")))
+ fetchProjectPartId(TypedEq<Utils::SmallStringView>("ProjectPart1")))
+ .WillOnce(Return(11));
+ EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<int>(11)))
.WillRepeatedly(Return(firstSources));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(false));
EXPECT_CALL(mockBuildDependenciesGenerator, create(projectPart1))
.WillOnce(Return(buildDependency));
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
- EXPECT_CALL(mockBuildDependenciesStorage, updateSources(Eq(secondSources)));
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatuses)));
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSources(Eq(secondSources), 11));
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatuses)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(secondUsedMacros)));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
@@ -167,13 +178,16 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchDependSourcesFromGeneratorIfTi
TEST_F(BuildDependenciesProvider, FetchDependSourcesFromGenerator)
{
- ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillByDefault(Return(firstSources));
+ ON_CALL(mockBuildDependenciesStorage,
+ fetchProjectPartId(TypedEq<Utils::SmallStringView>("ProjectPart1")))
+ .WillByDefault(Return(11));
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, 11)).WillByDefault(Return(firstSources));
ON_CALL(mockModifiedTimeChecker, isUpToDate(_)).WillByDefault(Return(false));
ON_CALL(mockBuildDependenciesGenerator, create(projectPart1)).WillByDefault(Return(buildDependency));
auto buildDependency = provider.create(projectPart1);
- ASSERT_THAT(buildDependency.includes, ElementsAre(HasSourceId(1), HasSourceId(3), HasSourceId(8)));
+ ASSERT_THAT(buildDependency.sources, ElementsAre(HasSourceId(1), HasSourceId(3), HasSourceId(8)));
}
TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeStampsAreUpToDate)
@@ -181,7 +195,11 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeSta
InSequence s;
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
- EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillRepeatedly(Return(firstSources));
+ EXPECT_CALL(mockBuildDependenciesStorage,
+ fetchProjectPartId(TypedEq<Utils::SmallStringView>("ProjectPart1")))
+ .WillOnce(Return(11));
+ EXPECT_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, 11))
+ .WillRepeatedly(Return(firstSources));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillRepeatedly(Return(true));
EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
@@ -195,7 +213,10 @@ TEST_F(BuildDependenciesProvider, CreateCallsFetchUsedMacrosFromStorageIfTimeSta
TEST_F(BuildDependenciesProvider, FetchUsedMacrosFromStorageIfDependSourcesAreUpToDate)
{
- ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, TypedEq<Utils::SmallStringView>("ProjectPart1"))).WillByDefault(Return(firstSources));
+ ON_CALL(mockBuildDependenciesStorage,
+ fetchProjectPartId(TypedEq<Utils::SmallStringView>("ProjectPart1")))
+ .WillByDefault(Return(11));
+ ON_CALL(mockBuildDependenciesStorage, fetchDependSources({2}, 11)).WillByDefault(Return(firstSources));
ON_CALL(mockModifiedTimeChecker, isUpToDate(firstSources)).WillByDefault(Return(true));
ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({1})).WillByDefault(Return(firstUsedMacros));
ON_CALL(mockBuildDependenciesStorage, fetchUsedMacros({2})).WillByDefault(Return(secondUsedMacros));
diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp
index d69f8b868a..30db7ea408 100644
--- a/tests/unit/unittest/builddependenciesstorage-test.cpp
+++ b/tests/unit/unittest/builddependenciesstorage-test.cpp
@@ -55,17 +55,20 @@ protected:
MockSqliteWriteStatement &syncNewUsedMacrosStatement =storage.syncNewUsedMacrosStatement;
MockSqliteWriteStatement &deleteOutdatedUsedMacrosStatement = storage.deleteOutdatedUsedMacrosStatement;
MockSqliteWriteStatement &deleteNewUsedMacrosTableStatement = storage.deleteNewUsedMacrosTableStatement;
- MockSqliteWriteStatement &insertFileStatuses = storage.insertFileStatusesStatement;
+ MockSqliteWriteStatement &insertOrUpdateFileStatusesStatement = storage.insertOrUpdateFileStatusesStatement;
MockSqliteWriteStatement &insertIntoNewSourceDependenciesStatement = storage.insertIntoNewSourceDependenciesStatement;
MockSqliteWriteStatement &syncNewSourceDependenciesStatement = storage.syncNewSourceDependenciesStatement;
MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = storage.deleteOutdatedSourceDependenciesStatement;
MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = storage.deleteNewSourceDependenciesStatement;
MockSqliteReadStatement &getLowestLastModifiedTimeOfDependencies = storage.getLowestLastModifiedTimeOfDependencies;
- MockSqliteWriteStatement &updateBuildDependencyTimeStampStatement = storage.updateBuildDependencyTimeStampStatement;
- MockSqliteWriteStatement &updateSourceTypeStatement = storage.updateSourceTypeStatement;
+ MockSqliteWriteStatement &insertOrUpdateProjectPartsSourcesStatement = storage.insertOrUpdateProjectPartsSourcesStatement;
MockSqliteReadStatement &fetchSourceDependenciesStatement = storage.fetchSourceDependenciesStatement;
MockSqliteReadStatement &fetchProjectPartIdStatement = storage.fetchProjectPartIdStatement;
MockSqliteReadStatement &fetchUsedMacrosStatement = storage.fetchUsedMacrosStatement;
+ MockSqliteWriteStatement &insertProjectPartNameStatement = storage.insertProjectPartNameStatement;
+ MockSqliteWriteStatement &updatePchCreationTimeStampStatement = storage.updatePchCreationTimeStampStatement;
+ MockSqliteWriteStatement &deleteAllProjectPartsSourcesWithProjectPartNameStatement
+ = storage.deleteAllProjectPartsSourcesWithProjectPartNameStatement;
};
TEST_F(BuildDependenciesStorage, ConvertStringsToJson)
@@ -81,8 +84,10 @@ TEST_F(BuildDependenciesStorage, InsertOrUpdateUsedMacros)
{
InSequence sequence;
- EXPECT_CALL(insertIntoNewUsedMacrosStatement, write(TypedEq<uint>(42u), TypedEq<Utils::SmallStringView>("FOO")));
- EXPECT_CALL(insertIntoNewUsedMacrosStatement, write(TypedEq<uint>(43u), TypedEq<Utils::SmallStringView>("BAR")));
+ EXPECT_CALL(insertIntoNewUsedMacrosStatement,
+ write(TypedEq<int>(42), TypedEq<Utils::SmallStringView>("FOO")));
+ EXPECT_CALL(insertIntoNewUsedMacrosStatement,
+ write(TypedEq<int>(43), TypedEq<Utils::SmallStringView>("BAR")));
EXPECT_CALL(syncNewUsedMacrosStatement, execute());
EXPECT_CALL(deleteOutdatedUsedMacrosStatement, execute());
EXPECT_CALL(deleteNewUsedMacrosTableStatement, execute());
@@ -90,12 +95,14 @@ TEST_F(BuildDependenciesStorage, InsertOrUpdateUsedMacros)
storage.insertOrUpdateUsedMacros({{"FOO", 42}, {"BAR", 43}});
}
-TEST_F(BuildDependenciesStorage, InsertFileStatuses)
+TEST_F(BuildDependenciesStorage, InsertOrUpdateFileStatuses)
{
- EXPECT_CALL(insertFileStatuses, write(TypedEq<int>(42), TypedEq<off_t>(1), TypedEq<time_t>(2), TypedEq<bool>(false)));
- EXPECT_CALL(insertFileStatuses, write(TypedEq<int>(43), TypedEq<off_t>(4), TypedEq<time_t>(5), TypedEq<bool>(true)));
+ EXPECT_CALL(insertOrUpdateFileStatusesStatement,
+ write(TypedEq<int>(42), TypedEq<off_t>(1), TypedEq<time_t>(2)));
+ EXPECT_CALL(insertOrUpdateFileStatusesStatement,
+ write(TypedEq<int>(43), TypedEq<off_t>(4), TypedEq<time_t>(5)));
- storage.insertFileStatuses({{42, 1, 2, false}, {43, 4, 5, true}});
+ storage.insertOrUpdateFileStatuses({{42, 1, 2}, {43, 4, 5}});
}
TEST_F(BuildDependenciesStorage, InsertOrUpdateSourceDependencies)
@@ -125,7 +132,6 @@ TEST_F(BuildDependenciesStorage, AddTablesInConstructor)
Storage storage{mockDatabase};
}
-
TEST_F(BuildDependenciesStorage, FetchLowestLastModifiedTimeIfNoModificationTimeExists)
{
EXPECT_CALL(getLowestLastModifiedTimeOfDependencies, valueReturnInt64(Eq(1)));
@@ -168,48 +174,82 @@ TEST_F(BuildDependenciesStorage, AddNewSourceDependenciesTable)
TEST_F(BuildDependenciesStorage, UpdateSources)
{
InSequence s;
- SourceEntries entries{{1, SourceType::TopProjectInclude, 10}, {2, SourceType::TopSystemInclude, 20}};
+ SourceEntries entries{{1, SourceType::TopProjectInclude, 10, ClangBackEnd::HasMissingIncludes::Yes},
+ {2, SourceType::TopSystemInclude, 20}};
+
+ EXPECT_CALL(deleteAllProjectPartsSourcesWithProjectPartNameStatement, write(TypedEq<int>(22)));
+ EXPECT_CALL(insertOrUpdateProjectPartsSourcesStatement,
+ write(TypedEq<int>(1), TypedEq<int>(22), TypedEq<uchar>(0), TypedEq<uchar>(1)));
+ EXPECT_CALL(insertOrUpdateProjectPartsSourcesStatement,
+ write(TypedEq<int>(2), TypedEq<int>(22), TypedEq<uchar>(1), TypedEq<uchar>(0)));
+
+ storage.insertOrUpdateSources(entries, 22);
+}
+
+TEST_F(BuildDependenciesStorage, UpdatePchCreationTimeStamp)
+{
+ InSequence s;
- EXPECT_CALL(updateBuildDependencyTimeStampStatement, write(TypedEq<long long>(10), TypedEq<int>(1)));
- EXPECT_CALL(updateSourceTypeStatement, write(TypedEq<uchar>(0), TypedEq<int>(1)));
- EXPECT_CALL(updateBuildDependencyTimeStampStatement, write(TypedEq<long long>(20), TypedEq<int>(2)));
- EXPECT_CALL(updateSourceTypeStatement, write(TypedEq<uchar>(1), TypedEq<int>(2)));
+ EXPECT_CALL(mockDatabase, immediateBegin());
+ EXPECT_CALL(updatePchCreationTimeStampStatement,
+ write(TypedEq<long long>(101), TypedEq<Utils::SmallStringView>("project1")));
+ EXPECT_CALL(mockDatabase, commit());
- storage.updateSources(entries);
+ storage.updatePchCreationTimeStamp(101, "project1");
}
-TEST_F(BuildDependenciesStorage, CallsFetchDependSourcesWithNonExistingProjectPartDontFetchesSourceDependencies)
+TEST_F(BuildDependenciesStorage, CallsFetchProjectIdWithNonExistingProjectPartName)
{
- EXPECT_CALL(fetchProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("test"))).WillOnce(Return(Utils::optional<int>{}));
- EXPECT_CALL(fetchSourceDependenciesStatement, valuesReturnSourceEntries(_, _, _)).Times(0);
+ EXPECT_CALL(fetchProjectPartIdStatement,
+ valueReturnInt32(TypedEq<Utils::SmallStringView>("test")));
+ EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test")));
- storage.fetchDependSources(22, "test");
+ storage.fetchProjectPartId("test");
}
-TEST_F(BuildDependenciesStorage, CallsFetchDependSourcesWithExistingProjectPartFetchesSourceDependencies)
+TEST_F(BuildDependenciesStorage, CallsFetchProjectIdWithExistingProjectPart)
{
- EXPECT_CALL(fetchProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("test"))).WillOnce(Return(Utils::optional<int>{20}));
- EXPECT_CALL(fetchSourceDependenciesStatement, valuesReturnSourceEntries(_, 22, 20));
+ EXPECT_CALL(fetchProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("test")))
+ .WillOnce(Return(Utils::optional<int>{20}));
+ EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test"))).Times(0);
- storage.fetchDependSources(22, "test");
+ storage.fetchProjectPartId("test");
}
-TEST_F(BuildDependenciesStorage, FetchDependSourcesWithNonExistingProjectPartReturnsEmptySourceEntries)
+TEST_F(BuildDependenciesStorage, FetchProjectIdWithNonExistingProjectPartName)
{
- EXPECT_CALL(fetchProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("test"))).WillOnce(Return(Utils::optional<int>{}));
+ ON_CALL(fetchProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("test")))
+ .WillByDefault(Return(Utils::optional<int>{}));
+ ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(21));
- auto entries = storage.fetchDependSources(22, "test");
+ int id = storage.fetchProjectPartId("test");
+
+ ASSERT_THAT(id, 21);
+}
+
+TEST_F(BuildDependenciesStorage, FetchProjectIdWithExistingProjectPartName)
+{
+ ON_CALL(fetchProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("test")))
+ .WillByDefault(Return(Utils::optional<int>{20}));
+
+ int id = storage.fetchProjectPartId("test");
+
+ ASSERT_THAT(id, 20);
+}
+
+TEST_F(BuildDependenciesStorage, CallsFetchDependSources)
+{
+ EXPECT_CALL(fetchSourceDependenciesStatement, valuesReturnSourceEntries(_, 22, 20));
- ASSERT_THAT(entries, IsEmpty());
+ storage.fetchDependSources(22, 20);
}
-TEST_F(BuildDependenciesStorage, FetchDependSourcesWithExistingProjectPartReturnsSourceEntries)
+TEST_F(BuildDependenciesStorage, FetchDependSources)
{
SourceEntries sourceEntries{{1, SourceType::TopProjectInclude, 10}, {2, SourceType::TopSystemInclude, 20}};
- EXPECT_CALL(fetchProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("test"))).WillOnce(Return(Utils::optional<int>{20}));
EXPECT_CALL(fetchSourceDependenciesStatement, valuesReturnSourceEntries(_, 22, 20)).WillOnce(Return(sourceEntries));
- auto entries = storage.fetchDependSources(22, "test");
+ auto entries = storage.fetchDependSources(22, 20);
ASSERT_THAT(entries, sourceEntries);
}
diff --git a/tests/unit/unittest/builddependencycollector-test.cpp b/tests/unit/unittest/builddependencycollector-test.cpp
index aa46fc77bb..5850666232 100644
--- a/tests/unit/unittest/builddependencycollector-test.cpp
+++ b/tests/unit/unittest/builddependencycollector-test.cpp
@@ -47,19 +47,37 @@ using ClangBackEnd::BuildDependency;
using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathIds;
using ClangBackEnd::FilePathView;
+using ClangBackEnd::HasMissingIncludes;
using ClangBackEnd::SourceDependency;
using ClangBackEnd::SourceType;
using ClangBackEnd::UsedMacro;
namespace {
-MATCHER_P2(HasInclude, sourceId, sourceType,
+MATCHER_P2(HasSource,
+ sourceId,
+ sourceType,
std::string(negation ? "hasn't " : "has ")
- + PrintToString(ClangBackEnd::SourceEntry(sourceId, sourceType, -1)))
+ + PrintToString(ClangBackEnd::SourceEntry(
+ sourceId, sourceType, -1, ClangBackEnd::HasMissingIncludes::No)))
{
const ClangBackEnd::SourceEntry &entry = arg;
- return entry.sourceId == sourceId && entry.sourceType == sourceType;
+ return entry.sourceId == sourceId && entry.sourceType == sourceType
+ && entry.hasMissingIncludes == ClangBackEnd::HasMissingIncludes::No;
+}
+
+MATCHER_P3(HasSource,
+ sourceId,
+ sourceType,
+ hasMissingIncludes,
+ std::string(negation ? "hasn't " : "has ")
+ + PrintToString(ClangBackEnd::SourceEntry(sourceId, sourceType, -1, hasMissingIncludes)))
+{
+ const ClangBackEnd::SourceEntry &entry = arg;
+
+ return entry.sourceId == sourceId && entry.sourceType == sourceType
+ && entry.hasMissingIncludes == hasMissingIncludes;
}
class BuildDependencyCollector : public ::testing::Test
@@ -107,50 +125,50 @@ protected:
ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const
{
- return {id(filePath), fileSize(filePath), lastModified(filePath), false};
+ return {id(filePath), fileSize(filePath), lastModified(filePath)};
}
- static FilePathIds filteredIncludes(const ClangBackEnd::SourceEntries &includes,
- ClangBackEnd::SourceType includeType)
+ static FilePathIds filteredSources(const ClangBackEnd::SourceEntries &sources,
+ ClangBackEnd::SourceType sourceType)
{
- FilePathIds filteredIncludes;
+ FilePathIds filteredSources;
- for (const ClangBackEnd::SourceEntry &include : includes) {
- if (include.sourceType == includeType)
- filteredIncludes.push_back(include.sourceId);
+ for (const ClangBackEnd::SourceEntry &source : sources) {
+ if (source.sourceType == sourceType)
+ filteredSources.push_back(source.sourceId);
}
- return filteredIncludes;
+ return filteredSources;
}
- static FilePathIds topIncludes(const ClangBackEnd::SourceEntries &includes)
+ static FilePathIds topSources(const ClangBackEnd::SourceEntries &sources)
{
- return filteredIncludes(includes, ClangBackEnd::SourceType::TopProjectInclude);
+ return filteredSources(sources, ClangBackEnd::SourceType::TopProjectInclude);
}
- static FilePathIds systemTopIncludes(const ClangBackEnd::SourceEntries &includes)
+ static FilePathIds systemTopSources(const ClangBackEnd::SourceEntries &sources)
{
- return filteredIncludes(includes, ClangBackEnd::SourceType::TopSystemInclude);
+ return filteredSources(sources, ClangBackEnd::SourceType::TopSystemInclude);
}
- static FilePathIds userIncludes(const ClangBackEnd::SourceEntries &includes)
+ static FilePathIds userSources(const ClangBackEnd::SourceEntries &sources)
{
- return filteredIncludes(includes, ClangBackEnd::SourceType::UserInclude);
+ return filteredSources(sources, ClangBackEnd::SourceType::UserInclude);
}
- static FilePathIds projectPartIncludes(const ClangBackEnd::SourceEntries &includes)
+ static FilePathIds projectPartSources(const ClangBackEnd::SourceEntries &sources)
{
- return filteredIncludes(includes, ClangBackEnd::SourceType::ProjectInclude);
+ return filteredSources(sources, ClangBackEnd::SourceType::ProjectInclude);
}
- static FilePathIds allIncludes(const ClangBackEnd::SourceEntries &includes)
+ static FilePathIds sources(const ClangBackEnd::SourceEntries &sources)
{
- FilePathIds filteredIncludes;
+ FilePathIds filteredSources;
- for (const ClangBackEnd::SourceEntry &include : includes)
- filteredIncludes.push_back(include.sourceId);
+ for (const ClangBackEnd::SourceEntry &source : sources)
+ filteredSources.push_back(source.sourceId);
- return filteredIncludes;
+ return filteredSources;
}
protected:
@@ -173,26 +191,31 @@ TEST_F(BuildDependencyCollector, IncludesExternalHeader)
{
collector.collect();
- ASSERT_THAT(allIncludes(collector.includeIds()),
+ ASSERT_THAT(sources(collector.sourceEntries()),
AllOf(Contains(id(TESTDATA_DIR "/builddependencycollector/external/external1.h")),
Contains(id(TESTDATA_DIR "/builddependencycollector/external/external2.h")),
- Contains(id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h")),
- Contains(id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"))));
+ Contains(id(TESTDATA_DIR
+ "/builddependencycollector/external/indirect_external.h")),
+ Contains(id(TESTDATA_DIR
+ "/builddependencycollector/external/indirect_external2.h"))));
}
TEST_F(BuildDependencyCollector, InternalHeaderAreUserIncludes)
{
collector.collect();
- ASSERT_THAT(userIncludes(collector.includeIds()), Contains(id(TESTDATA_DIR "/builddependencycollector/project/header1.h")));
+ ASSERT_THAT(userSources(collector.sourceEntries()),
+ Contains(id(TESTDATA_DIR "/builddependencycollector/project/header1.h")));
}
TEST_F(BuildDependencyCollector, NoDuplicate)
{
collector.collect();
- ASSERT_THAT(allIncludes(collector.includeIds()),
+ ASSERT_THAT(sources(collector.sourceEntries()),
UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/main.cpp"),
+ id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp"),
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
@@ -206,15 +229,18 @@ TEST_F(BuildDependencyCollector, IncludesAreSorted)
{
collector.collect();
- ASSERT_THAT(allIncludes(collector.includeIds()),
- ElementsAre(
- id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
- id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external3.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external2.h")));
+ ASSERT_THAT(sources(collector.sourceEntries()),
+ ElementsAre(id(TESTDATA_DIR "/builddependencycollector/project/main.cpp"),
+ id(TESTDATA_DIR "/builddependencycollector/project/main2.cpp"),
+ id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external3.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ id(TESTDATA_DIR
+ "/builddependencycollector/external/indirect_external.h"),
+ id(TESTDATA_DIR
+ "/builddependencycollector/external/indirect_external2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h")));
}
TEST_F(BuildDependencyCollector, If)
@@ -223,8 +249,9 @@ TEST_F(BuildDependencyCollector, If)
emptyCollector.collect();
- ASSERT_THAT(allIncludes(emptyCollector.includeIds()),
- ElementsAre(id(TESTDATA_DIR "/builddependencycollector/project/true.h")));
+ ASSERT_THAT(sources(emptyCollector.sourceEntries()),
+ ElementsAre(id(TESTDATA_DIR "/builddependencycollector/project/if.cpp"),
+ id(TESTDATA_DIR "/builddependencycollector/project/true.h")));
}
TEST_F(BuildDependencyCollector, LocalPath)
@@ -233,8 +260,9 @@ TEST_F(BuildDependencyCollector, LocalPath)
emptyCollector.collect();
- ASSERT_THAT(allIncludes(emptyCollector.includeIds()),
+ ASSERT_THAT(sources(emptyCollector.sourceEntries()),
UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/main.cpp"),
id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
@@ -250,20 +278,23 @@ TEST_F(BuildDependencyCollector, IgnoreMissingFile)
emptyCollector.collect();
- ASSERT_THAT(allIncludes(emptyCollector.includeIds()),
- UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h")));
+ ASSERT_THAT(sources(emptyCollector.sourceEntries()),
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/project/missingfile.cpp"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/indirect_external.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/indirect_external2.h")));
}
TEST_F(BuildDependencyCollector, IncludesOnlyTopExternalHeader)
{
collector.collect();
- ASSERT_THAT(topIncludes(collector.includeIds()),
- UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external3.h")));
+ ASSERT_THAT(
+ topSources(collector.sourceEntries()),
+ UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external3.h")));
}
TEST_F(BuildDependencyCollector, TopIncludeInIfMacro)
@@ -273,7 +304,7 @@ TEST_F(BuildDependencyCollector, TopIncludeInIfMacro)
emptyCollector.collect();
- ASSERT_THAT(topIncludes(emptyCollector.includeIds()),
+ ASSERT_THAT(topSources(emptyCollector.sourceEntries()),
ElementsAre(id(TESTDATA_DIR "/builddependencycollector/project/true.h")));
}
@@ -283,10 +314,11 @@ TEST_F(BuildDependencyCollector, TopIncludeWithLocalPath)
emptyCollector.collect();
- ASSERT_THAT(topIncludes(emptyCollector.includeIds()),
- UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
- id(TESTDATA_DIR "/builddependencycollector/external/external3.h")));
+ ASSERT_THAT(
+ topSources(emptyCollector.sourceEntries()),
+ UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external3.h")));
}
TEST_F(BuildDependencyCollector, TopIncludesIgnoreMissingFile)
@@ -296,8 +328,9 @@ TEST_F(BuildDependencyCollector, TopIncludesIgnoreMissingFile)
emptyCollector.collect();
- ASSERT_THAT(topIncludes(emptyCollector.includeIds()),
- UnorderedElementsAre(id(TESTDATA_DIR "/builddependencycollector/external/external1.h")));
+ ASSERT_THAT(topSources(emptyCollector.sourceEntries()),
+ UnorderedElementsAre(
+ id(TESTDATA_DIR "/builddependencycollector/external/external1.h")));
}
TEST_F(BuildDependencyCollector, SourceFiles)
@@ -620,10 +653,37 @@ TEST_F(BuildDependencyCollector, MissingInclude)
emptyCollector.collect();
- ASSERT_THAT(emptyCollector.includeIds(),
- ElementsAre(
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
- SourceType::UserInclude)));
+ ASSERT_THAT(
+ emptyCollector.sourceEntries(),
+ UnorderedElementsAre(
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/main5.cpp"),
+ SourceType::Source,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/missinginclude2.h"),
+ SourceType::ProjectInclude,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR
+ "/builddependencycollector/project/indirect_missinginclude.h"),
+ SourceType::ProjectInclude,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR
+ "/builddependencycollector/project/indirect_missinginclude3.h"),
+ SourceType::ProjectInclude,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR
+ "/builddependencycollector/project/indirect_missinginclude4.h"),
+ SourceType::ProjectInclude,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/missinginclude3.h"),
+ SourceType::ProjectInclude,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR
+ "/builddependencycollector/project/indirect_missinginclude2.h"),
+ SourceType::ProjectInclude,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
+ SourceType::UserInclude,
+ HasMissingIncludes::No)));
}
@@ -643,10 +703,12 @@ TEST_F(BuildDependencyCollector, GeneratedFile)
emptyCollector.collect();
- ASSERT_THAT(emptyCollector.includeIds(),
- ElementsAre(
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"),
- SourceType::UserInclude)));
+ ASSERT_THAT(
+ emptyCollector.sourceEntries(),
+ ElementsAre(HasSource(id(TESTDATA_DIR "/builddependencycollector/project/main6.cpp"),
+ SourceType::Source),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"),
+ SourceType::UserInclude)));
}
TEST_F(BuildDependencyCollector, CreateFakeFileContent)
@@ -715,41 +777,43 @@ TEST_F(BuildDependencyCollector, Create)
fileStatus(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"),
fileStatus(TESTDATA_DIR "/builddependencycollector/project/macros.h"),
ClangBackEnd::FileStatus(
- id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"),
- 12,
- 0,
- false))),
- Field(&BuildDependency::includes,
- UnorderedElementsAre(
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
- SourceType::UserInclude),
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
- SourceType::UserInclude),
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/external/external3.h"),
- SourceType::TopProjectInclude),
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
- SourceType::TopProjectInclude),
- HasInclude(id(TESTDATA_DIR
- "/builddependencycollector/external/indirect_external.h"),
- SourceType::ProjectInclude),
- HasInclude(id(TESTDATA_DIR
- "/builddependencycollector/external/indirect_external2.h"),
- SourceType::ProjectInclude),
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
- SourceType::TopProjectInclude),
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
- SourceType::TopSystemInclude),
- HasInclude(id(TESTDATA_DIR
- "/builddependencycollector/system/indirect_system.h"),
- SourceType::SystemInclude),
- HasInclude(id(TESTDATA_DIR
- "/builddependencycollector/system/indirect_system2.h"),
- SourceType::SystemInclude),
- HasInclude(id(TESTDATA_DIR "/builddependencycollector/project/macros.h"),
- SourceType::UserInclude),
- HasInclude(id(TESTDATA_DIR
- "/builddependencycollector/project/generated_file.h"),
- SourceType::TopProjectInclude))),
+ id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"), 12, 0))),
+ Field(
+ &BuildDependency::sources,
+ UnorderedElementsAre(
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp"),
+ SourceType::Source,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"),
+ SourceType::UserInclude,
+ HasMissingIncludes::Yes),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
+ SourceType::UserInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
+ SourceType::UserInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/external/external3.h"),
+ SourceType::TopProjectInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ SourceType::TopProjectInclude),
+ HasSource(id(TESTDATA_DIR
+ "/builddependencycollector/external/indirect_external.h"),
+ SourceType::ProjectInclude),
+ HasSource(id(TESTDATA_DIR
+ "/builddependencycollector/external/indirect_external2.h"),
+ SourceType::ProjectInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/external/external2.h"),
+ SourceType::TopProjectInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
+ SourceType::TopSystemInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/system/indirect_system.h"),
+ SourceType::SystemInclude),
+ HasSource(id(TESTDATA_DIR
+ "/builddependencycollector/system/indirect_system2.h"),
+ SourceType::SystemInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/macros.h"),
+ SourceType::UserInclude),
+ HasSource(id(TESTDATA_DIR "/builddependencycollector/project/generated_file.h"),
+ SourceType::UserInclude))),
Field(&BuildDependency::usedMacros,
UnorderedElementsAre(
UsedMacro{"IFDEF", id(TESTDATA_DIR "/builddependencycollector/project/macros.h")},
@@ -843,6 +907,6 @@ TEST_F(BuildDependencyCollector, Clear)
auto buildDependency = collector.create(projectPart);
- ASSERT_THAT(buildDependency.includes, IsEmpty());
+ ASSERT_THAT(buildDependency.sources, IsEmpty());
}
} // namespace
diff --git a/tests/unit/unittest/clangformat-test.cpp b/tests/unit/unittest/clangformat-test.cpp
index 115ecaf763..ad2c8bf3e3 100644
--- a/tests/unit/unittest/clangformat-test.cpp
+++ b/tests/unit/unittest/clangformat-test.cpp
@@ -32,9 +32,8 @@
namespace TextEditor {
class TabSettings
-{
-};
-}
+{};
+} // namespace TextEditor
namespace {
@@ -58,10 +57,7 @@ public:
: ClangFormatIndenter(doc)
{}
- bool formatWhileTyping() const override
- {
- return true;
- }
+ bool formatWhileTyping() const override { return true; }
};
class ClangFormat : public ::testing::Test
@@ -76,6 +72,7 @@ protected:
void insertLines(const std::vector<QString> &lines)
{
+ doc.clear();
cursor.setPosition(0);
for (size_t lineNumber = 1; lineNumber <= lines.size(); ++lineNumber) {
if (lineNumber > 1)
@@ -104,6 +101,7 @@ protected:
QTextCursor cursor{&doc};
};
+// clang-format off
TEST_F(ClangFormat, IndentBasicFile)
{
insertLines({"int main()",
@@ -121,14 +119,14 @@ TEST_F(ClangFormat, IndentBasicFile)
TEST_F(ClangFormat, IndentEmptyLine)
{
- insertLines({"int main",
+ insertLines({"int main()",
"{",
"",
"}"});
indenter.indent(cursor, QChar::Null, TextEditor::TabSettings());
- ASSERT_THAT(documentLines(), ElementsAre("int main",
+ ASSERT_THAT(documentLines(), ElementsAre("int main()",
"{",
" ",
"}"));
@@ -365,7 +363,148 @@ TEST_F(ClangFormat, IndentEmptyLineAndKeepPreviousEmptyLines)
"}"));
}
-TEST_F(ClangFormat, IndentFunctionBodyAndFormatBeforeIt)
+TEST_F(ClangFormat, IndentOnElectricCharacterButNotRemoveEmptyLinesBefore)
+{
+ insertLines({"{",
+ " ",
+ " ",
+ "if ()",
+ "}"});
+
+ indenter.indentBlock(doc.findBlockByNumber(3), '(', TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("{",
+ " ",
+ " ",
+ " if ()",
+ "}"));
+}
+
+TEST_F(ClangFormat, IndentAfterExtraSpaceInpreviousLine)
+{
+ insertLines({"if (a ",
+ "&& b)"});
+
+ indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("if (a",
+ " && b)"));
+}
+
+TEST_F(ClangFormat, IndentEmptyLineInsideParantheses)
+{
+ insertLines({"if (a ",
+ "",
+ " && b)"});
+
+ indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("if (a",
+ " ",
+ " && b)"));
+}
+
+TEST_F(ClangFormat, EmptyLineInInitializerList)
+{
+ insertLines({"Bar foo{a,",
+ "",
+ "};"});
+
+ indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("Bar foo{a,",
+ " ",
+ "};"));
+}
+
+TEST_F(ClangFormat, IndentClosingBraceAfterComma)
+{
+ insertLines({"Bar foo{a,",
+ "}"});
+
+ indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("Bar foo{a,",
+ " }"));
+}
+
+TEST_F(ClangFormat, DoNotIndentClosingBraceAfterSemicolon)
+{
+ insertLines({"{",
+ " a;"
+ "}"});
+
+ indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("{",
+ " a;"
+ "}"));
+}
+
+TEST_F(ClangFormat, SameIndentAfterSecondNewLineAfterIf)
+{
+ insertLines({"if (a)",
+ " ",
+ ""});
+
+ indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("if (a)",
+ " ",
+ " "));
+}
+
+TEST_F(ClangFormat, IndentAfterNewLineInsideIfWithFunctionCall)
+{
+ insertLines({"if (foo()",
+ ")"});
+
+ indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("if (foo()",
+ " )"));
+}
+
+TEST_F(ClangFormat, SameIndentAfterSecondNewLineInsideIfWithFunctionCall)
+{
+ insertLines({"if (foo()",
+ " ",
+ ")"});
+
+ indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("if (foo()",
+ " ",
+ " )"));
+}
+
+TEST_F(ClangFormat, SameIndentAfterSecondNonEmptyNewLineInsideIfWithFunctionCall)
+{
+ insertLines({"if (foo()",
+ " ",
+ "bar)"});
+
+ indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("if (foo()",
+ " ",
+ " bar)"));
+}
+
+TEST_F(ClangFormat, SameIndentsOnNewLinesAfterComments)
+{
+ insertLines({"namespace {} //comment",
+ "",
+ ""});
+
+ indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("namespace {} //comment",
+ "",
+ ""));
+}
+
+TEST_F(ClangFormat, IndentFunctionBodyButNotFormatBeforeIt)
{
insertLines({"int foo(int a, int b,",
" int c, int d",
@@ -375,8 +514,9 @@ TEST_F(ClangFormat, IndentFunctionBodyAndFormatBeforeIt)
extendedIndenter.indentBlock(doc.findBlockByNumber(3), QChar::Null, TextEditor::TabSettings());
- ASSERT_THAT(documentLines(), ElementsAre("int foo(int a, int b, int c, int d)",
- "{",
+ ASSERT_THAT(documentLines(), ElementsAre("int foo(int a, int b,",
+ " int c, int d",
+ " ) {",
" ",
"}"));
}
@@ -404,13 +544,11 @@ TEST_F(ClangFormat, ReformatToEmptyFunction)
insertLines({"int foo(int a, int b, int c, int d)",
"{",
" ",
- "}",
- ""});
+ "}"});
- extendedIndenter.indentBlock(doc.findBlockByNumber(4), QChar::Null, TextEditor::TabSettings());
+ extendedIndenter.indentBlock(doc.findBlockByNumber(3), '}', TextEditor::TabSettings());
- ASSERT_THAT(documentLines(), ElementsAre("int foo(int a, int b, int c, int d) {}",
- ""));
+ ASSERT_THAT(documentLines(), ElementsAre("int foo(int a, int b, int c, int d) {}"));
}
TEST_F(ClangFormat, ReformatToNonEmptyFunction)
@@ -421,13 +559,12 @@ TEST_F(ClangFormat, ReformatToNonEmptyFunction)
extendedIndenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
- ASSERT_THAT(documentLines(), ElementsAre("int foo(int a, int b)",
- "{",
+ ASSERT_THAT(documentLines(), ElementsAre("int foo(int a, int b) {",
" ",
"}"));
}
-TEST_F(ClangFormat, IndentIfBodyAndFormatBeforeIt)
+TEST_F(ClangFormat, IndentClosingScopeAndFormatBeforeIt)
{
insertLines({"if(a && b",
" &&c && d",
@@ -435,10 +572,9 @@ TEST_F(ClangFormat, IndentIfBodyAndFormatBeforeIt)
"",
"}"});
- extendedIndenter.indentBlock(doc.findBlockByNumber(3), QChar::Null, TextEditor::TabSettings());
+ extendedIndenter.indentBlock(doc.findBlockByNumber(4), '}', TextEditor::TabSettings());
ASSERT_THAT(documentLines(), ElementsAre("if (a && b && c && d) {",
- " ",
"}"));
}
@@ -496,7 +632,7 @@ TEST_F(ClangFormat, IndentAndFormatCompleteStatementOnClosingScope)
"}"));
}
-TEST_F(ClangFormat, IndentAndFormatWithEmptyLines)
+TEST_F(ClangFormat, OnlyIndentClosingParenthesis)
{
insertLines({"foo(a,",
" ",
@@ -505,7 +641,25 @@ TEST_F(ClangFormat, IndentAndFormatWithEmptyLines)
extendedIndenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
ASSERT_THAT(documentLines(), ElementsAre("foo(a,",
- "",
+ " ",
+ " )"));
+}
+
+TEST_F(ClangFormat, EquallyIndentInsideParenthesis)
+{
+ insertLines({"if (a",
+ ")"});
+ extendedIndenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+ auto linesAfterFirstLineBreak = documentLines();
+ insertLines({"if (a",
+ " ",
+ ")"});
+ extendedIndenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(linesAfterFirstLineBreak, ElementsAre("if (a",
+ " )"));
+ ASSERT_THAT(documentLines(), ElementsAre("if (a",
+ " ",
" )"));
}
@@ -623,4 +777,22 @@ TEST_F(ClangFormat, FormatTemplateparameters)
ASSERT_THAT(documentLines(), ElementsAre("using Alias = Template<A, B, C>"));
}
+TEST_F(ClangFormat, SortIncludes)
+{
+ insertLines({"#include \"b.h\"",
+ "#include \"a.h\"",
+ "",
+ "#include <bb.h>",
+ "#include <aa.h>"});
+
+ indenter.format({{1, 5}});
+
+ ASSERT_THAT(documentLines(), ElementsAre("#include \"a.h\"",
+ "#include \"b.h\"",
+ "",
+ "#include <aa.h>",
+ "#include <bb.h>"));
}
+// clang-format on
+
+} // namespace
diff --git a/tests/unit/unittest/commandlinebuilder-test.cpp b/tests/unit/unittest/commandlinebuilder-test.cpp
index a75c8d8a35..328b832b9c 100644
--- a/tests/unit/unittest/commandlinebuilder-test.cpp
+++ b/tests/unit/unittest/commandlinebuilder-test.cpp
@@ -139,6 +139,7 @@ TYPED_TEST(CommandLineBuilder, CHeader)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang",
+ "-w",
"-DNOMINMAX",
"-x",
"c-header",
@@ -156,6 +157,7 @@ TYPED_TEST(CommandLineBuilder, CSource)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang",
+ "-w",
"-DNOMINMAX",
"-x",
"c",
@@ -174,6 +176,7 @@ TYPED_TEST(CommandLineBuilder, ObjectiveCHeader)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang",
+ "-w",
"-DNOMINMAX",
"-x",
"objective-c-header",
@@ -192,6 +195,7 @@ TYPED_TEST(CommandLineBuilder, ObjectiveCSource)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang",
+ "-w",
"-DNOMINMAX",
"-x",
"objective-c",
@@ -209,6 +213,7 @@ TYPED_TEST(CommandLineBuilder, CppHeader)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -227,6 +232,7 @@ TYPED_TEST(CommandLineBuilder, CppSource)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++",
@@ -246,6 +252,7 @@ TYPED_TEST(CommandLineBuilder, ObjectiveCppHeader)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"objective-c++-header",
@@ -265,6 +272,7 @@ TYPED_TEST(CommandLineBuilder, ObjectiveCppSource)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"objective-c++",
@@ -498,6 +506,7 @@ TYPED_TEST(CommandLineBuilder, IncludesOrder)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -525,6 +534,7 @@ TYPED_TEST(CommandLineBuilder, EmptySourceFile)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -539,6 +549,7 @@ TYPED_TEST(CommandLineBuilder, SourceFile)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -555,6 +566,7 @@ TYPED_TEST(CommandLineBuilder, EmptyOutputFile)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -574,6 +586,7 @@ TYPED_TEST(CommandLineBuilder, OutputFile)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -596,6 +609,7 @@ TYPED_TEST(CommandLineBuilder, IncludePchPath)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -619,6 +633,7 @@ TYPED_TEST(CommandLineBuilder, CompilerMacros)
ASSERT_THAT(builder.commandLine,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
diff --git a/tests/unit/unittest/data/highlightingmarks.cpp b/tests/unit/unittest/data/highlightingmarks.cpp
index e1a48903ca..a703e89a11 100644
--- a/tests/unit/unittest/data/highlightingmarks.cpp
+++ b/tests/unit/unittest/data/highlightingmarks.cpp
@@ -686,3 +686,12 @@ class NonConstParameterConstructor
NonConstParameterConstructor bar(foo);
}
};
+
+class StaticMembersAccess
+{
+protected:
+ static int protectedValue;
+
+private:
+ static int privateValue;
+};
diff --git a/tests/unit/unittest/filepathstorage-test.cpp b/tests/unit/unittest/filepathstorage-test.cpp
index be689b44f3..c08c84e913 100644
--- a/tests/unit/unittest/filepathstorage-test.cpp
+++ b/tests/unit/unittest/filepathstorage-test.cpp
@@ -189,7 +189,8 @@ TEST_F(FilePathStorage, CallWriteForWriteDirectory)
TEST_F(FilePathStorage, CallWriteForWriteSource)
{
- EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("unknownfile.h")));
+ EXPECT_CALL(insertIntoSources,
+ write(TypedEq<int>(5), TypedEq<Utils::SmallStringView>("unknownfile.h")));
storage.writeSourceId(5, "unknownfile.h");
}
@@ -280,7 +281,8 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceIdForUnknownEntry)
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
valueReturnInt32(5, Eq("unknownfile.h")));
- EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("unknownfile.h")));
+ EXPECT_CALL(insertIntoSources,
+ write(TypedEq<int>(5), TypedEq<Utils::SmallStringView>("unknownfile.h")));
EXPECT_CALL(mockDatabase, commit());
storage.fetchSourceId(5, "unknownfile.h");
@@ -347,7 +349,8 @@ TEST_F(FilePathStorage, RestartFetchSourceIdIfTheDatabaseIsBusyInBeginBecauseThe
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
valueReturnInt32(5, Eq("otherunknownfile.h")));
- EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h")));
+ EXPECT_CALL(insertIntoSources,
+ write(TypedEq<int>(5), TypedEq<Utils::SmallStringView>("otherunknownfile.h")));
EXPECT_CALL(mockDatabase, commit());
storage.fetchSourceId(5, "otherunknownfile.h");
@@ -360,13 +363,16 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheDatabase
EXPECT_CALL(mockDatabase, deferredBegin());
EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
valueReturnInt32(5, Eq("otherunknownfile.h")));
- EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h")))
- .WillOnce(Throw(Sqlite::StatementIsBusy("busy")));;
+ 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,
valueReturnInt32(5, Eq("otherunknownfile.h")));
- EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h")));
+ EXPECT_CALL(insertIntoSources,
+ write(TypedEq<int>(5), TypedEq<Utils::SmallStringView>("otherunknownfile.h")));
EXPECT_CALL(mockDatabase, commit());
storage.fetchSourceId(5, "otherunknownfile.h");
@@ -379,12 +385,14 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheIndexIsC
EXPECT_CALL(mockDatabase,deferredBegin());
EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
valueReturnInt32(5, Eq("otherunknownfile.h")));
- EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h")))
- .WillOnce(Throw(Sqlite::ConstraintPreventsModification("busy")));;
+ EXPECT_CALL(insertIntoSources,
+ write(TypedEq<int>(5), TypedEq<Utils::SmallStringView>("otherunknownfile.h")))
+ .WillOnce(Throw(Sqlite::ConstraintPreventsModification("busy")));
EXPECT_CALL(mockDatabase, rollback());
EXPECT_CALL(mockDatabase,deferredBegin());
EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName,
- valueReturnInt32(5, Eq("otherunknownfile.h")));
+ valueReturnInt32(5, Eq("otherunknownfile.h")))
+ .WillOnce(Return(Utils::optional<int>(42)));
EXPECT_CALL(mockDatabase, commit());
storage.fetchSourceId(5, "otherunknownfile.h");
diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp
index 8427e79af8..2befb52417 100644
--- a/tests/unit/unittest/gtest-creator-printing.cpp
+++ b/tests/unit/unittest/gtest-creator-printing.cpp
@@ -45,7 +45,6 @@
#include <fulltokeninfo.h>
#include <includesearchpath.h>
#include <nativefilepath.h>
-#include <pchcreatorincludes.h>
#include <pchtask.h>
#include <precompiledheadersupdatedmessage.h>
#include <projectpartartefact.h>
@@ -1138,6 +1137,7 @@ const char* progressTypeToString(ClangBackEnd::ProgressType type)
case ProgressType::Invalid: return "Invalid";
case ProgressType::PrecompiledHeader: return "PrecompiledHeader";
case ProgressType::Indexing: return "Indexing";
+ case ProgressType::DependencyCreation: return "DependencyCreation";
}
return nullptr;
@@ -1150,11 +1150,6 @@ std::ostream &operator<<(std::ostream &out, const ProgressMessage &message)
<< message.total << ")";
}
-std::ostream &operator<<(std::ostream &out, const PchCreatorIncludes &includes)
-{
- return out << "(" << includes.includeIds << ", " << includes.topIncludeIds << ", "
- << includes.topSystemIncludeIds << ")";
-}
std::ostream &operator<<(std::ostream &out, const PchTask &task)
{
return out << "(" << task.projectPartIds << ", " << task.includes << ", " << task.compilerMacros
@@ -1171,11 +1166,11 @@ std::ostream &operator<<(std::ostream &out, const PchTaskSet &taskSet)
std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency)
{
return out << "(\n"
- << "includes: " << dependency.includes << ",\n"
- << "usedMacros: " << dependency.usedMacros << ",\n"
- << "fileStatuses: " << dependency.fileStatuses << ",\n"
- << "sourceFiles: " << dependency.sourceFiles << ",\n"
- << "sourceDependencies: " << dependency.sourceDependencies << ",\n"
+ << "includes: " << dependency.sources << ",\n"
+ << "usedMacros: " << dependency.usedMacros << ",\n"
+ << "fileStatuses: " << dependency.fileStatuses << ",\n"
+ << "sourceFiles: " << dependency.sourceFiles << ",\n"
+ << "sourceDependencies: " << dependency.sourceDependencies << ",\n"
<< ")";
}
@@ -1184,7 +1179,7 @@ std::ostream &operator<<(std::ostream &out, const SlotUsage &slotUsage)
return out << "(" << slotUsage.free << ", " << slotUsage.used << ")";
}
-const char *sourceTypeString(SourceType sourceType)
+const char *typeToString(SourceType sourceType)
{
using ClangBackEnd::SymbolTag;
@@ -1199,6 +1194,22 @@ const char *sourceTypeString(SourceType sourceType)
return "ProjectInclude";
case SourceType::UserInclude:
return "UserInclude";
+ case SourceType::Source:
+ return "Source";
+ }
+
+ return "";
+}
+
+const char *typeToString(HasMissingIncludes hasMissingIncludes)
+{
+ using ClangBackEnd::SymbolTag;
+
+ switch (hasMissingIncludes) {
+ case HasMissingIncludes::No:
+ return "HasMissingIncludes::No";
+ case HasMissingIncludes::Yes:
+ return "HasMissingIncludes::Yes";
}
return "";
@@ -1206,7 +1217,8 @@ const char *sourceTypeString(SourceType sourceType)
std::ostream &operator<<(std::ostream &out, const SourceEntry &entry)
{
- return out << "(" << entry.sourceId << ", " << sourceTypeString(entry.sourceType) << ")";
+ return out << "(" << entry.sourceId << ", " << typeToString(entry.sourceType) << ", "
+ << typeToString(entry.hasMissingIncludes) << ")";
}
const char *typeToString(IncludeSearchPathType type)
diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h
index cb63fd56bb..75eae281ae 100644
--- a/tests/unit/unittest/gtest-creator-printing.h
+++ b/tests/unit/unittest/gtest-creator-printing.h
@@ -186,7 +186,6 @@ class SuspendResumeJobsEntry;
class ReferencesResult;
class SymbolIndexerTask;
class ProgressMessage;
-class PchCreatorIncludes;
class PchTask;
class PchTaskSet;
class BuildDependency;
@@ -277,7 +276,6 @@ std::ostream &operator<<(std::ostream &os, const SuspendResumeJobsEntry &entry);
std::ostream &operator<<(std::ostream &os, const ReferencesResult &value);
std::ostream &operator<<(std::ostream &out, const SymbolIndexerTask &task);
std::ostream &operator<<(std::ostream &out, const ProgressMessage &message);
-std::ostream &operator<<(std::ostream &out, const PchCreatorIncludes &includes);
std::ostream &operator<<(std::ostream &out, const PchTask &task);
std::ostream &operator<<(std::ostream &out, const PchTaskSet &taskSet);
std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency);
diff --git a/tests/unit/unittest/mockbuilddependenciesstorage.h b/tests/unit/unittest/mockbuilddependenciesstorage.h
index a654579a83..739c13cf8d 100644
--- a/tests/unit/unittest/mockbuilddependenciesstorage.h
+++ b/tests/unit/unittest/mockbuilddependenciesstorage.h
@@ -32,19 +32,22 @@
class MockBuildDependenciesStorage : public ClangBackEnd::BuildDependenciesStorageInterface
{
public:
- MOCK_METHOD1(updateSources,
- void (const ClangBackEnd::SourceEntries &sources));
+ MOCK_METHOD2(insertOrUpdateSources,
+ void(const ClangBackEnd::SourceEntries &sources, int projectPartId));
MOCK_METHOD1(insertOrUpdateUsedMacros,
void (const ClangBackEnd::UsedMacros &usedMacros));
- MOCK_METHOD1(insertFileStatuses,
- void (const ClangBackEnd::FileStatuses &fileStatuses));
+ MOCK_METHOD1(insertOrUpdateFileStatuses, void(const ClangBackEnd::FileStatuses &fileStatuses));
MOCK_METHOD1(insertOrUpdateSourceDependencies,
void (const ClangBackEnd::SourceDependencies &sourceDependencies));
MOCK_CONST_METHOD1(fetchLowestLastModifiedTime,
long long (ClangBackEnd::FilePathId sourceId));
MOCK_CONST_METHOD2(fetchDependSources,
- ClangBackEnd::SourceEntries (ClangBackEnd::FilePathId sourceId, Utils::SmallStringView));
+ ClangBackEnd::SourceEntries(ClangBackEnd::FilePathId sourceId,
+ int projectPartId));
MOCK_CONST_METHOD1(fetchUsedMacros,
ClangBackEnd::UsedMacros (ClangBackEnd::FilePathId sourceId));
+ MOCK_METHOD1(fetchProjectPartId, int(Utils::SmallStringView projectPartName));
+ MOCK_METHOD2(updatePchCreationTimeStamp,
+ void(long long pchCreationTimeStamp, Utils::SmallStringView projectPartName));
};
diff --git a/tests/unit/unittest/mockprojectparts.h b/tests/unit/unittest/mockprojectparts.h
index 7c7a2daf4a..15ec023846 100644
--- a/tests/unit/unittest/mockprojectparts.h
+++ b/tests/unit/unittest/mockprojectparts.h
@@ -27,9 +27,9 @@
#include "googletest.h"
-#include <projectpartsinterface.h>
+#include <projectpartsmanagerinterface.h>
-class MockProjectParts : public ClangBackEnd::ProjectPartsInterface
+class MockProjectPartsManager : public ClangBackEnd::ProjectPartsManagerInterface
{
public:
MOCK_METHOD1(update,
diff --git a/tests/unit/unittest/mocksqlitedatabase.h b/tests/unit/unittest/mocksqlitedatabase.h
index 0b890e01f0..5bef2ba8c5 100644
--- a/tests/unit/unittest/mocksqlitedatabase.h
+++ b/tests/unit/unittest/mocksqlitedatabase.h
@@ -39,8 +39,8 @@
class MockSqliteDatabase : public MockSqliteTransactionBackend
{
public:
- using ReadStatement = MockSqliteReadStatement;
- using WriteStatement = MockSqliteWriteStatement;
+ using ReadStatement = NiceMock<MockSqliteReadStatement>;
+ using WriteStatement = NiceMock<MockSqliteWriteStatement>;
MOCK_METHOD1(execute,
void (Utils::SmallStringView sqlStatement));
diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp
index b9cecd4d1a..04d2a07c14 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.cpp
+++ b/tests/unit/unittest/mocksqlitereadstatement.cpp
@@ -186,9 +186,10 @@ MockSqliteReadStatement::value<SourceLocation, 3>(const long long &symbolId, con
return valueReturnSourceLocation(symbolId, locationKind);
}
-template <>
-SourceEntries
-MockSqliteReadStatement::values<SourceEntry, 3>(std::size_t reserveSize, const int &filePathId, const int &projectPartId)
+template<>
+SourceEntries MockSqliteReadStatement::values<SourceEntry, 4>(std::size_t reserveSize,
+ const int &filePathId,
+ const int &projectPartId)
{
return valuesReturnSourceEntries(reserveSize, filePathId, projectPartId);
}
diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h
index 43c88eb044..5c6fbdef77 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.h
+++ b/tests/unit/unittest/mocksqlitereadstatement.h
@@ -255,9 +255,10 @@ template <>
Utils::optional<SourceLocation>
MockSqliteReadStatement::value<SourceLocation, 3>(const long long &symbolId, const int &locationKind);
-template <>
-SourceEntries
-MockSqliteReadStatement::values<SourceEntry, 3>(std::size_t reserveSize, const int&, const int&);
+template<>
+SourceEntries MockSqliteReadStatement::values<SourceEntry, 4>(std::size_t reserveSize,
+ const int &,
+ const int &);
template <>
Utils::optional<Sources::SourceNameAndDirectoryId>
diff --git a/tests/unit/unittest/mocksqlitewritestatement.h b/tests/unit/unittest/mocksqlitewritestatement.h
index ee7df6362f..4b369845aa 100644
--- a/tests/unit/unittest/mocksqlitewritestatement.h
+++ b/tests/unit/unittest/mocksqlitewritestatement.h
@@ -42,8 +42,7 @@ public:
MOCK_METHOD0(execute,
void ());
- MOCK_METHOD2(bind,
- void (int index, Utils::SmallStringView value));
+ MOCK_METHOD2(bind, void(int, Utils::SmallStringView));
MOCK_METHOD2(bindValues,
void (Utils::SmallStringView, Utils::SmallStringView));
@@ -60,11 +59,11 @@ public:
MOCK_METHOD5(write,
void (long long, int, int, int, int));
- MOCK_METHOD2(write,
- void (uint, Utils::SmallStringView));
+ MOCK_METHOD2(write, void(uint, Utils::SmallStringView));
- MOCK_METHOD2(write,
- void (Utils::SmallStringView, Utils::SmallStringView));
+ MOCK_METHOD2(write, void(int, Utils::SmallStringView));
+
+ MOCK_METHOD2(write, void(Utils::SmallStringView, Utils::SmallStringView));
MOCK_METHOD3(write,
void (Utils::SmallStringView, Utils::SmallStringView, long long));
@@ -103,17 +102,16 @@ public:
MOCK_METHOD3(write,
void (uint, uint, uint));
- MOCK_METHOD4(write,
- void (int, off_t, time_t, bool));
+ MOCK_METHOD3(write, void(int, off_t, time_t));
MOCK_METHOD2(write,
void (uint, uint));
MOCK_METHOD2(write,
void (uchar, int));
-
+ MOCK_METHOD4(write, void(int, int, uchar, uchar));
MOCK_METHOD2(write,
void (long long, int));
-
+ MOCK_METHOD2(write, void(long long, Utils::SmallStringView));
Utils::SmallString sqlStatement;
};
diff --git a/tests/unit/unittest/mocksymbolstorage.h b/tests/unit/unittest/mocksymbolstorage.h
index 325e18b1c9..c4b55fcfe4 100644
--- a/tests/unit/unittest/mocksymbolstorage.h
+++ b/tests/unit/unittest/mocksymbolstorage.h
@@ -46,9 +46,6 @@ public:
Utils::Language language,
Utils::LanguageVersion languageVersion,
Utils::LanguageExtension languageExtension));
- MOCK_METHOD2(updateProjectPartSources,
- void(int projectPartId,
- const ClangBackEnd::FilePathIds &sourceFilePathIds));
MOCK_CONST_METHOD1(fetchProjectPartArtefact,
Utils::optional<ClangBackEnd::ProjectPartArtefact> (ClangBackEnd::FilePathId sourceId));
MOCK_CONST_METHOD1(fetchProjectPartArtefact,
diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp
index d891a08987..3dbafc8aa0 100644
--- a/tests/unit/unittest/pchcreator-test.cpp
+++ b/tests/unit/unittest/pchcreator-test.cpp
@@ -28,6 +28,7 @@
#include "fakeprocess.h"
#include "filesystem-utilities.h"
+#include "mockbuilddependenciesstorage.h"
#include "mockclangpathwatcher.h"
#include "mockpchmanagerclient.h"
#include "testenvironment.h"
@@ -97,16 +98,22 @@ protected:
FileContainer generatedFile{generatedFilePath.clone(), "#pragma once", {}};
NiceMock<MockPchManagerClient> mockPchManagerClient;
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
- ClangBackEnd::PchCreator creator{environment, database, mockPchManagerClient, mockClangPathWatcher};
+ NiceMock<MockBuildDependenciesStorage> mockBuildDependenciesStorage;
+ ClangBackEnd::PchCreator creator{environment,
+ database,
+ mockPchManagerClient,
+ mockClangPathWatcher,
+ mockBuildDependenciesStorage};
PchTask pchTask1{
"project1",
{id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
id(TESTDATA_DIR "/builddependencycollector/external/external2.h")},
- {id(generatedFilePath),
- id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
+ {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/external/external2.h"),
+ id(generatedFilePath),
+ id(main2Path)},
{},
{},
{},
@@ -134,6 +141,7 @@ TEST_F(PchCreator, CreateProjectPartClangCompilerArguments)
ASSERT_THAT(arguments,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -158,6 +166,7 @@ TEST_F(PchCreator, CreateProjectPartClangCompilerArgumentsWithSystemPch)
ASSERT_THAT(arguments,
ElementsAre("clang++",
+ "-w",
"-DNOMINMAX",
"-x",
"c++-header",
@@ -190,25 +199,24 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
creator.doInMainThreadAfterFinished();
}
-TEST_F(PchCreatorVerySlowTest, AllIncludesAreWatchedAfterSucess)
+TEST_F(PchCreatorVerySlowTest, SourcesAreWatchedAfterSucess)
{
creator.generatePch(std::move(pchTask1));
- EXPECT_CALL(
- mockClangPathWatcher,
- updateIdPaths(ElementsAre(
- AllOf(Field(&ClangBackEnd::IdPaths::id, "project1"),
- 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")))))));
+ EXPECT_CALL(mockClangPathWatcher,
+ updateIdPaths(ElementsAre(AllOf(
+ Field(&ClangBackEnd::IdPaths::id, "project1"),
+ 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();
}
-
-TEST_F(PchCreatorVerySlowTest, AllIncludesAreNotWatchedAfterFail)
+TEST_F(PchCreatorVerySlowTest, SourcesAreNotWatchedAfterFail)
{
pchTask1.systemIncludeSearchPaths = {};
pchTask1.projectIncludeSearchPaths = {};
@@ -222,6 +230,15 @@ TEST_F(PchCreatorVerySlowTest, AllIncludesAreNotWatchedAfterFail)
creator.doInMainThreadAfterFinished();
}
+TEST_F(PchCreatorVerySlowTest, PchCreationTimeStampsAreUpdated)
+{
+ creator.generatePch(std::move(pchTask1));
+
+ EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(_, Eq("project1")));
+
+ creator.doInMainThreadAfterFinished();
+}
+
TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForPchTask)
{
creator.generatePch(std::move(pchTask1));
@@ -241,6 +258,15 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchCleared)
ASSERT_THAT(creator.projectPartPch(), ClangBackEnd::ProjectPartPch{});
}
+TEST_F(PchCreatorVerySlowTest, SourcesCleared)
+{
+ creator.generatePch(std::move(pchTask1));
+
+ creator.clear();
+
+ ASSERT_THAT(creator.sources(), IsEmpty());
+}
+
TEST_F(PchCreatorVerySlowTest, ClangToolCleared)
{
creator.generatePch(std::move(pchTask1));
@@ -266,7 +292,7 @@ TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask
ASSERT_THAT(creator.projectPartPch(),
AllOf(Field(&ProjectPartPch::projectPartId, Eq("faultyProjectPart")),
Field(&ProjectPartPch::pchPath, IsEmpty()),
- Field(&ProjectPartPch::lastModified, Eq(-1))));
+ Field(&ProjectPartPch::lastModified, Gt(0))));
}
TEST_F(PchCreatorVerySlowTest, GeneratedFile)
diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp
index 5a2ca172c0..370667edc8 100644
--- a/tests/unit/unittest/pchmanagerserver-test.cpp
+++ b/tests/unit/unittest/pchmanagerserver-test.cpp
@@ -55,7 +55,7 @@ class PchManagerServer : public ::testing::Test
{
server.setClient(&mockPchManagerClient);
- ON_CALL(mockProjectParts, update(projectParts)).WillByDefault(Return(projectParts));
+ ON_CALL(mockProjectPartsManager, update(projectParts)).WillByDefault(Return(projectParts));
ON_CALL(mockGeneratedFiles, isValid()).WillByDefault(Return(true));
}
@@ -67,13 +67,15 @@ class PchManagerServer : public ::testing::Test
protected:
NiceMock<MockPchTaskGenerator> mockPchTaskGenerator;
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
- NiceMock<MockProjectParts> mockProjectParts;
+ NiceMock<MockProjectPartsManager> mockProjectPartsManager;
NiceMock<MockGeneratedFiles> mockGeneratedFiles;
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
- ClangBackEnd::PchManagerServer server{
- mockClangPathWatcher, mockPchTaskGenerator, mockProjectParts, mockGeneratedFiles};
+ ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
+ mockPchTaskGenerator,
+ mockProjectPartsManager,
+ mockGeneratedFiles};
NiceMock<MockPchManagerClient> mockPchManagerClient;
SmallString projectPartId1 = "project1";
SmallString projectPartId2 = "project2";
@@ -117,7 +119,7 @@ TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue)
{
InSequence s;
- EXPECT_CALL(mockProjectParts, update(updateProjectPartsMessage.projectsParts))
+ EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts))
.WillOnce(Return(projectParts2));
EXPECT_CALL(
mockPchTaskGenerator, addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument")));
@@ -152,7 +154,7 @@ TEST_F(PchManagerServer, RemoveIncludesFromFileWatcher)
TEST_F(PchManagerServer, RemoveProjectPartsFromProjectParts)
{
- EXPECT_CALL(mockProjectParts, remove(removeProjectPartsMessage.projectsPartIds));
+ EXPECT_CALL(mockProjectPartsManager, remove(removeProjectPartsMessage.projectsPartIds));
server.removeProjectParts(removeProjectPartsMessage.clone());
}
@@ -161,7 +163,10 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier)
{
EXPECT_CALL(mockClangPathWatcher, setNotifier(_));
- ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchTaskGenerator, mockProjectParts, mockGeneratedFiles};
+ ClangBackEnd::PchManagerServer server{mockClangPathWatcher,
+ mockPchTaskGenerator,
+ mockProjectPartsManager,
+ mockGeneratedFiles};
}
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
@@ -169,8 +174,8 @@ TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
server.updateProjectParts(
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
- EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId)))
- .WillOnce(Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart1}}));
+ EXPECT_CALL(mockProjectPartsManager, projects(ElementsAre(projectPart1.projectPartId)))
+ .WillOnce(Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart1}}));
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(ElementsAre(projectPart1), ElementsAre("toolChainArgument")));
server.pathsWithIdsChanged({projectPartId1});
@@ -213,11 +218,11 @@ TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid)
{
InSequence s;
- EXPECT_CALL(mockProjectParts, update(ElementsAre(projectPart1)))
+ EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1)))
.WillOnce(Return(ProjectPartContainers{projectPart1}));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(false));
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
- EXPECT_CALL(mockProjectParts, updateDeferred(ElementsAre(projectPart1)));
+ EXPECT_CALL(mockProjectPartsManager, updateDeferred(ElementsAre(projectPart1)));
server.updateProjectParts(
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
@@ -227,11 +232,11 @@ TEST_F(PchManagerServer, GeneratePchIfGeneratedFilesAreValid)
{
InSequence s;
- EXPECT_CALL(mockProjectParts, update(ElementsAre(projectPart1)))
+ EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1)))
.WillOnce(Return(ProjectPartContainers{projectPart1}));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(true));
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _));
- EXPECT_CALL(mockProjectParts, updateDeferred(_)).Times(0);
+ EXPECT_CALL(mockProjectPartsManager, updateDeferred(_)).Times(0);
server.updateProjectParts(
ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
@@ -247,7 +252,7 @@ TEST_F(PchManagerServer, AfterUpdatingGeneratedFilesAreValidSoGeneratePchs)
EXPECT_CALL(mockGeneratedFiles, update(updateGeneratedFilesMessage.generatedFiles));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(true));
- EXPECT_CALL(mockProjectParts, deferredUpdates())
+ EXPECT_CALL(mockProjectPartsManager, deferredUpdates())
.WillOnce(Return(ClangBackEnd::ProjectPartContainers{projectPart1}));
EXPECT_CALL(mockPchTaskGenerator,
addProjectParts(ElementsAre(projectPart1), ElementsAre("toolChainArgument")));
@@ -265,7 +270,7 @@ TEST_F(PchManagerServer, AfterUpdatingGeneratedFilesAreStillInvalidSoNoPchsGener
EXPECT_CALL(mockGeneratedFiles, update(updateGeneratedFilesMessage.generatedFiles));
EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(false));
- EXPECT_CALL(mockProjectParts, deferredUpdates()).Times(0);
+ EXPECT_CALL(mockProjectPartsManager, deferredUpdates()).Times(0);
EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
server.updateGeneratedFiles(updateGeneratedFilesMessage.clone());
diff --git a/tests/unit/unittest/pchtaskgenerator-test.cpp b/tests/unit/unittest/pchtaskgenerator-test.cpp
index d85432baf2..a6946f7ccf 100644
--- a/tests/unit/unittest/pchtaskgenerator-test.cpp
+++ b/tests/unit/unittest/pchtaskgenerator-test.cpp
@@ -99,7 +99,7 @@ TEST_F(PchTaskGenerator, AddProjectParts)
Field(&PchTaskSet::system,
AllOf(Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
Field(&PchTask::includes, ElementsAre(5)),
- Field(&PchTask::allIncludes, IsEmpty()),
+ Field(&PchTask::sources, IsEmpty()),
Field(&PchTask::compilerMacros,
ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})),
Field(&PchTask::systemIncludeSearchPaths,
@@ -116,7 +116,7 @@ TEST_F(PchTaskGenerator, AddProjectParts)
&PchTaskSet::project,
AllOf(Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
Field(&PchTask::includes, ElementsAre(3)),
- Field(&PchTask::allIncludes, ElementsAre(1, 2, 3, 4, 5)),
+ Field(&PchTask::sources, ElementsAre(1, 2, 3, 4, 5)),
Field(&PchTask::compilerMacros,
ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})),
Field(&PchTask::systemIncludeSearchPaths,
diff --git a/tests/unit/unittest/pchtasksmerger-test.cpp b/tests/unit/unittest/pchtasksmerger-test.cpp
index c279da505e..da61d14adb 100644
--- a/tests/unit/unittest/pchtasksmerger-test.cpp
+++ b/tests/unit/unittest/pchtasksmerger-test.cpp
@@ -272,14 +272,14 @@ TEST_F(PchTasksMerger, MergeAllIncludes)
{
Merger::mergePchTasks(systemTask1, systemTask2);
- ASSERT_THAT(systemTask1.allIncludes, ElementsAre(1, 2, 3, 11, 12, 13));
+ ASSERT_THAT(systemTask1.sources, ElementsAre(1, 2, 3, 11, 12, 13));
}
TEST_F(PchTasksMerger, DontAllMergeIncludes)
{
Merger::mergePchTasks(systemTask1, systemTask3);
- ASSERT_THAT(systemTask1.allIncludes, ElementsAre(1, 2, 3));
+ ASSERT_THAT(systemTask1.sources, ElementsAre(1, 2, 3));
}
TEST_F(PchTasksMerger, MergeProjectIds)
diff --git a/tests/unit/unittest/projectparts-test.cpp b/tests/unit/unittest/projectparts-test.cpp
index 8ab342b2f1..16f1ef0988 100644
--- a/tests/unit/unittest/projectparts-test.cpp
+++ b/tests/unit/unittest/projectparts-test.cpp
@@ -25,7 +25,7 @@
#include "googletest.h"
-#include <projectparts.h>
+#include <projectpartsmanager.h>
#include <projectpartcontainer.h>
@@ -41,7 +41,7 @@ using ClangBackEnd::FilePathId;
class ProjectParts : public testing::Test
{
protected:
- ClangBackEnd::ProjectParts projectParts;
+ ClangBackEnd::ProjectPartsManager projectParts;
FilePathId firstHeader{1};
FilePathId secondHeader{2};
FilePathId firstSource{11};
diff --git a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
index 7e1e730b17..ebd67dccba 100644
--- a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
+++ b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
@@ -102,7 +102,10 @@ TEST_F(RefactoringDatabaseInitializer, AddProjectPartsSourcesTable)
{
InSequence s;
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsSources(projectPartId INTEGER, sourceId INTEGER, sourceType INTEGER)")));
+ EXPECT_CALL(mockDatabase,
+ execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsSources(projectPartId INTEGER, "
+ "sourceId INTEGER, sourceType INTEGER, pchCreationTimeStamp INTEGER, "
+ "hasMissingIncludes INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsSources_sourceId_projectPartId ON projectPartsSources(sourceId, projectPartId)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsSources_projectPartId ON projectPartsSources(projectPartId)")));
@@ -124,7 +127,11 @@ TEST_F(RefactoringDatabaseInitializer, AddFileStatusesTable)
{
InSequence s;
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, lastModified INTEGER, buildDependencyTimeStamp INTEGER, isInPrecompiledHeader INTEGER)")));
+ EXPECT_CALL(
+ mockDatabase,
+ execute(Eq(
+ "CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, "
+ "lastModified INTEGER)")));
initializer.createFileStatusesTable();
}
@@ -171,13 +178,20 @@ TEST_F(RefactoringDatabaseInitializer, CreateInTheContructor)
"TEXT, systemIncludeSearchPaths TEXT, projectIncludeSearchPaths TEXT, "
"language INTEGER, languageVersion INTEGER, languageExtension INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)")));
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsSources(projectPartId INTEGER, sourceId INTEGER, sourceType INTEGER)")));
+ EXPECT_CALL(mockDatabase,
+ execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsSources(projectPartId INTEGER, "
+ "sourceId INTEGER, sourceType INTEGER, pchCreationTimeStamp INTEGER, "
+ "hasMissingIncludes INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsSources_sourceId_projectPartId ON projectPartsSources(sourceId, projectPartId)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsSources_projectPartId ON projectPartsSources(projectPartId)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS usedMacros(usedMacroId INTEGER PRIMARY KEY, sourceId INTEGER, macroName TEXT)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_sourceId_macroName ON usedMacros(sourceId, macroName)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_macroName ON usedMacros(macroName)")));
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, lastModified INTEGER, buildDependencyTimeStamp INTEGER, isInPrecompiledHeader INTEGER)")));
+ EXPECT_CALL(
+ mockDatabase,
+ execute(Eq(
+ "CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, "
+ "lastModified INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, dependencySourceId INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON sourceDependencies(sourceId, dependencySourceId)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS precompiledHeaders(projectPartId INTEGER PRIMARY KEY, projectPchPath TEXT, projectPchBuildTime INTEGER, systemPchPath TEXT, systemPchBuildTime INTEGER)")));
@@ -215,7 +229,10 @@ TEST_F(RefactoringDatabaseInitializer, DontCreateIfAlreadyInitialized)
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS usedMacros(usedMacroId INTEGER PRIMARY KEY, sourceId INTEGER, macroName TEXT)"))).Times(0);
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_sourceId_macroName ON usedMacros(sourceId, macroName)"))).Times(0);
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_macroName ON usedMacros(macroName)"))).Times(0);
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, lastModified INTEGER, isInPrecompiledHeader INTEGER)"))).Times(0);
+ EXPECT_CALL(mockDatabase,
+ execute(Eq("CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, "
+ "size INTEGER, lastModified INTEGER, isInPrecompiledHeader INTEGER)")))
+ .Times(0);
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, dependencySourceId INTEGER)"))).Times(0);
EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON sourceDependencies(sourceId, dependencySourceId)"))).Times(0);
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS precompiledHeaders(projectPartId INTEGER PRIMARY KEY, pchPath TEXT, pchBuildTime INTEGER)"))).Times(0);
diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp
index eecd388f02..ea015bdee6 100644
--- a/tests/unit/unittest/symbolindexer-test.cpp
+++ b/tests/unit/unittest/symbolindexer-test.cpp
@@ -73,13 +73,6 @@ using ClangBackEnd::SourceLocationKind;
using ClangBackEnd::UsedMacros;
using OptionalProjectPartArtefact = Utils::optional<ClangBackEnd::ProjectPartArtefact>;
-MATCHER_P(IsFileId, fileNameId,
- std::string(negation ? "isn't " : "is ")
- + PrintToString(ClangBackEnd::FilePathId(fileNameId)))
-{
- return arg == ClangBackEnd::FilePathId(fileNameId);
-}
-
struct Data
{
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
@@ -211,7 +204,7 @@ protected:
SourceLocationEntries sourceLocations{{1, 1, {42, 23}, SourceLocationKind::Declaration}};
FilePathIds sourceFileIds{1, 23};
UsedMacros usedMacros{{"Foo", 1}};
- FileStatuses fileStatus{{2, 3, 4, false}};
+ FileStatuses fileStatus{{2, 3, 4}};
SourceDependencies sourceDependencies{{1, 2}, {1, 3}};
Utils::SmallString systemIncludeSearchPathsText{
R"([["/includes", 1, 2], [")" TESTDATA_DIR R"(" ,2 , 3], ["/other/includes", 3, 3]])"};
@@ -269,6 +262,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector)
EXPECT_CALL(mockCollector,
setFile(main1PathId,
ElementsAre("clang++",
+ "-w",
"-Wno-pragma-once-outside-header",
"-DNOMINMAX",
"-x",
@@ -301,6 +295,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInColl
EXPECT_CALL(mockCollector,
setFile(main1PathId,
ElementsAre("clang++",
+ "-w",
"-Wno-pragma-once-outside-header",
"-DNOMINMAX",
"-x",
@@ -335,6 +330,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithoutPrecompiledHeaderInC
EXPECT_CALL(mockCollector,
setFile(main1PathId,
ElementsAre("clang++",
+ "-w",
"-Wno-pragma-once-outside-header",
"-DNOMINMAX",
"-x",
@@ -442,26 +438,6 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartsInStorage)
indexer.updateProjectParts({projectPart1, projectPart2});
}
-TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSourcesWithArtifact)
-{
- ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>("project1"))).WillByDefault(Return(artefact));
- ON_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project1"), _, _, _, _, _, _, _)).WillByDefault(Return(-1));
-
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(_, _));
-
- indexer.updateProjectParts({projectPart1});
-}
-
-TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSourcesWithoutArtifact)
-{
- ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>("project2"))).WillByDefault(Return(nullArtefact));
- ON_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project2"), _, _, _, _, _, _, _)).WillByDefault(Return(3));
-
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(3, ElementsAre(IsFileId(1), IsFileId(23))));
-
- indexer.updateProjectParts({projectPart2});
-}
-
TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertOrUpdateUsedMacros)
{
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(usedMacros)))
@@ -472,7 +448,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertOrUpdateUsedMacros)
TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertFileStatuses)
{
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatus)))
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatus)))
.Times(2);
indexer.updateProjectParts({projectPart1, projectPart2});
@@ -516,6 +492,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithoutProjectPartArtifact)
EXPECT_CALL(mockCollector,
setFile(main1PathId,
ElementsAre("clang++",
+ "-w",
"-Wno-pragma-once-outside-header",
"-DNOMINMAX",
"-x",
@@ -538,9 +515,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithoutProjectPartArtifact)
EXPECT_CALL(mockCollector, collectSymbols());
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(TypedEq<int>(12), Eq(sourceFileIds)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(usedMacros)));
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatus)));
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatus)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies)));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
@@ -569,6 +545,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithProjectPartArtifact)
EXPECT_CALL(mockCollector,
setFile(Eq(main1PathId),
ElementsAre("clang++",
+ "-w",
"-Wno-pragma-once-outside-header",
"-DNOMINMAX",
"-x",
@@ -591,9 +568,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithProjectPartArtifact)
EXPECT_CALL(mockCollector, collectSymbols());
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(TypedEq<int>(artefact.projectPartId), Eq(sourceFileIds)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(usedMacros)));
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatus)));
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatus)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies)));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
@@ -624,6 +600,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderButGetsAnErrorForCollectingS
EXPECT_CALL(mockCollector,
setFile(main1PathId,
ElementsAre("clang++",
+ "-w",
"-Wno-pragma-once-outside-header",
"-DNOMINMAX",
"-x",
@@ -646,9 +623,8 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderButGetsAnErrorForCollectingS
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0);
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(TypedEq<int>(12), Eq(sourceFileIds))).Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(usedMacros))).Times(0);
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatus))).Times(0);
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatus))).Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies)))
.Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
@@ -689,6 +665,7 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder)
EXPECT_CALL(mockCollector,
setFile(Eq(sourceFileIds[0]),
ElementsAre("clang++",
+ "-w",
"-DFOO",
"-DNOMINMAX",
"-x",
@@ -711,9 +688,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder)
EXPECT_CALL(mockCollector, collectSymbols());
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(artefact.projectPartId, Eq(sourceFileIds)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(usedMacros)));
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatus)));
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatus)));
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies)));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
@@ -732,9 +708,8 @@ TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath)
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0);
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _)).Times(0);
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(An<int>(), _)).Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(_)).Times(0);
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(_)).Times(0);
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(_)).Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(_)).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
@@ -753,6 +728,7 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrderButGetsAnErrorForCollectingSy
EXPECT_CALL(mockCollector,
setFile(Eq(sourceFileIds[0]),
ElementsAre("clang++",
+ "-w",
"-DFOO",
"-DNOMINMAX",
"-x",
@@ -775,10 +751,8 @@ TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrderButGetsAnErrorForCollectingSy
EXPECT_CALL(mockCollector, collectSymbols()).WillOnce(Return(false));
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0);
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(0);
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(artefact.projectPartId, Eq(sourceFileIds)))
- .Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(Eq(usedMacros))).Times(0);
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(Eq(fileStatus))).Times(0);
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(Eq(fileStatus))).Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies)))
.Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
@@ -797,6 +771,7 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader)
EXPECT_CALL(mockCollector,
setFile(Eq(sourceFileIds[0]),
ElementsAre("clang++",
+ "-w",
"-DFOO",
"-DNOMINMAX",
"-x",
@@ -833,6 +808,7 @@ TEST_F(SymbolIndexer, UpdateChangedPathIsNotUsingPrecompiledHeaderIfItNotExists)
EXPECT_CALL(mockCollector,
setFile(Eq(sourceFileIds[0]),
ElementsAre("clang++",
+ "-w",
"-DFOO",
"-DNOMINMAX",
"-x",
@@ -950,9 +926,8 @@ TEST_F(SymbolIndexer, DontReparseInUpdateProjectPartsIfDefinesAreTheSame)
EXPECT_CALL(mockCollector, collectSymbols()).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0);
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _)).Times(0);
- EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(An<int>(), _)).Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateUsedMacros(_)).Times(0);
- EXPECT_CALL(mockBuildDependenciesStorage, insertFileStatuses(_)).Times(0);
+ EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateFileStatuses(_)).Times(0);
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateSourceDependencies(_)).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0);
diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp
index 2d7025373f..48e4420dc1 100644
--- a/tests/unit/unittest/symbolscollector-test.cpp
+++ b/tests/unit/unittest/symbolscollector-test.cpp
@@ -147,7 +147,7 @@ protected:
ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const
{
- return {filePathId(filePath), fileSize(filePath), lastModified(filePath), false};
+ return {filePathId(filePath), fileSize(filePath), lastModified(filePath)};
}
SymbolIndex symbolId(const Utils::SmallString &symbolName)
diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp
index f9a3d0a7de..ddd7136252 100644
--- a/tests/unit/unittest/symbolstorage-test.cpp
+++ b/tests/unit/unittest/symbolstorage-test.cpp
@@ -70,8 +70,6 @@ protected:
MockSqliteWriteStatement &deleteNewLocationsTableStatement = storage.m_deleteNewLocationsTableStatement;
MockSqliteWriteStatement &insertOrUpdateProjectPartStatement = storage.m_insertOrUpdateProjectPartStatement;
MockSqliteReadStatement &getProjectPartIdStatement = storage.m_getProjectPartIdStatement;
- MockSqliteWriteStatement &deleteAllProjectPartsSourcesWithProjectPartIdStatement = storage.m_deleteAllProjectPartsSourcesWithProjectPartIdStatement;
- MockSqliteWriteStatement &insertProjectPartSourcesStatement = storage.m_insertProjectPartSourcesStatement;
MockSqliteReadStatement &getProjectPartArtefactsBySourceId = storage.m_getProjectPartArtefactsBySourceId;
MockSqliteReadStatement &getProjectPartArtefactsByProjectPartName = storage.m_getProjectPartArtefactsByProjectPartName;
@@ -212,18 +210,6 @@ TEST_F(SymbolStorage, InsertOrUpdateProjectPart)
Utils::LanguageExtension::None);
}
-
-TEST_F(SymbolStorage, UpdateProjectPartSources)
-{
- InSequence sequence;
-
- EXPECT_CALL(deleteAllProjectPartsSourcesWithProjectPartIdStatement, write(TypedEq<int>(42)));
- EXPECT_CALL(insertProjectPartSourcesStatement, write(TypedEq<int>(42), TypedEq<int>(1)));
- EXPECT_CALL(insertProjectPartSourcesStatement, write(TypedEq<int>(42), TypedEq<int>(2)));
-
- storage.updateProjectPartSources(42, {1, 2});
-}
-
TEST_F(SymbolStorage, FetchProjectPartArtefactBySourceIdCallsValueInStatement)
{
EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp
index 3383c9a3b9..8d79bc95cb 100644
--- a/tests/unit/unittest/tokenprocessor-test.cpp
+++ b/tests/unit/unittest/tokenprocessor-test.cpp
@@ -1704,6 +1704,24 @@ TEST_F(TokenProcessor, LambdaLocalVariableCapture)
ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::LocalVariable));
}
+TEST_F(TokenProcessor, StaticProtectedMember)
+{
+ const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(693, 31));
+
+ ClangBackEnd::TokenInfoContainer container(infos[2]);
+
+ ASSERT_THAT(container.extraInfo.accessSpecifier, ClangBackEnd::AccessSpecifier::Protected);
+}
+
+TEST_F(TokenProcessor, StaticPrivateMember)
+{
+ const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(696, 29));
+
+ ClangBackEnd::TokenInfoContainer container(infos[2]);
+
+ ASSERT_THAT(container.extraInfo.accessSpecifier, ClangBackEnd::AccessSpecifier::Private);
+}
+
Data *TokenProcessor::d;
void TokenProcessor::SetUpTestCase()
diff --git a/tests/unit/unittest/usedmacrocollector-test.cpp b/tests/unit/unittest/usedmacrocollector-test.cpp
index 61f7fcd99b..31aa4fab38 100644
--- a/tests/unit/unittest/usedmacrocollector-test.cpp
+++ b/tests/unit/unittest/usedmacrocollector-test.cpp
@@ -68,7 +68,7 @@ protected:
ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const
{
- return {filePathId(filePath), fileSize(filePath), lastModified(filePath), false};
+ return {filePathId(filePath), fileSize(filePath), lastModified(filePath)};
}
protected:
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
diff --git a/tests/unit/unittest/usedmacrofilter-test.cpp b/tests/unit/unittest/usedmacrofilter-test.cpp
index bdde5417af..788a443eee 100644
--- a/tests/unit/unittest/usedmacrofilter-test.cpp
+++ b/tests/unit/unittest/usedmacrofilter-test.cpp
@@ -41,11 +41,13 @@ using ClangBackEnd::CompilerMacros;
class UsedMacroFilter : public testing::Test
{
protected:
- SourceEntries includes{{1, SourceType::UserInclude, 0},
- {2, SourceType::SystemInclude, 0},
- {3, SourceType::ProjectInclude, 0},
- {4, SourceType::TopSystemInclude, 0},
- {5, SourceType::TopProjectInclude, 0}};
+ SourceEntries sources{{1, SourceType::UserInclude, 0},
+ {2, SourceType::SystemInclude, 0},
+ {3, SourceType::ProjectInclude, 0},
+ {4, SourceType::TopSystemInclude, 0},
+ {5, SourceType::TopProjectInclude, 0},
+ {6, SourceType::Source, 0},
+ {7, SourceType::TopProjectInclude, 0, ClangBackEnd::HasMissingIncludes::Yes}};
UsedMacros usedMacros{{"YI", 1},
{"ER", 2},
{"SE", 2},
@@ -65,57 +67,62 @@ protected:
TEST_F(UsedMacroFilter, SystemIncludes)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.systemIncludes, ElementsAre(FilePathId{2}, FilePathId{4}));
}
TEST_F(UsedMacroFilter, ProjectIncludes)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.projectIncludes, ElementsAre(FilePathId{3}, FilePathId{5}));
}
TEST_F(UsedMacroFilter, TopSystemIncludes)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.topSystemIncludes, ElementsAre(FilePathId{4}));
}
TEST_F(UsedMacroFilter, TopProjectIncludes)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.topProjectIncludes, ElementsAre(FilePathId{5}));
}
-TEST_F(UsedMacroFilter, AllIncludes)
+TEST_F(UsedMacroFilter, Sources)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
-
- ASSERT_THAT(filter.allIncludes,
- ElementsAre(FilePathId{1}, FilePathId{2}, FilePathId{3}, FilePathId{4}, FilePathId{5}));
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
+
+ ASSERT_THAT(filter.sources,
+ ElementsAre(FilePathId{1},
+ FilePathId{2},
+ FilePathId{3},
+ FilePathId{4},
+ FilePathId{5},
+ FilePathId{6}));
}
TEST_F(UsedMacroFilter, SystemUsedMacros)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.systemUsedMacros, ElementsAre("ER", "SE", "LIU"));
}
TEST_F(UsedMacroFilter, ProjectUsedMacros)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.projectUsedMacros, ElementsAre("QI", "WU", "SAN"));
}
TEST_F(UsedMacroFilter, SystemCompileMacros)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.systemCompilerMacros,
ElementsAre(CompilerMacro{"ER", "2", 2},
@@ -125,7 +132,7 @@ TEST_F(UsedMacroFilter, SystemCompileMacros)
TEST_F(UsedMacroFilter, ProjectCompileMacros)
{
- ClangBackEnd::UsedMacroFilter filter(includes, usedMacros, compileMacros);
+ ClangBackEnd::UsedMacroFilter filter(sources, usedMacros, compileMacros);
ASSERT_THAT(filter.projectCompilerMacros,
ElementsAre(CompilerMacro{"QI"},