diff --git a/dist/changes-4.10.0.md b/dist/changes-4.10.0.md index f97a83a472d..9a03649d44f 100644 --- a/dist/changes-4.10.0.md +++ b/dist/changes-4.10.0.md @@ -16,6 +16,7 @@ you can check out from the public Git repository. For example: ### Language Client +* Removed `Experimental` flag * Added option for starting server when needed * Added option for starting one server per project * Added support for `workspace/workspaceFolders` server request @@ -34,7 +35,7 @@ you can check out from the public Git repository. For example: * Added option for hiding kit settings (QTCREATORBUG-9134) * Added support for drag & drop in Projects tree (QTCREATORBUG-6446) * Added option for closing files of project when closing project (QTCREATORBUG-22198) -* Added filtering to `Application Output`, `Compile Output`, and `General Messages` +* Added filtering to `Issues`, `Application Output`, `Compile Output`, and `General Messages` (QTCREATORBUG-16356) * Added `Re-detect` and `Remove All` to compiler settings * Added Locator filter for all files in all project directory trees (`a`) (QTCREATORBUG-19122) @@ -59,6 +60,7 @@ you can check out from the public Git repository. For example: * Added completion of paths in project files (QTCREATORBUG-5915) * Added forced `qmake` run on rebuild * Fixed building sub-project in case of additional custom make steps (QTCREATORBUG-15794) +* Fixed missing items from `OBJECTIVE_HEADERS` (QTCREATORBUG-17569) ## CMake Projects @@ -102,9 +104,12 @@ you can check out from the public Git repository. For example: ## QML Support +* Fixed various formatting issues + ## Debugging * Added pretty printer for `QMargin` +* Fixed issues with restoring layout (QTCREATORBUG-21669) ### CDB @@ -120,7 +125,10 @@ you can check out from the public Git repository. For example: * Added support for `ShapeGradient` (QDS-359) * Added gradient picker that allows loading and saving of presets +* Added support for changing properties for multiple items at once (QDS-324) +* Added missing properties for `LineEdit` and `ComboBox` * Updated properties of `Flickable` +* Improved handling of errors in state editor (QDS-695) ## Version Control Systems @@ -191,13 +199,16 @@ Denis Shienkov Denis Vygovskiy Eike Ziller Friedemann Kleint +Giuseppe D'Angelo Haxor Leet +Henning Gruendl illiteratecoder Ivan Donchevskii Ivan Komissarov Joel Smith Jörg Bornemann Kavindra Palaraja +Leena Miettinen Luca Carlon Marco Bubke Martin Haase @@ -213,5 +224,6 @@ Tim Henning Tim Jenssen Tobias Hunger Tor Arne Vestbø +Uladzislau Paulovich Ulf Hermann Ville Nummela diff --git a/doc/images/qtcreator-application-output.png b/doc/images/qtcreator-application-output.png index 05f76b380d3..23250da4852 100644 Binary files a/doc/images/qtcreator-application-output.png and b/doc/images/qtcreator-application-output.png differ diff --git a/doc/images/qtcreator-build-issues.png b/doc/images/qtcreator-build-issues.png deleted file mode 100644 index 85c42782b3b..00000000000 Binary files a/doc/images/qtcreator-build-issues.png and /dev/null differ diff --git a/doc/images/qtcreator-compile-output.png b/doc/images/qtcreator-compile-output.png new file mode 100644 index 00000000000..3807bf345d8 Binary files /dev/null and b/doc/images/qtcreator-compile-output.png differ diff --git a/doc/images/qtcreator-compile-pane.png b/doc/images/qtcreator-compile-pane.png deleted file mode 100644 index e7af4fe5e80..00000000000 Binary files a/doc/images/qtcreator-compile-pane.png and /dev/null differ diff --git a/doc/images/qtcreator-context-sensitive-help.png b/doc/images/qtcreator-context-sensitive-help.png index d26b14469de..fb5720bb4af 100644 Binary files a/doc/images/qtcreator-context-sensitive-help.png and b/doc/images/qtcreator-context-sensitive-help.png differ diff --git a/doc/images/qtcreator-general-messages.png b/doc/images/qtcreator-general-messages.png new file mode 100644 index 00000000000..143a28c8766 Binary files /dev/null and b/doc/images/qtcreator-general-messages.png differ diff --git a/doc/images/qtcreator-help-add-bookmark-dlg.png b/doc/images/qtcreator-help-add-bookmark-dlg.png index 998060a81fd..bec770fe986 100644 Binary files a/doc/images/qtcreator-help-add-bookmark-dlg.png and b/doc/images/qtcreator-help-add-bookmark-dlg.png differ diff --git a/doc/images/qtcreator-help-filter-attributes.png b/doc/images/qtcreator-help-filter-attributes.png index 2ca849a6009..9c290d9dd0a 100644 Binary files a/doc/images/qtcreator-help-filter-attributes.png and b/doc/images/qtcreator-help-filter-attributes.png differ diff --git a/doc/images/qtcreator-help-filters.png b/doc/images/qtcreator-help-filters.png index 38fd932e9a7..2763f736c8f 100644 Binary files a/doc/images/qtcreator-help-filters.png and b/doc/images/qtcreator-help-filters.png differ diff --git a/doc/images/qtcreator-help-options.png b/doc/images/qtcreator-help-options.png new file mode 100644 index 00000000000..63c34700b51 Binary files /dev/null and b/doc/images/qtcreator-help-options.png differ diff --git a/doc/images/qtcreator-help-search.png b/doc/images/qtcreator-help-search.png index 14ece95700b..ca29bd6593f 100644 Binary files a/doc/images/qtcreator-help-search.png and b/doc/images/qtcreator-help-search.png differ diff --git a/doc/images/qtcreator-issues.png b/doc/images/qtcreator-issues.png new file mode 100644 index 00000000000..b0bde84e455 Binary files /dev/null and b/doc/images/qtcreator-issues.png differ diff --git a/doc/images/qtcreator-language-client-options.png b/doc/images/qtcreator-language-client-options.png index fef98897485..ab1a0e09d37 100644 Binary files a/doc/images/qtcreator-language-client-options.png and b/doc/images/qtcreator-language-client-options.png differ diff --git a/doc/images/qtcreator-task-pane.png b/doc/images/qtcreator-task-pane.png deleted file mode 100644 index b2207514005..00000000000 Binary files a/doc/images/qtcreator-task-pane.png and /dev/null differ diff --git a/doc/src/editors/creator-coding.qdoc b/doc/src/editors/creator-coding.qdoc index b897961996b..11990f46185 100644 --- a/doc/src/editors/creator-coding.qdoc +++ b/doc/src/editors/creator-coding.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -93,10 +93,10 @@ \li \l{Using Language Servers} - The experimental language client provides code completion, - highlighting of the symbol under cursor, and jumping to the symbol - definition for other programming languages besides C++. In addition, - it integrates diagnostics from the language server. + The language client provides code completion, highlighting of the + symbol under cursor, and jumping to the symbol definition for other + programming languages besides C++. In addition, it integrates + diagnostics from the language server. \li \l{Editing MIME Types} diff --git a/doc/src/editors/creator-locator.qdoc b/doc/src/editors/creator-locator.qdoc index 7d8f25dd077..e7c048f6d2f 100644 --- a/doc/src/editors/creator-locator.qdoc +++ b/doc/src/editors/creator-locator.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -99,7 +99,7 @@ \section1 Using Locator Filters The locator enables you to browse not only files, but any items defined by - \b{locator filters}. By default, the locator contains filters for: + \b{locator filters}. The filters that are available depend on the file type: \list @@ -114,11 +114,11 @@ \li Locating bookmarks (\c {b}). For more information, see \l{Using Bookmarks}. - \li Locating class (\c {c}), enum, and function (m) definitions in your - project or anywhere referenced from your project (\c {:}) + \li Locating class (\c {c}), enum, and function (\c {m}) definitions in + your project or anywhere referenced from your project (\c {:}) \endif - \li Locating QML methods (m) + \li Locating QML methods (\c {m}) \li Locating symbols in the current document (\c {.}) diff --git a/doc/src/editors/creator-only/creator-language-server.qdoc b/doc/src/editors/creator-only/creator-language-server.qdoc index 4b75aae16e1..9dc5d1e84ff 100644 --- a/doc/src/editors/creator-only/creator-language-server.qdoc +++ b/doc/src/editors/creator-only/creator-language-server.qdoc @@ -39,8 +39,9 @@ \list \li \l{Completing Code}{Code completion} \li Highlighting the symbol under cursor - \li \l{Moving to Symbol Definition or Declaration} - {Moving to the symbol definition} + \li Navigating in the code by using the \l{Searching with the Locator} + {locator} or \l{Moving to Symbol Definition or Declaration} + {moving to the symbol definition} \li Inspecting code by viewing the document \l{Viewing Defined Types and Symbols}{outline} \li \l{Finding Symbols}{Finding references to symbols} @@ -50,8 +51,10 @@ By providing a client for the language server protocol, \QC can support the above features for several other programming languages besides C++. - However, the experimental client does not support language servers that - require special handling. + However, the client does not support language servers that require special + handling. + + \section1 Adding MIME Types for Language Servers \QC uses the \l{https://www.iana.org/assignments/media-types/media-types.xhtml} {MIME type} of the file to determine which language server to request @@ -62,21 +65,11 @@ only sent to the languge server if they are known to be handled by it. For more information about how \QC uses MIME types, see \l {Editing MIME Types}. - The experimental language service client has been mostly tested with Python. - If problems arise when you try some other language, please select - \uicontrol Help > \uicontrol {Report Bug} to report them in the Qt Bug - Tracker. The reports should include \QC console output with the environment - variable \c {QT_LOGGING_RULES=qtc.languageclient.*=true} set. + \section1 Specifying Settings for Language Clients To use a language server: \list 1 - \li Enable the language server client by selecting \uicontrol Help > - \uicontrol {About Plugins} > \uicontrol {Other Languages} > - \uicontrol {Language Client} (or \uicontrol {Qt Creator} > - \uicontrol {About Plugins} > \uicontrol {Other Languages} > - \uicontrol {Language Client} on \macos). - \li Restart \QC to load the language client plugin. \li Select \uicontrol Tools > \uicontrol Options > \uicontrol {Language Client} (or \uicontrol {Qt Creator} > \uicontrol Preferences > \uicontrol {Language Client} > on @@ -86,15 +79,48 @@ language server. \li Select \uicontrol Add to add language servers. \li In the \uicontrol Name field, enter a name for the language server. + Select the \inlineimage replace.png + (\uicontrol {Variables}) button to use a variable for the server + name. For more information, see \l{Using Qt Creator Variables}. \li In the \uicontrol {Language} field, select \uicontrol {Set MIME Types} to select the MIME types of the files to send to the language server. In the field below, you can enter file patterns to extend the MIME types, separated by semicolons. + \li In the \uicontrol {Startup behavior} field, select whether the + language server is started when \QC starts or when a project or file + with a matching MIME type is opened. The + \uicontrol {General Messages} \l{Viewing Output}{output pane} + displays information about the connection to the language server. + \li In the \uicontrol Capabilities field, you can see the features + that are supported by the language server. Only some of them are + implemented by \QC. \li In the \uicontrol Executable field, enter the path to the language server executable. \li In the \uicontrol Arguments field, enter any required command line + arguments. Select \uicontrol Variables to use variables as arguments. \endlist To remove language servers from the list, select \uicontrol Delete. + + \section1 Supported Locator Filters + + The locator enables you to browse not only files, but any items defined by + \e {locator filters}. The language client plugin supports the following + locator filters: + + \list + \li Locating symbols in the current project (\c {:}) + \li Locating symbols in the current document (\c {.}) + \li Locating class (\c {c}), enum, and function (\c {m}) + definitions in your project + \endlist + + \section1 Reporting Issues + + The language service client has been mostly tested with Python. + If problems arise when you try it or some other language, please select + \uicontrol Help > \uicontrol {Report Bug} to report them in the Qt Bug + Tracker. The reports should include \QC console output with the environment + variable \c {QT_LOGGING_RULES=qtc.languageclient.*=true} set. */ diff --git a/doc/src/howto/creator-help.qdoc b/doc/src/howto/creator-help.qdoc index 51bf69b810b..7d8e7908bcc 100644 --- a/doc/src/howto/creator-help.qdoc +++ b/doc/src/howto/creator-help.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -23,12 +23,6 @@ ** ****************************************************************************/ -// ********************************************************************** -// NOTE: the sections are not ordered by their logical order to avoid -// reshuffling the file each time the index order changes (i.e., often). -// Run the fixnavi.pl script to adjust the links to the index order. -// ********************************************************************** - /*! \contentspage index.html \page creator-help.html @@ -62,7 +56,6 @@ \li To select and configure how the documentation is displayed in the \uicontrol Help mode, select \uicontrol Tools > \uicontrol Options > \uicontrol Help. - \endlist The following image displays the context sensitive help in the \uicontrol Edit @@ -70,6 +63,19 @@ \image qtcreator-context-sensitive-help.png + If the help HTML file does not use a style sheet, you can change the font + family, style, and size in \uicontrol Tools > \uicontrol Options > + \uicontrol Help > \uicontrol General. + + \image qtcreator-help-options.png + + By default, you can use the mouse scroll wheel to zoom help pages. To + disable this feature, deselect the \uicontrol {Enable scroll wheel zooming} + check box. + + To switch to the editor context when you close the last help page, select + the \uicontrol {Return to editor on closing the last page} check box. + \section1 Viewing Function Tooltips To hide function tooltips by default, select \uicontrol {Tools > Options > @@ -127,17 +133,19 @@ \endlist - To import and export bookmarks, select \uicontrol {Tools > Options > Help > - General Settings > Import} or \uicontrol Export. + To import and export bookmarks, select \uicontrol Tools > \uicontrol Options + > \uicontrol Help > \uicontrol General > \uicontrol {Import Bookmarks} or + \uicontrol {Export Bookmarks}. \section2 Full-text Search In the \uicontrol Search pane, you can use full-text search for finding a - particular word in all the installed documents. In the \uicontrol {Search for} - field, enter the term you are looking for, and select the \uicontrol Search - button. All documents that contain the specified term are listed. The list - is sorted by the number of search hits that the documents contain. Select a - document in the list to open it. + particular word in all the installed documents. Enter the term you are + looking for, and select the \uicontrol Search button. All documents that + contain the specified term are listed. The list is sorted by document + version (if you have installed several Qt versions, for example) and + the number of search hits that the documents contain. Select a document in + the list to open it. \image qtcreator-help-search.png "Search pane" @@ -159,12 +167,6 @@ \endlist - For more flexibility, use the \uicontrol {Advanced search}. Specify words to - exclude from the search hits, or search for an exact phrase or for similar - words. For example, searching for \c{QStin}, \c{QSting}, or \c{QStrin} lists - all the documents with titles that are similar, such as \c{QString}. - Combine options to improve the search results. - Full-text search is based on indexing all the installed documents the first time when you open the \uicontrol Search pane. If you add or remove documents, \QC recreates the index. diff --git a/doc/src/howto/creator-ui.qdoc b/doc/src/howto/creator-ui.qdoc index d477eda78de..314abee8740 100644 --- a/doc/src/howto/creator-ui.qdoc +++ b/doc/src/howto/creator-ui.qdoc @@ -110,6 +110,46 @@ documentation, see \l{Tips and Tricks}. \endif + \section1 Changing Languages + + \QC has been localized into several languages. If the system language + is one of the supported languages, it is automatically selected. To + change the language, select \uicontrol Tools > \uicontrol Options > + \uicontrol Environment and select a language in the \uicontrol Language + field. The change takes effect after you restart \QC. + + \section1 Viewing Images + + \QC opens image files in the image viewer. + + \image qtcreator-image-viewer.png "Image viewer" + + Use the toolbar buttons (1) or \l{Keyboard Shortcuts}{keyboard shortcuts} + to: + + \list + + \li Export SVG images to pixmaps + + \li Switch between background and outline modes + + \li Zoom in and out + + \li Fit images to screen + + \li Return to original size + + \li Play and pause animated GIF and MNG images + + \endlist + + \section2 Exporting SVG Images + + If you receive a freely scalable icon in the SVG format from an UI designer, + you can export it to several images of different sizes to create a set of + pixmaps. You can then use QIcon::addPixmap() to add the pixmaps to icons in + different modes and states. + \section1 Platform Notes This section describes the cases where the behavior of \QC depends on the @@ -296,7 +336,7 @@ \title Viewing Output - \image qtcreator-task-pane.png + \image qtcreator-general-messages.png "General Messages output pane" The task pane in \QC can display one of the following panes: @@ -334,6 +374,9 @@ up in the pane. In these panes, you can also use the zoom buttons to increase and decrease the text size of the output. + To filter the output, enter a string in the \uicontrol Filter field. + Filtering is not supported in all output panes. + To open the \uicontrol{General Messages} and \if defined(qtcreator) \l{Using Version Control Systems}{Version Control} @@ -404,7 +447,7 @@ \uicontrol {Filter Tree} and then select a filter. - \image qtcreator-build-issues.png + \image qtcreator-issues.png "Issues output pane" Right-clicking on a line brings up a context menu with actions that you can apply to the contents of the line. You can remove a line, copy its contents @@ -422,6 +465,11 @@ To jump from one issue to the next or previous one, press \key F6 and \key Shift+F6. + By default, the \uicontrol Issues pane is cleared on a new build. To keep + the issues from the previous build rounds, deselect \uicontrol Tools > + \uicontrol Options > \uicontrol {Build & Run} > \uicontrol General > + \uicontrol {Clear issues list on new build}. + \section1 Search Results In the \uicontrol{Search Results} pane, you can search through projects, files on @@ -470,7 +518,7 @@ The \uicontrol{Compile Output} is a more detailed version of information displayed in the \uicontrol{Issues} pane. - \image qtcreator-compile-pane.png + \image qtcreator-compile-output.png "Compile Output pane" Double-click on a file name in an error message to open the file in the code editor. @@ -563,42 +611,4 @@ \l{Showing Task List Files in Issues Pane}. \endif - \section1 Changing Languages - - \QC has been localized into several languages. If the system language is one - of the supported languages, it is automatically selected. To change the - language, select \uicontrol {Tools > Options > Environment} and select a language - in the \uicontrol Language field. The change takes effect after you restart \QC. - - \section1 Viewing Images - - \QC opens image files in the image viewer. - - \image qtcreator-image-viewer.png "Image viewer" - - Use the toolbar buttons (1) or \l{Keyboard Shortcuts}{keyboard shortcuts} - to: - - \list - - \li Export SVG images to pixmaps - - \li Switch between background and outline modes - - \li Zoom in and out - - \li Fit images to screen - - \li Return to original size - - \li Play and pause animated GIF and MNG images - - \endlist - - \section1 Exporting SVG Images - - If you receive a freely scalable icon in the SVG format from an UI designer, - you can export it to several images of different sizes to create a set of - pixmaps. You can then use QIcon::addPixmap() to add the pixmaps to icons in - different modes and states. */ diff --git a/doc/src/overview/creator-only/creator-overview.qdoc b/doc/src/overview/creator-only/creator-overview.qdoc index 1f6f31936d1..790ed4bf0d0 100644 --- a/doc/src/overview/creator-only/creator-overview.qdoc +++ b/doc/src/overview/creator-only/creator-overview.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -79,10 +79,9 @@ languages as code, not just as plain text. This enables it to provide you with useful features, such as semantic highlighting, checking code syntax, code completion, and refactoring actions. - In addition, the experimental language server plugin provides - some of these services for other programming languages, such as - Python, for which a \e {language server} is available that - provides information about the code to IDEs. + \QC supports some of these services also for other programming + languages, such as Python, for which a \e {language server} is + available that provides information about the code to IDEs. For more information, see \l{Coding}. \row \li \inlineimage creator_buildingrunning.png diff --git a/doc/src/projects/creator-only/creator-projects-opening.qdoc b/doc/src/projects/creator-only/creator-projects-opening.qdoc index 6298c896b52..38489791501 100644 --- a/doc/src/projects/creator-only/creator-projects-opening.qdoc +++ b/doc/src/projects/creator-only/creator-projects-opening.qdoc @@ -59,8 +59,8 @@ \uicontrol Options > \uicontrol Kits. Qt for Python projects rely on the \l{Using Language Servers} - {experimental language server client} for code completion, - highlighting, and other useful features. + {language server client} for code completion, highlighting, and + other useful features. If \QC cannot find an existing build for a particular \l{glossary-buildandrun-kit}{kit}, it starts out diff --git a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt index e8498150989..27cc4082230 100644 --- a/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt +++ b/src/libs/3rdparty/syntax-highlighting/CMakeLists.txt @@ -33,6 +33,15 @@ add_qtc_library(KSyntaxHighlighting STATIC ) install( - DIRECTORY data/ + DIRECTORY data/syntax DESTINATION "${IDE_DATA_PATH}/generic-highlighter/" ) + +add_custom_target(copy_generic_highligher_to_builddir ALL VERBATIM) +add_custom_command(TARGET copy_generic_highligher_to_builddir POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory data/syntax + "${PROJECT_BINARY_DIR}/${IDE_DATA_PATH}/generic-highlighter/syntax" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT Copy files into build directory + VERBATIM +) diff --git a/src/libs/clangsupport/CMakeLists.txt b/src/libs/clangsupport/CMakeLists.txt index f4731397c79..84cdbaf8b9b 100644 --- a/src/libs/clangsupport/CMakeLists.txt +++ b/src/libs/clangsupport/CMakeLists.txt @@ -70,7 +70,7 @@ add_qtc_library(ClangSupport ipcclientinterface.h ipcclientprovider.h ipcinterface.h - ipcserverinterface.cpp ipcserverinterface.h + ipcserverinterface.h lineprefixer.cpp lineprefixer.h messageenvelop.cpp messageenvelop.h modifiedtimechecker.h @@ -93,7 +93,6 @@ add_qtc_library(ClangSupport projectpartcontainer.cpp projectpartcontainer.h projectpartid.h projectpartpch.cpp projectpartpch.h - projectpartpchproviderinterface.h projectpartsstorage.h projectpartsstorageinterface.h readmessageblock.cpp readmessageblock.h diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri index 201c5bf5380..df537f58486 100644 --- a/src/libs/clangsupport/clangsupport-lib.pri +++ b/src/libs/clangsupport/clangsupport-lib.pri @@ -204,7 +204,6 @@ HEADERS += \ $$PWD/nativefilepath.h \ $$PWD/filepathview.h \ $$PWD/compilermacro.h \ - $$PWD/projectpartpchproviderinterface.h \ $$PWD/updategeneratedfilesmessage.h \ $$PWD/removegeneratedfilesmessage.h \ $$PWD/generatedfiles.h \ diff --git a/src/libs/clangsupport/ipcserverinterface.cpp b/src/libs/clangsupport/ipcserverinterface.cpp deleted file mode 100644 index fbc92de52ec..00000000000 --- a/src/libs/clangsupport/ipcserverinterface.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "ipcserverinterface.h" - -namespace ClangBackEnd { - - -} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/precompiledheadersupdatedmessage.h b/src/libs/clangsupport/precompiledheadersupdatedmessage.h index 9c17a3c9da2..5bd24dcd49c 100644 --- a/src/libs/clangsupport/precompiledheadersupdatedmessage.h +++ b/src/libs/clangsupport/precompiledheadersupdatedmessage.h @@ -25,7 +25,10 @@ #pragma once -#include "projectpartpch.h" +#include "clangsupport_global.h" +#include "projectpartid.h" + +#include namespace ClangBackEnd { @@ -33,29 +36,26 @@ class PrecompiledHeadersUpdatedMessage { public: PrecompiledHeadersUpdatedMessage() = default; - PrecompiledHeadersUpdatedMessage(ProjectPartPch projectPartPch) + PrecompiledHeadersUpdatedMessage(ProjectPartId projectPartId) { - projectPartPchs.push_back(projectPartPch); + projectPartIds.push_back(projectPartId); } - PrecompiledHeadersUpdatedMessage(ProjectPartPchs &&projectPartPchs) - : projectPartPchs(std::move(projectPartPchs)) + PrecompiledHeadersUpdatedMessage(ProjectPartIds &&projectPartIds) + : projectPartIds(std::move(projectPartIds)) {} - ProjectPartPchs takeProjectPartPchs() const - { - return std::move(projectPartPchs); - } + ProjectPartIds takeProjectPartIds() const { return std::move(projectPartIds); } friend QDataStream &operator<<(QDataStream &out, const PrecompiledHeadersUpdatedMessage &message) { - out << message.projectPartPchs; + out << message.projectPartIds; return out; } friend QDataStream &operator>>(QDataStream &in, PrecompiledHeadersUpdatedMessage &message) { - in >> message.projectPartPchs; + in >> message.projectPartIds; return in; } @@ -63,16 +63,13 @@ public: friend bool operator==(const PrecompiledHeadersUpdatedMessage &first, const PrecompiledHeadersUpdatedMessage &second) { - return first.projectPartPchs == second.projectPartPchs; + return first.projectPartIds == second.projectPartIds; } - PrecompiledHeadersUpdatedMessage clone() const - { - return PrecompiledHeadersUpdatedMessage(Utils::clone(projectPartPchs)); - } + PrecompiledHeadersUpdatedMessage clone() const { return *this; } public: - ProjectPartPchs projectPartPchs; + ProjectPartIds projectPartIds; }; CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const PrecompiledHeadersUpdatedMessage &message); diff --git a/src/libs/clangsupport/projectpartid.h b/src/libs/clangsupport/projectpartid.h index c372682bafc..fc5f659605f 100644 --- a/src/libs/clangsupport/projectpartid.h +++ b/src/libs/clangsupport/projectpartid.h @@ -54,7 +54,7 @@ public: return first.projectPathId < second.projectPathId; } - friend QDataStream &operator<<(QDataStream &out, const ProjectPartId &projectPathId) + friend QDataStream &operator<<(QDataStream &out, ProjectPartId projectPathId) { out << projectPathId.projectPathId; diff --git a/src/libs/clangsupport/projectpartpch.cpp b/src/libs/clangsupport/projectpartpch.cpp index aac672441c7..9c870ac572b 100644 --- a/src/libs/clangsupport/projectpartpch.cpp +++ b/src/libs/clangsupport/projectpartpch.cpp @@ -29,8 +29,7 @@ namespace ClangBackEnd { QDebug operator<<(QDebug debug, const ProjectPartPch &projectPartPch) { - debug.nospace() << "FileContainer(" << projectPartPch.projectPartId.projectPathId << ", " - << projectPartPch.pchPath << ")"; + debug.nospace() << "FileContainer(" << projectPartPch.projectPartId.projectPathId << ")"; return debug; } diff --git a/src/libs/clangsupport/projectpartpch.h b/src/libs/clangsupport/projectpartpch.h index c471b46b166..213247ae429 100644 --- a/src/libs/clangsupport/projectpartpch.h +++ b/src/libs/clangsupport/projectpartpch.h @@ -74,8 +74,7 @@ public: friend bool operator==(const ProjectPartPch &first, const ProjectPartPch &second) { - return first.projectPartId == second.projectPartId - && first.pchPath == second.pchPath; + return first.projectPartId == second.projectPartId && first.pchPath == second.pchPath; } ProjectPartPch clone() const diff --git a/src/libs/sqlite/CMakeLists.txt b/src/libs/sqlite/CMakeLists.txt index a1359feb92d..22ba4bac340 100644 --- a/src/libs/sqlite/CMakeLists.txt +++ b/src/libs/sqlite/CMakeLists.txt @@ -9,7 +9,7 @@ add_qtc_library(Sqlite ../3rdparty/sqlite/sqlite3.c createtablesqlstatementbuilder.cpp createtablesqlstatementbuilder.h sqlitebasestatement.cpp sqlitebasestatement.h - sqlitecolumn.cpp sqlitecolumn.h + sqlitecolumn.h sqlitedatabase.cpp sqlitedatabase.h sqlitedatabasebackend.cpp sqlitedatabasebackend.h sqliteexception.cpp sqliteexception.h @@ -17,11 +17,11 @@ add_qtc_library(Sqlite sqliteindex.h sqlitereadstatement.cpp sqlitereadstatement.h sqlitereadwritestatement.cpp sqlitereadwritestatement.h - sqlitetable.cpp sqlitetable.h + sqlitetable.h sqlitetransaction.h sqlitewritestatement.cpp sqlitewritestatement.h sqlstatementbuilder.cpp sqlstatementbuilder.h - sqlstatementbuilderexception.cpp sqlstatementbuilderexception.h + sqlstatementbuilderexception.h utf8string.cpp utf8string.h utf8stringvector.cpp utf8stringvector.h ) diff --git a/src/libs/sqlite/sqlite-lib.pri b/src/libs/sqlite/sqlite-lib.pri index 052e533d2e6..4d7f906a199 100644 --- a/src/libs/sqlite/sqlite-lib.pri +++ b/src/libs/sqlite/sqlite-lib.pri @@ -19,16 +19,14 @@ SOURCES += \ $$PWD/sqlitereadwritestatement.cpp \ $$PWD/sqlitewritestatement.cpp \ $$PWD/sqlstatementbuilder.cpp \ - $$PWD/sqlstatementbuilderexception.cpp \ $$PWD/utf8string.cpp \ $$PWD/utf8stringvector.cpp \ $$PWD/sqlitedatabase.cpp \ - $$PWD/sqlitetable.cpp \ - $$PWD/sqlitecolumn.cpp \ $$PWD/sqlitebasestatement.cpp HEADERS += \ $$PWD/createtablesqlstatementbuilder.h \ $$PWD/sqlitedatabasebackend.h \ + $$PWD/sqlitedatabaseinterface.h \ $$PWD/sqliteexception.h \ $$PWD/sqliteglobal.h \ $$PWD/sqlitereadstatement.h \ diff --git a/src/libs/sqlite/sqlite-source.pri b/src/libs/sqlite/sqlite-source.pri index b297e31da2a..57292939018 100644 --- a/src/libs/sqlite/sqlite-source.pri +++ b/src/libs/sqlite/sqlite-source.pri @@ -17,12 +17,9 @@ SOURCES += \ sqliteworkerthread.cpp \ sqlitewritestatement.cpp \ sqlstatementbuilder.cpp \ - sqlstatementbuilderexception.cpp \ utf8string.cpp \ utf8stringvector.cpp \ sqlitedatabase.cpp \ - sqlitetable.cpp \ - sqlitecolumn.cpp \ tablewriteworker.cpp \ tablewriteworkerproxy.cpp HEADERS += \ diff --git a/src/libs/sqlite/sqlitecolumn.cpp b/src/libs/sqlite/sqlitecolumn.cpp deleted file mode 100644 index 201f1fbcb9d..00000000000 --- a/src/libs/sqlite/sqlitecolumn.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "sqlitecolumn.h" - -namespace Sqlite { - - -} // namespace Sqlite diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h index d0eae28f790..2c35a293c23 100644 --- a/src/libs/sqlite/sqlitedatabase.h +++ b/src/libs/sqlite/sqlitedatabase.h @@ -26,6 +26,7 @@ #pragma once #include "sqlitedatabasebackend.h" +#include "sqlitedatabaseinterface.h" #include "sqliteglobal.h" #include "sqlitetable.h" #include "sqlitetransaction.h" @@ -43,7 +44,7 @@ using namespace std::chrono_literals; class ReadStatement; class WriteStatement; -class SQLITE_EXPORT Database final : public TransactionInterface +class SQLITE_EXPORT Database final : public TransactionInterface, public DatabaseInterface { template friend class Statement; @@ -105,19 +106,18 @@ public: return m_databaseBackend.changesCount(); } - int totalChangesCount() - { - return m_databaseBackend.totalChangesCount(); - } + int totalChangesCount() { return m_databaseBackend.totalChangesCount(); } + + void walCheckpointFull() override { m_databaseBackend.walCheckpointFull(); } private: - void deferredBegin(); - void immediateBegin(); - void exclusiveBegin(); - void commit(); - void rollback(); - void lock(); - void unlock(); + void deferredBegin() override; + void immediateBegin() override; + void exclusiveBegin() override; + void commit() override; + void rollback() override; + void lock() override; + void unlock() override; void initializeTables(); void registerTransactionStatements(); diff --git a/src/libs/sqlite/sqlitedatabasebackend.cpp b/src/libs/sqlite/sqlitedatabasebackend.cpp index a42564aca56..bf9dfab6fc2 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.cpp +++ b/src/libs/sqlite/sqlitedatabasebackend.cpp @@ -406,6 +406,27 @@ void DatabaseBackend::setBusyTimeout(std::chrono::milliseconds timeout) sqlite3_busy_timeout(m_databaseHandle, int(timeout.count())); } +void DatabaseBackend::walCheckpointFull() +{ + int resultCode = sqlite3_wal_checkpoint_v2(m_databaseHandle, + nullptr, + SQLITE_CHECKPOINT_TRUNCATE, + nullptr, + nullptr); + + switch (resultCode) { + case SQLITE_OK: + break; + case SQLITE_BUSY: + throw DatabaseIsBusy("DatabaseBackend::walCheckpointFull: Operation could not concluded " + "because database is busy!"); + case SQLITE_ERROR: + throwException("DatabaseBackend::walCheckpointFull: Error occurred!"); + case SQLITE_MISUSE: + throwExceptionStatic("DatabaseBackend::walCheckpointFull: Misuse of database!"); + } +} + void DatabaseBackend::throwExceptionStatic(const char *whatHasHappens) { throw Exception(whatHasHappens); diff --git a/src/libs/sqlite/sqlitedatabasebackend.h b/src/libs/sqlite/sqlitedatabasebackend.h index 2de55672aa3..7f3973f8787 100644 --- a/src/libs/sqlite/sqlitedatabasebackend.h +++ b/src/libs/sqlite/sqlitedatabasebackend.h @@ -85,6 +85,8 @@ public: void setBusyTimeout(std::chrono::milliseconds timeout); + void walCheckpointFull(); + protected: bool databaseIsOpen() const; diff --git a/src/libs/sqlite/sqlstatementbuilderexception.cpp b/src/libs/sqlite/sqlitedatabaseinterface.h similarity index 86% rename from src/libs/sqlite/sqlstatementbuilderexception.cpp rename to src/libs/sqlite/sqlitedatabaseinterface.h index 82f5b4f7929..61ea3ac928d 100644 --- a/src/libs/sqlite/sqlstatementbuilderexception.cpp +++ b/src/libs/sqlite/sqlitedatabaseinterface.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -23,12 +23,15 @@ ** ****************************************************************************/ -#include "sqlstatementbuilderexception.h" +#pragma once namespace Sqlite { +class DatabaseInterface +{ +public: + virtual void walCheckpointFull() = 0; - - - - +protected: + ~DatabaseInterface() = default; +}; } // namespace Sqlite diff --git a/src/libs/sqlite/sqlitetable.cpp b/src/libs/sqlite/sqlitetable.cpp deleted file mode 100644 index 99b0e95938c..00000000000 --- a/src/libs/sqlite/sqlitetable.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "sqlitetable.h" - -namespace Sqlite { - - - -} // namespace Sqlite diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp index 6b02f92c249..fe83b95f586 100644 --- a/src/libs/utils/consoleprocess_unix.cpp +++ b/src/libs/utils/consoleprocess_unix.cpp @@ -80,8 +80,12 @@ bool ConsoleProcess::start() QtcProcess::SplitError perr; QtcProcess::Arguments pargs = QtcProcess::prepareArgs(d->m_commandLine.arguments(), - &perr, HostOsInfo::hostOs(), - &d->m_environment, &d->m_workingDir); + &perr, + HostOsInfo::hostOs(), + &d->m_environment, + &d->m_workingDir, + d->m_commandLine.metaCharMode() + == CommandLine::MetaCharMode::Abort); QString pcmd; if (perr == QtcProcess::SplitOk) { pcmd = d->m_commandLine.executable().toString(); diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index c402c8dae10..22fb05240b2 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -78,8 +78,9 @@ CommandLine::CommandLine(const FilePath &executable) : m_executable(executable) {} -CommandLine::CommandLine(const FilePath &exe, const QStringList &args) +CommandLine::CommandLine(const FilePath &exe, const QStringList &args, MetaCharMode metaCharMode) : m_executable(exe) + , m_metaCharMode(metaCharMode) { addArgs(args); } diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h index 15f119646e3..cfe388bb47d 100644 --- a/src/libs/utils/fileutils.h +++ b/src/libs/utils/fileutils.h @@ -132,10 +132,13 @@ class QTCREATOR_UTILS_EXPORT CommandLine { public: enum RawType { Raw }; + enum class MetaCharMode { Abort, Ignore }; CommandLine() {} explicit CommandLine(const FilePath &executable); - CommandLine(const FilePath &exe, const QStringList &args); + CommandLine(const FilePath &exe, + const QStringList &args, + MetaCharMode metaCharMode = MetaCharMode::Ignore); CommandLine(const FilePath &exe, const QString &unparsedArgs, RawType); void addArg(const QString &arg, OsType osType = HostOsInfo::hostOs()); @@ -147,11 +150,13 @@ public: FilePath executable() const { return m_executable; } QString arguments() const { return m_arguments; } + MetaCharMode metaCharMode() const { return m_metaCharMode; } QStringList splitArguments(OsType osType = HostOsInfo::hostOs()) const; private: FilePath m_executable; QString m_arguments; + MetaCharMode m_metaCharMode; }; class QTCREATOR_UTILS_EXPORT FileUtils { diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index d05746d5b1e..992e1817c02 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -595,12 +595,12 @@ static QString quoteArgWin(const QString &arg) } QtcProcess::Arguments QtcProcess::prepareArgs(const QString &cmd, SplitError *err, OsType osType, - const Environment *env, const QString *pwd) + const Environment *env, const QString *pwd, bool abortOnMeta) { if (osType == OsTypeWindows) return prepareArgsWin(cmd, err, env, pwd); else - return Arguments::createUnixArgs(splitArgs(cmd, osType, true, err, env, pwd)); + return Arguments::createUnixArgs(splitArgs(cmd, osType, abortOnMeta, err, env, pwd)); } diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index d3d22d34154..5eeacf666e8 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -79,7 +79,8 @@ public: //! Prepare argument of a shell command for feeding into QProcess static Arguments prepareArgs(const QString &cmd, SplitError *err, OsType osType = HostOsInfo::hostOs(), - const Environment *env = nullptr, const QString *pwd = nullptr); + const Environment *env = nullptr, const QString *pwd = nullptr, + bool abortOnMeta = true); //! Prepare a shell command for feeding into QProcess static bool prepareCommand(const QString &command, const QString &arguments, QString *outCmd, Arguments *outArgs, OsType osType = HostOsInfo::hostOs(), diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index a3c2e7632e6..a725fc55eab 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -234,15 +234,15 @@ bool AndroidDeployQtStep::init() if (m_useAndroiddeployqt) { const ProjectNode *node = target()->project()->findNodeForBuildKey(rc->buildKey()); + if (!node) + return false; m_apkPath = Utils::FilePath::fromString(node->data(Constants::AndroidApk).toString()); if (!m_apkPath.isEmpty()) { m_manifestName = Utils::FilePath::fromString(node->data(Constants::AndroidManifest).toString()); m_command = AndroidConfigurations::currentConfig().adbToolPath(); AndroidManager::setManifestPath(target(), m_manifestName); } else { - QString jsonFile; - if (node) - jsonFile = node->data(Constants::AndroidDeploySettingsFile).toString(); + QString jsonFile = node->data(Constants::AndroidDeploySettingsFile).toString(); if (jsonFile.isEmpty()) { emit addOutput(tr("Cannot find the androiddeploy Json file."), OutputFormat::Stderr); return false; diff --git a/src/plugins/clangpchmanager/pchmanagerclient.cpp b/src/plugins/clangpchmanager/pchmanagerclient.cpp index c26b871f506..04d1d4a0bf8 100644 --- a/src/plugins/clangpchmanager/pchmanagerclient.cpp +++ b/src/plugins/clangpchmanager/pchmanagerclient.cpp @@ -43,11 +43,8 @@ void PchManagerClient::alive() void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message) { - for (ClangBackEnd::ProjectPartPch &projectPartPch : message.takeProjectPartPchs()) { - const QString pchPath{projectPartPch.pchPath}; - addProjectPartPch(std::move(projectPartPch)); - precompiledHeaderUpdated(projectPartPch.projectPartId, pchPath, projectPartPch.lastModified); - } + for (ClangBackEnd::ProjectPartId &projectPartId : message.takeProjectPartIds()) + precompiledHeaderUpdated(projectPartId); } void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message) @@ -66,10 +63,8 @@ void PchManagerClient::progress(ClangBackEnd::ProgressMessage &&message) void PchManagerClient::precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId) { - for (auto notifier : m_notifiers) { - removeProjectPartPch(projectPartId); + for (auto notifier : m_notifiers) notifier->precompiledHeaderRemoved(projectPartId); - } } void PchManagerClient::setConnectionClient(PchManagerConnectionClient *connectionClient) @@ -77,22 +72,6 @@ void PchManagerClient::setConnectionClient(PchManagerConnectionClient *connectio m_connectionClient = connectionClient; } -Utils::optional PchManagerClient::projectPartPch( - ClangBackEnd::ProjectPartId projectPartId) const -{ - auto found = std::lower_bound(m_projectPartPchs.cbegin(), - m_projectPartPchs.cend(), - projectPartId, - [] (const auto &projectPartPch, auto projectPartId) { - return projectPartId < projectPartPch.projectPartId; - }); - - if (found != m_projectPartPchs.end() && found->projectPartId == projectPartId) - return *found; - - return Utils::nullopt; -} - void PchManagerClient::attach(PchManagerNotifierInterface *notifier) { m_notifiers.push_back(notifier); @@ -109,47 +88,15 @@ void PchManagerClient::detach(PchManagerNotifierInterface *notifierToBeDeleted) m_notifiers.erase(newEnd, m_notifiers.end()); } -void PchManagerClient::removeProjectPartPch(ClangBackEnd::ProjectPartId projectPartId) -{ - auto found = std::lower_bound(m_projectPartPchs.begin(), - m_projectPartPchs.end(), - projectPartId, - [] (const auto &projectPartPch, auto projectPartId) { - return projectPartId < projectPartPch.projectPartId; - }); - - if (found != m_projectPartPchs.end() && found->projectPartId == projectPartId) { - *found = std::move(m_projectPartPchs.back()); - m_projectPartPchs.pop_back(); - } -} - -void PchManagerClient::addProjectPartPch(ClangBackEnd::ProjectPartPch &&projectPartPch) -{ - auto found = std::lower_bound(m_projectPartPchs.begin(), - m_projectPartPchs.end(), - projectPartPch.projectPartId, - [] (const auto &projectPartPch, auto projectPartId) { - return projectPartId < projectPartPch.projectPartId; - }); - - if (found != m_projectPartPchs.end() && found->projectPartId == projectPartPch.projectPartId) - *found = std::move(projectPartPch); - else - m_projectPartPchs.insert(found, std::move(projectPartPch)); -} - const std::vector &PchManagerClient::notifiers() const { return m_notifiers; } -void PchManagerClient::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId, - const QString &pchFilePath, - long long lastModified) +void PchManagerClient::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId) { for (auto notifier : m_notifiers) - notifier->precompiledHeaderUpdated(projectPartId, pchFilePath, lastModified); + notifier->precompiledHeaderUpdated(projectPartId); } } // namespace ClangPchManager diff --git a/src/plugins/clangpchmanager/pchmanagerclient.h b/src/plugins/clangpchmanager/pchmanagerclient.h index 308370356e2..7d986a0ab69 100644 --- a/src/plugins/clangpchmanager/pchmanagerclient.h +++ b/src/plugins/clangpchmanager/pchmanagerclient.h @@ -28,7 +28,7 @@ #include "clangpchmanager_global.h" #include -#include +#include #include @@ -37,8 +37,7 @@ class PchManagerConnectionClient; class ProgressManagerInterface; class PchManagerNotifierInterface; -class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchManagerClientInterface, - public ClangBackEnd::ProjectPartPchProviderInterface +class CLANGPCHMANAGER_EXPORT PchManagerClient final : public ClangBackEnd::PchManagerClientInterface { friend class PchManagerNotifierInterface; public: @@ -56,27 +55,13 @@ public: void setConnectionClient(PchManagerConnectionClient *connectionClient); - Utils::optional projectPartPch( - ClangBackEnd::ProjectPartId projectPartId) const override; - - const ClangBackEnd::ProjectPartPchs &projectPartPchs() const override - { - return m_projectPartPchs; - } - unittest_public : const std::vector ¬ifiers() const; - void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId, - const QString &pchFilePath, - long long lastModified); + void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId); void attach(PchManagerNotifierInterface *notifier); void detach(PchManagerNotifierInterface *notifier); - void addProjectPartPch(ClangBackEnd::ProjectPartPch &&projectPartPch); - void removeProjectPartPch(ClangBackEnd::ProjectPartId projectPartId); - private: - ClangBackEnd::ProjectPartPchs m_projectPartPchs; std::vector m_notifiers; PchManagerConnectionClient *m_connectionClient=nullptr; ProgressManagerInterface &m_pchCreationProgressManager; diff --git a/src/plugins/clangpchmanager/pchmanagernotifierinterface.h b/src/plugins/clangpchmanager/pchmanagernotifierinterface.h index 04461186d6f..780ec5a2cd1 100644 --- a/src/plugins/clangpchmanager/pchmanagernotifierinterface.h +++ b/src/plugins/clangpchmanager/pchmanagernotifierinterface.h @@ -42,10 +42,7 @@ public: PchManagerNotifierInterface(const PchManagerNotifierInterface &) = delete; PchManagerNotifierInterface &operator=(const PchManagerNotifierInterface &) = delete; - virtual void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId, - const QString &pchFilePath, - long long lastModified) - = 0; + virtual void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId) = 0; virtual void precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId) = 0; PchManagerClient &m_pchManagerClient; diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.cpp b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp index 8cfd5b942a4..20a9fce730d 100644 --- a/src/plugins/clangrefactoring/refactoringprojectupdater.cpp +++ b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp @@ -30,9 +30,7 @@ namespace ClangRefactoring { -void RefactoringProjectUpdater::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId, - const QString &, - long long) +void RefactoringProjectUpdater::precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId) { const QString projectPartName = fetchProjectPartName(projectPartId); diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.h b/src/plugins/clangrefactoring/refactoringprojectupdater.h index 643bf746674..01e96cb0a45 100644 --- a/src/plugins/clangrefactoring/refactoringprojectupdater.h +++ b/src/plugins/clangrefactoring/refactoringprojectupdater.h @@ -48,9 +48,7 @@ public: { } - void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId, - const QString &pchFilePath, - long long lastModified) override; + void precompiledHeaderUpdated(ClangBackEnd::ProjectPartId projectPartId) override; void precompiledHeaderRemoved(ClangBackEnd::ProjectPartId projectPartId) override; private: diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp index 77fb5c96ea3..d740b6ca204 100644 --- a/src/plugins/coreplugin/dialogs/shortcutsettings.cpp +++ b/src/plugins/coreplugin/dialogs/shortcutsettings.cpp @@ -552,7 +552,7 @@ bool ShortcutSettingsWidget::markCollisions(ShortcutItem *item) } item->m_item->setForeground(2, hasCollision ? Utils::creatorTheme()->color(Utils::Theme::TextColorError) - : commandList()->palette().window()); + : commandList()->palette().windowText()); return hasCollision; } diff --git a/src/plugins/coreplugin/editortoolbar.cpp b/src/plugins/coreplugin/editortoolbar.cpp index 9f28c33f6d5..9d19415e45c 100644 --- a/src/plugins/coreplugin/editortoolbar.cpp +++ b/src/plugins/coreplugin/editortoolbar.cpp @@ -295,8 +295,10 @@ void EditorToolBar::setToolbarCreationFlags(ToolbarCreationFlags flags) { d->m_isStandalone = flags & FlagsStandalone; if (d->m_isStandalone) { - connect(EditorManager::instance(), &EditorManager::currentEditorChanged, - this, &EditorToolBar::updateEditorListSelection); + connect(EditorManager::instance(), + &EditorManager::currentEditorChanged, + this, + &EditorToolBar::setCurrentEditor); disconnect(d->m_editorList, QOverload::of(&QComboBox::activated), this, &EditorToolBar::listSelectionActivated); @@ -327,15 +329,6 @@ void EditorToolBar::setCurrentEditor(IEditor *editor) updateDocumentStatus(document); } -void EditorToolBar::updateEditorListSelection(IEditor *newSelection) -{ - if (newSelection) { - const Utils::optional index = DocumentModel::rowOfDocument(newSelection->document()); - if (QTC_GUARD(index)) - d->m_editorList->setCurrentIndex(index.value()); - } -} - void EditorToolBar::changeActiveEditor(int row) { EditorManager::activateEditorForEntry(DocumentModel::entryAtRow(row)); diff --git a/src/plugins/coreplugin/editortoolbar.h b/src/plugins/coreplugin/editortoolbar.h index b8d7fad468e..0d82e58303a 100644 --- a/src/plugins/coreplugin/editortoolbar.h +++ b/src/plugins/coreplugin/editortoolbar.h @@ -105,7 +105,6 @@ private: void updateActionShortcuts(); void updateDocumentStatus(IDocument *document); - void updateEditorListSelection(IEditor *newSelection); void fillListContextMenu(QMenu *menu); void updateToolBar(QWidget *toolBar); diff --git a/src/plugins/cpptools/cppfilesettingspage.cpp b/src/plugins/cpptools/cppfilesettingspage.cpp index 187f5d5913e..5ee5ef22cfa 100644 --- a/src/plugins/cpptools/cppfilesettingspage.cpp +++ b/src/plugins/cpptools/cppfilesettingspage.cpp @@ -169,6 +169,7 @@ static bool keyWordReplacement(const QString &keyWord, const QChar ypsilon = QLatin1Char('y'); if (format.count(ypsilon) == 2) format.insert(format.indexOf(ypsilon), QString(2, ypsilon)); + format.replace('/', "\\/"); } *value = QString::fromLatin1("%{CurrentDate:") + format + QLatin1Char('}'); return true; @@ -193,7 +194,6 @@ static void parseLicenseTemplatePlaceholders(QString *t) { int pos = 0; const QChar placeHolder = QLatin1Char('%'); - bool isCompatibilityStyle = false; do { const int placeHolderPos = t->indexOf(placeHolder, pos); if (placeHolderPos == -1) @@ -208,7 +208,6 @@ static void parseLicenseTemplatePlaceholders(QString *t) const QString keyWord = t->mid(placeHolderPos, endPlaceHolderPos + 1 - placeHolderPos); QString replacement; if (keyWordReplacement(keyWord, &replacement)) { - isCompatibilityStyle = true; t->replace(placeHolderPos, keyWord.size(), replacement); pos = placeHolderPos + replacement.size(); } else { @@ -218,8 +217,6 @@ static void parseLicenseTemplatePlaceholders(QString *t) } } while (pos < t->size()); - if (isCompatibilityStyle) - t->replace(QLatin1Char('\\'), QLatin1String("\\\\")); } // Convenience that returns the formatted license template. diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 780787271ce..7e8bf80c81d 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -293,7 +293,7 @@ HelpPluginPrivate::HelpPluginPrivate() cmd = ActionManager::registerAction(action, "Help.ReportBug"); ActionManager::actionContainer(Core::Constants::M_HELP)->addAction(cmd, Core::Constants::G_HELP_SUPPORT); connect(action, &QAction::triggered, this, [] { - QDesktopServices::openUrl(QUrl("https://bugreports.qt.io")); + QDesktopServices::openUrl(QUrl("https://bugreports.qt.io/secure/CreateIssue.jspa?pid=10512")); }); action = new QAction(HelpPlugin::tr("System Information..."), this); diff --git a/src/plugins/perfprofiler/tests/perfresourcecounter_test.cpp b/src/plugins/perfprofiler/tests/perfresourcecounter_test.cpp index 87d905c8809..f242725c357 100644 --- a/src/plugins/perfprofiler/tests/perfresourcecounter_test.cpp +++ b/src/plugins/perfprofiler/tests/perfresourcecounter_test.cpp @@ -140,9 +140,10 @@ void PerfResourceCounterTest::testUnitSized() QList ids; for (int i = 0; i < 10000; ++i) { counter.request(1); - int id = qrand(); + const int id = qrand(); counter.obtain(id); - ids.append(id); + if (id != 0) // Otherwise it's the invalid ID and that means the allocation "failed". + ids.append(id); QCOMPARE(counter.currentTotal(), ids.length()); } QCOMPARE(sum(container), counter.currentTotal()); diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index 3cd6590f206..a725658b9bf 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -30,6 +30,8 @@ #include "desktopdeviceconfigurationwidget.h" #include "desktopprocesssignaloperation.h" +#include + #include #include @@ -58,6 +60,9 @@ DesktopDevice::DesktopDevice() const QString portRange = QString::fromLatin1("%1-%2").arg(DESKTOP_PORT_START).arg(DESKTOP_PORT_END); setFreePorts(Utils::PortList::fromString(portRange)); + setOpenTerminal([](const Utils::Environment &env, const QString &workingDir) { + Core::FileUtils::openTerminal(workingDir, env); + }); } IDevice::DeviceInfo DesktopDevice::deviceInformation() const diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 0faade9f9bf..86d783a6d99 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -153,6 +153,7 @@ public: QList deviceIcons; QList deviceActions; QVariantMap extraData; + IDevice::OpenTerminal openTerminal; }; } // namespace Internal @@ -162,6 +163,11 @@ IDevice::IDevice() : d(new Internal::IDevicePrivate) { } +void IDevice::setOpenTerminal(const IDevice::OpenTerminal &openTerminal) +{ + d->openTerminal = openTerminal; +} + void IDevice::setupId(Origin origin, Core::Id id) { d->origin = origin; @@ -169,6 +175,17 @@ void IDevice::setupId(Origin origin, Core::Id id) d->id = id.isValid() ? id : newId(); } +bool IDevice::canOpenTerminal() const +{ + return bool(d->openTerminal); +} + +void IDevice::openTerminal(const Utils::Environment &env, const QString &workingDir) const +{ + QTC_ASSERT(canOpenTerminal(), return); + d->openTerminal(env, workingDir); +} + IDevice::~IDevice() = default; /*! diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index db750086a5f..b2635440000 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -120,6 +120,7 @@ public: // See cpp file for documentation. class PROJECTEXPLORER_EXPORT IDevice : public QEnableSharedFromThis { + friend class Internal::IDevicePrivate; public: using Ptr = QSharedPointer; using ConstPtr = QSharedPointer; @@ -218,9 +219,15 @@ public: void setupId(Origin origin, Core::Id id = Core::Id()); + bool canOpenTerminal() const; + void openTerminal(const Utils::Environment &env, const QString &workingDir) const; + protected: IDevice(); + using OpenTerminal = std::function; + void setOpenTerminal(const OpenTerminal &openTerminal); + private: IDevice(const IDevice &) = delete; IDevice &operator=(const IDevice &) = delete; diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp index a4b0857820d..bab6ca6adc7 100644 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp +++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp @@ -201,7 +201,9 @@ void SshDeviceProcess::handleConnected() this, &SshDeviceProcess::handleProcessStarted); connect(&d->consoleProcess, &ConsoleProcess::stubStopped, this, [this] { handleProcessFinished(d->consoleProcess.errorString()); }); - d->consoleProcess.setCommand({FilePath::fromString(cmdLine.first()), cmdLine.mid(1)}); + d->consoleProcess.setCommand({FilePath::fromString(cmdLine.first()), + cmdLine.mid(1), + CommandLine::MetaCharMode::Ignore}); d->consoleProcess.start(); } else { connect(d->process.get(), &QSsh::SshRemoteProcess::started, diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 1c3a2071778..2a9dda6659c 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -268,11 +268,20 @@ static Utils::optional buildEnv(const Project *project) return project->activeTarget()->activeBuildConfiguration()->environment(); } -static Utils::optional runEnv(const Project *project) +static bool canOpenTerminalWithRunEnv(const Project *project) { - if (!project || !project->activeTarget() || !project->activeTarget()->activeRunConfiguration()) - return {}; - return project->activeTarget()->activeRunConfiguration()->runnable().environment; + if (!project) + return false; + const Target * const target = project->activeTarget(); + if (!target) + return false; + const RunConfiguration * const runConfig = target->activeRunConfiguration(); + if (!runConfig) + return false; + IDevice::ConstPtr device = runConfig->runnable().device; + if (!device) + device = DeviceKitAspect::device(target->kit()); + return device && device->canOpenTerminal(); } static Target *activeTarget() @@ -382,6 +391,7 @@ public: void updateUnloadProjectMenu(); using EnvironmentGetter = std::function(const Project *project)>; void openTerminalHere(const EnvironmentGetter &env); + void openTerminalHereWithRunEnv(); void invalidateProject(ProjectExplorer::Project *project); @@ -1501,7 +1511,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er connect(dd->m_openTerminalHere, &QAction::triggered, dd, []() { dd->openTerminalHere(sysEnv); }); connect(dd->m_openTerminalHereBuildEnv, &QAction::triggered, dd, []() { dd->openTerminalHere(buildEnv); }); - connect(dd->m_openTerminalHereRunEnv, &QAction::triggered, dd, []() { dd->openTerminalHere(runEnv); }); + connect(dd->m_openTerminalHereRunEnv, &QAction::triggered, dd, []() { dd->openTerminalHereWithRunEnv(); }); connect(dd->m_filePropertiesAction, &QAction::triggered, this, []() { const Node *currentNode = ProjectTree::currentNode(); @@ -3244,7 +3254,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions() Project *project = ProjectTree::currentProject(); m_openTerminalHereBuildEnv->setVisible(bool(buildEnv(project))); - m_openTerminalHereRunEnv->setVisible(bool(runEnv(project))); + m_openTerminalHereRunEnv->setVisible(canOpenTerminalWithRunEnv(project)); if (pn && project) { if (pn == project->rootProjectNode()) { @@ -3583,6 +3593,28 @@ void ProjectExplorerPluginPrivate::openTerminalHere(const EnvironmentGetter &env FileUtils::openTerminal(directoryFor(currentNode), environment.value()); } +void ProjectExplorerPluginPrivate::openTerminalHereWithRunEnv() +{ + const Node *currentNode = ProjectTree::currentNode(); + QTC_ASSERT(currentNode, return); + + const Project * const project = ProjectTree::projectForNode(currentNode); + QTC_ASSERT(project, return); + const Target * const target = project->activeTarget(); + QTC_ASSERT(target, return); + const RunConfiguration * const runConfig = target->activeRunConfiguration(); + QTC_ASSERT(runConfig, return); + + const Runnable runnable = runConfig->runnable(); + IDevice::ConstPtr device = runnable.device; + if (!device) + device = DeviceKitAspect::device(target->kit()); + QTC_ASSERT(device && device->canOpenTerminal(), return); + const QString workingDir = device->type() == Constants::DESKTOP_DEVICE_TYPE + ? directoryFor(currentNode) : runnable.workingDirectory; + device->openTerminal(runnable.environment, workingDir); +} + void ProjectExplorerPluginPrivate::removeFile() { const Node *currentNode = ProjectTree::currentNode(); diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp index ca35bcff682..5259a0d609d 100644 --- a/src/plugins/projectexplorer/projecttree.cpp +++ b/src/plugins/projectexplorer/projecttree.cpp @@ -389,9 +389,15 @@ void ProjectTree::applyTreeManager(FolderNode *folder) bool ProjectTree::hasNode(const Node *node) { return Utils::contains(SessionManager::projects(), [node](const Project *p) { - return p && p->rootProjectNode() && ( - p->containerNode() == node - || p->rootProjectNode()->findNode([node](const Node *n) { return n == node; })); + if (!p) + return false; + if (p->containerNode() == node) + return true; + // When parsing fails we have a living container node but no rootProjectNode. + ProjectNode *pn = p->rootProjectNode(); + if (!pn) + return false; + return pn->findNode([node](const Node *n) { return n == node; }) != nullptr; }); } diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index 27aabb710c0..aff90d75bcf 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -410,9 +410,6 @@ QString QbsProductNode::buildKey() const QVariant QbsProductNode::data(Core::Id role) const { -// if (role == Android::Constants::AndroidExtraLibs) -// return value("ANDROID_EXTRA_LIBS"); - if (role == Android::Constants::AndroidDeploySettingsFile) { for (const auto &artifact : m_qbsProductData.generatedArtifacts()) { if (artifact.fileTags().contains("qt_androiddeployqt_input")) @@ -426,11 +423,9 @@ QVariant QbsProductNode::data(Core::Id role) const for (const auto &artifact : m_qbsProductData.generatedArtifacts()) { if (artifact.fileTags().contains("dynamiclibrary")) { ret << QFileInfo(artifact.filePath()).path(); - qDebug() << artifact.properties().toString(); } } ret.removeDuplicates(); - qDebug() << ret; return ret; } @@ -442,16 +437,8 @@ QVariant QbsProductNode::data(Core::Id role) const return {}; } - if (role == Android::Constants::AndroidApk) { -// qDebug() << m_qbsProductData.name() << m_qbsProductData.targetExecutable() << m_qbsProductData.properties(); -// for (const auto &artifact : m_qbsProductData.installableArtifacts()) { -// qDebug() << artifact.fileTags() << artifact.filePath(); -// } -// for (const auto &artifact : m_qbsProductData.generatedArtifacts()) { -// qDebug() << artifact.fileTags() << artifact.filePath(); -// } + if (role == Android::Constants::AndroidApk) return m_qbsProductData.targetExecutable(); - } return {}; } diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 10a09fe9a5d..c9fce5bb9ad 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -878,8 +878,7 @@ QStringList QmakePriFile::varNames(FileType type, QtSupport::ProFileReader *read QStringList vars; switch (type) { case FileType::Header: - vars << QLatin1String("HEADERS"); - vars << QLatin1String("PRECOMPILED_HEADER"); + vars << "HEADERS" << "OBJECTIVE_HEADERS" << "PRECOMPILED_HEADER"; break; case FileType::Source: { vars << QLatin1String("SOURCES"); @@ -888,12 +887,15 @@ QStringList QmakePriFile::varNames(FileType type, QtSupport::ProFileReader *read QStringList inputs = readerExact->values(var + QLatin1String(".input")); foreach (const QString &input, inputs) // FORMS, RESOURCES, and STATECHARTS are handled below, HEADERS and SOURCES above - if (input != QLatin1String("FORMS") - && input != QLatin1String("STATECHARTS") - && input != QLatin1String("RESOURCES") - && input != QLatin1String("SOURCES") - && input != QLatin1String("HEADERS")) + if (input != "FORMS" + && input != "STATECHARTS" + && input != "RESOURCES" + && input != "SOURCES" + && input != "HEADERS" + && input != "OBJECTIVE_HEADERS" + && input != "PRECOMPILED_HEADER") { vars << input; + } } break; } diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 8730d534525..938a3a404a6 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -524,6 +524,21 @@ void QmakeProject::asyncUpdate() m_asyncUpdateFutureInterface->reportStarted(); + const Kit * const kit = activeTarget() ? activeTarget()->kit() : nullptr; + QtSupport::BaseQtVersion * const qtVersion = QtSupport::QtKitAspect::qtVersion(kit); + if (!qtVersion || !qtVersion->isValid()) { + const QString errorMessage = kit + ? tr("Cannot parse project \"%1\": The currently selected kit \"%2\" does not " + "have a valid Qt.").arg(displayName(), kit->displayName()) + : tr("Cannot parse project \"%1\": No kit selected.").arg(displayName()); + proFileParseError(errorMessage); + m_asyncUpdateFutureInterface->reportCanceled(); + m_asyncUpdateFutureInterface->reportFinished(); + delete m_asyncUpdateFutureInterface; + m_asyncUpdateFutureInterface = nullptr; + return; + } + if (m_asyncUpdateState == AsyncFullUpdatePending) { rootProFile()->asyncUpdate(); } else { diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index 07e758b35ac..ae7400e3825 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -185,6 +185,7 @@ void StatesEditorModel::renameState(int internalNodeId, const QString &newName) newName.isEmpty() ? tr("The empty string as a name is reserved for the base state.") : tr("Name already used in another state")); + reset(); } else { m_statesEditorView->renameState(internalNodeId, newName); } diff --git a/src/plugins/qmldesigner/designercore/include/nodehints.h b/src/plugins/qmldesigner/designercore/include/nodehints.h index 1e8b7d99e41..7fed390ee0a 100644 --- a/src/plugins/qmldesigner/designercore/include/nodehints.h +++ b/src/plugins/qmldesigner/designercore/include/nodehints.h @@ -64,9 +64,11 @@ public: bool isStackedContainer() const; bool canBeReparentedTo(const ModelNode &potenialParent); QString indexPropertyForStackedContainer() const; + QStringList visibleNonDefaultProperties() const; bool takesOverRenderingOfChildren() const; bool visibleInNavigator() const; bool visibleInLibrary() const; + QString forceNonDefaultProperty() const; QHash hints() const; static NodeHints fromModelNode(const ModelNode &modelNode); diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodehints.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodehints.cpp index c6bc6451866..dcb350c4480 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodehints.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodehints.cpp @@ -192,6 +192,19 @@ QString NodeHints::indexPropertyForStackedContainer() const return Internal::evaluateExpression(expression, modelNode(), ModelNode()).toString(); } +QStringList NodeHints::visibleNonDefaultProperties() const +{ + if (!isValid()) + return {}; + + const QString expression = m_hints.value("visibleNonDefaultProperties"); + + if (expression.isEmpty()) + return {}; + + return Internal::evaluateExpression(expression, modelNode(), ModelNode()).toString().split(","); +} + bool NodeHints::takesOverRenderingOfChildren() const { if (!isValid()) @@ -213,6 +226,16 @@ bool NodeHints::visibleInLibrary() const return evaluateBooleanExpression("visibleInLibrary", true); } +QString NodeHints::forceNonDefaultProperty() const +{ + const QString expression = m_hints.value("forceNonDefaultProperty"); + + if (expression.isEmpty()) + return {}; + + return Internal::evaluateExpression(expression, modelNode(), ModelNode()).toString(); +} + QHash NodeHints::hints() const { return m_hints; diff --git a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp index 65ed482bfb1..53e29b7157e 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlobjectnode.cpp @@ -263,7 +263,7 @@ QString QmlObjectNode::stripedTranslatableText(const PropertyName &name) const return regularExpressionPatter.cap(2); return instanceValue(name).toString(); } - return modelNode().variantProperty(name).value().toString(); + return instanceValue(name).toString(); } QString QmlObjectNode::expression(const PropertyName &name) const diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 30c1f9b4759..82399b9b277 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -52,7 +52,7 @@ static Abis detectTargetAbis(const FilePath &sdpPath) if (!sdpPath.fileName().isEmpty()) { Utils::EnvironmentItems environment = QnxUtils::qnxEnvironment(sdpPath.toString()); foreach (const Utils::EnvironmentItem &item, environment) { - if (item.name == QLatin1Literal("QNX_TARGET")) + if (item.name == QLatin1String("QNX_TARGET")) qnxTarget = FilePath::fromString(item.value); } } diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index e6b22eb4bbd..6e05739c019 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -196,9 +196,38 @@ LinuxDevice::LinuxDevice() } }}); + setOpenTerminal([this](const Utils::Environment &env, const QString &workingDir) { + DeviceProcess * const proc = createProcess(nullptr); + QObject::connect(proc, &DeviceProcess::finished, [proc] { + if (!proc->errorString().isEmpty()) { + Core::MessageManager::write(tr("Error running remote shell: %1") + .arg(proc->errorString()), + Core::MessageManager::ModeSwitch); + } + proc->deleteLater(); + }); + QObject::connect(proc, &DeviceProcess::error, [proc] { + Core::MessageManager::write(tr("Error starting remote shell."), + Core::MessageManager::ModeSwitch); + proc->deleteLater(); + }); + Runnable runnable; + runnable.device = sharedFromThis(); + runnable.environment = env; + runnable.workingDirectory = workingDir; + + // It seems we cannot pass an environment to OpenSSH dynamically + // without specifying an executable. + if (env.size() > 0) + runnable.executable = "/bin/sh"; + + proc->setRunInTerminal(true); + proc->start(runnable); + }); + if (Utils::HostOsInfo::isAnyUnixHost()) { addDeviceAction({tr("Open Remote Shell"), [](const IDevice::Ptr &device, QWidget *) { - device.staticCast()->startRemoteShell(Utils::Environment()); + device->openTerminal(Utils::Environment(), QString()); }}); } } @@ -268,36 +297,6 @@ bool LinuxDevice::supportsRSync() const return extraData("RemoteLinux.SupportsRSync").toBool(); } -void LinuxDevice::startRemoteShell(const Utils::Environment &env) const -{ - DeviceProcess * const proc = createProcess(nullptr); - QObject::connect(proc, &DeviceProcess::finished, [proc] { - if (!proc->errorString().isEmpty()) { - Core::MessageManager::write(tr("Error running remote shell: %1") - .arg(proc->errorString()), - Core::MessageManager::ModeSwitch); - } - proc->deleteLater(); - }); - QObject::connect(proc, &DeviceProcess::error, [proc] { - Core::MessageManager::write(tr("Error starting remote shell."), - Core::MessageManager::ModeSwitch); - proc->deleteLater(); - }); - Runnable runnable; - runnable.device = sharedFromThis(); - runnable.environment = env; - - // It seems we cannot pass an environment to OpenSSH dynamically - // without specifying an executable. - if (env.size() > 0) - runnable.executable = "/bin/sh"; - - proc->setRunInTerminal(true); - proc->start(runnable); -} - - namespace Internal { // Factory diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index c8e8d8bf314..18faf4ae059 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -32,8 +32,6 @@ #include -namespace Utils { class Environment; } - namespace RemoteLinux { class REMOTELINUX_EXPORT LinuxDevice : public ProjectExplorer::IDevice @@ -64,8 +62,6 @@ public: void setSupportsRsync(bool supportsRsync); bool supportsRSync() const; - void startRemoteShell(const Utils::Environment &env) const; - protected: LinuxDevice(); }; diff --git a/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp b/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp index b244a5e129c..0d94cf3ffab 100644 --- a/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp +++ b/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp @@ -78,7 +78,7 @@ RemoteLinuxEnvironmentAspectWidget::RemoteLinuxEnvironmentAspectWidget } const auto linuxDevice = device.dynamicCast(); QTC_ASSERT(linuxDevice, return); - linuxDevice->startRemoteShell(env); + linuxDevice->openTerminal(env, QString()); }; envWidget()->setOpenTerminalFunc(openTerminalFunc); } diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 864acf4e83f..cc220576604 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -226,9 +226,9 @@ void StudioWelcomePlugin::extensionsInitialized() s_view->setWindowModality(Qt::ApplicationModal); s_view->engine()->addImportPath("qrc:/studiofonts"); #ifdef QT_DEBUG - s_view->engine()->addImportPath(QLatin1Literal(STUDIO_QML_PATH) + s_view->engine()->addImportPath(QLatin1String(STUDIO_QML_PATH) + "splashscreen/imports"); - s_view->setSource(QUrl::fromLocalFile(QLatin1Literal(STUDIO_QML_PATH) + s_view->setSource(QUrl::fromLocalFile(QLatin1String(STUDIO_QML_PATH) + "splashscreen/main.qml")); #else s_view->engine()->addImportPath("qrc:/qml/splashscreen/imports"); @@ -287,9 +287,9 @@ WelcomeMode::WelcomeMode() m_modeWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); m_modeWidget->engine()->addImportPath("qrc:/studiofonts"); #ifdef QT_DEBUG - m_modeWidget->engine()->addImportPath(QLatin1Literal(STUDIO_QML_PATH) + m_modeWidget->engine()->addImportPath(QLatin1String(STUDIO_QML_PATH) + "welcomepage/imports"); - m_modeWidget->setSource(QUrl::fromLocalFile(QLatin1Literal(STUDIO_QML_PATH) + m_modeWidget->setSource(QUrl::fromLocalFile(QLatin1String(STUDIO_QML_PATH) + "welcomepage/main.qml")); #else m_modeWidget->engine()->addImportPath("qrc:/qml/welcomepage/imports"); diff --git a/src/plugins/todo/todoitemsprovider.cpp b/src/plugins/todo/todoitemsprovider.cpp index ef2523c3469..c2f958bb4ee 100644 --- a/src/plugins/todo/todoitemsprovider.cpp +++ b/src/plugins/todo/todoitemsprovider.cpp @@ -45,6 +45,7 @@ #include using namespace ProjectExplorer; +using namespace Utils; namespace Todo { namespace Internal { @@ -90,7 +91,7 @@ void TodoItemsProvider::updateList() // Show only items of the current file if any if (m_settings.scanningScope == ScanningScopeCurrentFile) { if (m_currentEditor) - m_itemsList = m_itemsHash.value(m_currentEditor->document()->filePath().toString()); + m_itemsList = m_itemsHash.value(m_currentEditor->document()->filePath()); // Show only items of the current sub-project } else if (m_settings.scanningScope == ScanningScopeSubProject) { if (m_startupProject) @@ -121,21 +122,19 @@ void TodoItemsProvider::createScanners() void TodoItemsProvider::setItemsListWithinStartupProject() { - QHashIterator > it(m_itemsHash); - const QSet fileNames - = QSet::fromList(Utils::transform(m_startupProject->files(Project::SourceFiles), - &Utils::FilePath::toString)); + QHashIterator > it(m_itemsHash); + const auto filePaths = QSet::fromList(m_startupProject->files(Project::SourceFiles)); QVariantMap settings = m_startupProject->namedSettings(Constants::SETTINGS_NAME_KEY).toMap(); while (it.hasNext()) { it.next(); - QString fileName = it.key(); - if (fileNames.contains(fileName)) { + const FilePath filePath = it.key(); + if (filePaths.contains(filePath)) { bool skip = false; for (const QVariant &pattern : settings[Constants::EXCLUDES_LIST_KEY].toList()) { QRegExp re(pattern.toString()); - if (re.indexIn(fileName) != -1) { + if (re.indexIn(filePath.toString()) != -1) { skip = true; break; } @@ -154,22 +153,19 @@ void TodoItemsProvider::setItemsListWithinSubproject() ProjectNode *projectNode = node->parentProjectNode(); if (projectNode) { // FIXME: The name doesn't match the implementation that lists all files. - QSet subprojectFileNames; + QSet subprojectFileNames; projectNode->forEachGenericNode([&](Node *node) { subprojectFileNames.insert(node->filePath()); }); // files must be both in the current subproject and the startup-project. - const QSet fileNames - = QSet::fromList(Utils::transform(m_startupProject->files(Project::SourceFiles), - &Utils::FilePath::toString)); - QHashIterator > it(m_itemsHash); + const auto fileNames + = QSet::fromList(m_startupProject->files(Project::SourceFiles)); + QHashIterator > it(m_itemsHash); while (it.hasNext()) { it.next(); - if (subprojectFileNames.contains(Utils::FilePath::fromString(it.key())) - && fileNames.contains(it.key())) { + if (subprojectFileNames.contains(it.key()) && fileNames.contains(it.key())) m_itemsList << it.value(); - } } } } @@ -178,7 +174,7 @@ void TodoItemsProvider::setItemsListWithinSubproject() void TodoItemsProvider::itemsFetched(const QString &fileName, const QList &items) { // Replace old items with new ones - m_itemsHash.insert(fileName, items); + m_itemsHash.insert(FilePath::fromString(fileName), items); m_shouldUpdateList = true; } diff --git a/src/plugins/todo/todoitemsprovider.h b/src/plugins/todo/todoitemsprovider.h index 234025bfec7..f2d1f33a104 100644 --- a/src/plugins/todo/todoitemsprovider.h +++ b/src/plugins/todo/todoitemsprovider.h @@ -60,7 +60,7 @@ private: TodoItemsModel *m_itemsModel; // All to-do items are stored here regardless current scanning scope - QHash > m_itemsHash; + QHash > m_itemsHash; // This list contains only those to-do items that are within current scanning scope QList m_itemsList; diff --git a/src/share/3rdparty/CMakeLists.txt b/src/share/3rdparty/CMakeLists.txt index 39791681244..ede2157426e 100644 --- a/src/share/3rdparty/CMakeLists.txt +++ b/src/share/3rdparty/CMakeLists.txt @@ -2,3 +2,12 @@ install( DIRECTORY fonts DESTINATION "${IDE_DATA_PATH}" ) + +add_custom_target(copy_fonts_to_builddir ALL VERBATIM) +add_custom_command(TARGET copy_fonts_to_builddir POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory fonts + "${PROJECT_BINARY_DIR}/${IDE_DATA_PATH}/fonts" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT Copy files into build directory + VERBATIM +) diff --git a/src/tools/clangbackend/source/CMakeLists.txt b/src/tools/clangbackend/source/CMakeLists.txt index f8cf5d5de92..fe0ab54deb6 100644 --- a/src/tools/clangbackend/source/CMakeLists.txt +++ b/src/tools/clangbackend/source/CMakeLists.txt @@ -1,6 +1,6 @@ add_qtc_library(clangbackend_lib STATIC DEPENDS libclang Sqlite ClangSupport - DEFINES CLANGSUPPORT_BUILD_LIB + PUBLIC_DEFINES CLANGSUPPORT_BUILD_LIB PUBLIC_INCLUDES ${CLANG_INCLUDE_DIRS} SOURCES diff --git a/src/tools/clangpchmanagerbackend/source/CMakeLists.txt b/src/tools/clangpchmanagerbackend/source/CMakeLists.txt index aa3003c5ca7..76973c6a21d 100644 --- a/src/tools/clangpchmanagerbackend/source/CMakeLists.txt +++ b/src/tools/clangpchmanagerbackend/source/CMakeLists.txt @@ -1,7 +1,7 @@ add_qtc_library(clangpchmanagerbackend_lib STATIC DEPENDS clangrefactoringbackend_lib ClangSupport PUBLIC_DEPENDS libclang - DEFINES CLANGSUPPORT_BUILD_LIB + PUBLIC_DEFINES CLANGSUPPORT_BUILD_LIB PUBLIC_INCLUDES ${CLANG_INCLUDE_DIRS} SOURCES diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h index e7269dd0f94..8c8c51a6cd2 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorage.h @@ -66,6 +66,12 @@ public: } } + FilePathIds fetchSources(ProjectPartId projectPartId) const override + { + return fetchProjectPartsFilesStatement.template values(1024, + projectPartId.projectPathId); + } + void insertOrUpdateFileStatuses(const FileStatuses &fileStatuses) override { WriteStatement &statement = insertOrUpdateFileStatusesStatement; @@ -246,6 +252,8 @@ public: "CONFLICT(sourceId, projectPartId) DO UPDATE SET sourceType = ?003, " "hasMissingIncludes = ?004", database}; + mutable ReadStatement fetchProjectPartsFilesStatement{ + "SELECT sourceId FROM projectPartsFiles WHERE projectPartId = ? ORDER BY sourceId", database}; mutable ReadStatement fetchSourceDependenciesStatement{ "WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION " "SELECT dependencySourceId FROM sourceDependencies, " diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h index a56e88b1f27..1166564b329 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesstorageinterface.h @@ -56,6 +56,7 @@ public: virtual UsedMacros fetchUsedMacros(FilePathId sourceId) const = 0; virtual ProjectPartId fetchProjectPartId(Utils::SmallStringView projectPartName) = 0; virtual void updatePchCreationTimeStamp(long long pchCreationTimeStamp, ProjectPartId projectPartId) = 0; + virtual FilePathIds fetchSources(ProjectPartId projectPartId) const = 0; protected: ~BuildDependenciesStorageInterface() = default; diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp index 2bd0b87af0d..b2c6cf8f86b 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp +++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp @@ -129,8 +129,7 @@ void BuildDependencyCollector::collect() auto action = std::make_unique(m_buildDependency, m_filePathCache, - m_excludedFilePaths, - m_sourcesManager); + m_excludedFilePaths); tool.run(action.get()); } diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.h b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h index f8aaa8f07cd..084024c8212 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependencycollector.h +++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h @@ -95,7 +95,6 @@ private: BuildDependency m_buildDependency; ClangBackEnd::FilePaths m_excludedFilePaths; Utils::SmallStringVector m_directories; - SourcesManager m_sourcesManager; const FilePathCachingInterface &m_filePathCache; const GeneratedFilesInterface &m_generatedFiles; const Environment &m_environment; diff --git a/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h index fa1a10e79c3..3e98dc2483b 100644 --- a/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h @@ -40,15 +40,13 @@ class CollectBuildDependencyAction final : public clang::PreprocessOnlyAction { public: CollectBuildDependencyAction(BuildDependency &buildDependency, - const FilePathCachingInterface &filePathCache, - std::vector &excludedIncludeUID, - std::vector &alreadyIncludedFileUIDs, - SourcesManager &sourcesManager) - : m_buildDependency(buildDependency), - m_filePathCache(filePathCache), - m_excludedIncludeUID(excludedIncludeUID), - m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs), - m_sourcesManager(sourcesManager) + const FilePathCachingInterface &filePathCache, + std::vector &excludedIncludeUID, + std::vector &alreadyIncludedFileUIDs) + : m_buildDependency(buildDependency) + , m_filePathCache(filePathCache) + , m_excludedIncludeUID(excludedIncludeUID) + , m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs) { } @@ -66,7 +64,6 @@ public: m_excludedIncludeUID, m_alreadyIncludedFileUIDs, compilerInstance.getSourceManager(), - m_sourcesManager, compilerInstance.getPreprocessorPtr()); preprocessor.addPPCallbacks( @@ -88,7 +85,6 @@ private: const FilePathCachingInterface &m_filePathCache; std::vector &m_excludedIncludeUID; std::vector &m_alreadyIncludedFileUIDs; - SourcesManager &m_sourcesManager; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h index 9db095bd75f..8583ff7a158 100644 --- a/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h @@ -54,12 +54,10 @@ public: const std::vector &excludedIncludeUID, std::vector &alreadyIncludedFileUIDs, clang::SourceManager &sourceManager, - SourcesManager &sourcesManager, std::shared_ptr preprocessor) : CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(buildDependency.usedMacros, filePathCache, sourceManager, - sourcesManager, preprocessor, buildDependency.sourceDependencies, buildDependency.sourceFiles, @@ -189,7 +187,6 @@ public: { filterOutHeaderGuards(); mergeUsedMacros(); - m_sourcesManager.updateModifiedTimeStamps(); filterOutIncludesWithMissingIncludes(); } diff --git a/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h index 4f28d0f7c82..471291ee90d 100644 --- a/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h @@ -38,13 +38,11 @@ class CollectBuildDependencyToolAction final : public clang::tooling::FrontendAc { public: CollectBuildDependencyToolAction(BuildDependency &buildDependency, - const FilePathCachingInterface &filePathCache, - const ClangBackEnd::FilePaths &excludedIncludes, - SourcesManager &sourcesManager) - : m_buildDependency(buildDependency), - m_filePathCache(filePathCache), - m_excludedFilePaths(excludedIncludes), - m_sourcesManager(sourcesManager) + const FilePathCachingInterface &filePathCache, + const ClangBackEnd::FilePaths &excludedIncludes) + : m_buildDependency(buildDependency) + , m_filePathCache(filePathCache) + , m_excludedFilePaths(excludedIncludes) {} @@ -67,8 +65,7 @@ public: return new CollectBuildDependencyAction(m_buildDependency, m_filePathCache, m_excludedIncludeUIDs, - m_alreadyIncludedFileUIDs, - m_sourcesManager); + m_alreadyIncludedFileUIDs); } std::vector generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const @@ -95,7 +92,6 @@ private: BuildDependency &m_buildDependency; const FilePathCachingInterface &m_filePathCache; const ClangBackEnd::FilePaths &m_excludedFilePaths; - SourcesManager &m_sourcesManager; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectusedmacroactionfactory.h b/src/tools/clangpchmanagerbackend/source/collectusedmacroactionfactory.h index b3f1cc0029a..423d5f88764 100644 --- a/src/tools/clangpchmanagerbackend/source/collectusedmacroactionfactory.h +++ b/src/tools/clangpchmanagerbackend/source/collectusedmacroactionfactory.h @@ -39,13 +39,11 @@ class CollectUsedMacrosToolActionFactory final : public clang::tooling::Frontend public: CollectUsedMacrosToolActionFactory(UsedMacros &usedMacros, FilePathCachingInterface &filePathCache, - SourcesManager &sourcesManager, SourceDependencies &sourceDependencies, FilePathIds &sourceFiles, FileStatuses &fileStatuses) : m_usedMacros(usedMacros), m_filePathCache(filePathCache), - m_sourcesManager(sourcesManager), m_sourceDependencies(sourceDependencies), m_sourceFiles(sourceFiles), m_fileStatuses(fileStatuses) @@ -67,7 +65,6 @@ public: { return new CollectUsedMacrosAction(m_usedMacros, m_filePathCache, - m_sourcesManager, m_sourceDependencies, m_sourceFiles, m_fileStatuses); @@ -76,7 +73,6 @@ public: private: UsedMacros &m_usedMacros; FilePathCachingInterface &m_filePathCache; - SourcesManager &m_sourcesManager; SourceDependencies &m_sourceDependencies; FilePathIds &m_sourceFiles; FileStatuses &m_fileStatuses; diff --git a/src/tools/clangpchmanagerbackend/source/collectusedmacrosaction.h b/src/tools/clangpchmanagerbackend/source/collectusedmacrosaction.h index 4134d41d410..8f50e5a2308 100644 --- a/src/tools/clangpchmanagerbackend/source/collectusedmacrosaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectusedmacrosaction.h @@ -41,13 +41,11 @@ class CollectUsedMacrosAction final : public clang::PreprocessOnlyAction public: CollectUsedMacrosAction(UsedMacros &usedMacros, FilePathCachingInterface &filePathCache, - SourcesManager &sourcesManager, SourceDependencies &sourceDependencies, FilePathIds &sourceFiles, FileStatuses &fileStatuses) : m_usedMacros(usedMacros), m_filePathCache(filePathCache), - m_sourcesManager(sourcesManager), m_sourceDependencies(sourceDependencies), m_sourceFiles(sourceFiles), m_fileStatuses(fileStatuses) @@ -65,7 +63,6 @@ public: m_usedMacros, m_filePathCache, compilerInstance.getSourceManager(), - m_sourcesManager, compilerInstance.getPreprocessorPtr(), m_sourceDependencies, m_sourceFiles, @@ -87,7 +84,6 @@ public: private: UsedMacros &m_usedMacros; FilePathCachingInterface &m_filePathCache; - SourcesManager &m_sourcesManager; SourceDependencies &m_sourceDependencies; FilePathIds &m_sourceFiles; FileStatuses &m_fileStatuses; diff --git a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h index b8ea406df0f..5dc630de182 100644 --- a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h @@ -54,17 +54,16 @@ public: CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(UsedMacros &usedMacros, const FilePathCachingInterface &filePathCache, const clang::SourceManager &sourceManager, - SourcesManager &sourcesManager, std::shared_ptr preprocessor, SourceDependencies &sourceDependencies, FilePathIds &sourceFiles, FileStatuses &fileStatuses) - : SymbolsVisitorBase(filePathCache, &sourceManager, sourcesManager), - m_usedMacros(usedMacros), - m_preprocessor(preprocessor), - m_sourceDependencies(sourceDependencies), - m_sourceFiles(sourceFiles), - m_fileStatuses(fileStatuses) + : SymbolsVisitorBase(filePathCache, &sourceManager, m_filePathIndices) + , m_usedMacros(usedMacros) + , m_preprocessor(preprocessor) + , m_sourceDependencies(sourceDependencies) + , m_sourceFiles(sourceFiles) + , m_fileStatuses(fileStatuses) {} void addSourceFile(const clang::FileEntry *fileEntry) @@ -166,6 +165,7 @@ public: private: UsedMacros m_maybeUsedMacros; + FilePathIds m_filePathIndices; UsedMacros &m_usedMacros; std::shared_ptr m_preprocessor; SourceDependencies &m_sourceDependencies; @@ -248,7 +248,6 @@ public: { filterOutHeaderGuards(); mergeUsedMacros(); - m_sourcesManager.updateModifiedTimeStamps(); } private: diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 9dd1bf36476..cd7b492868d 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -113,8 +113,11 @@ Utils::SmallStringVector PchCreator::generateClangCompilerArguments(const PchTas void PchCreator::generatePch(PchTask &&pchTask) { m_projectPartPch.projectPartId = pchTask.projectPartId(); - m_projectPartPch.lastModified = QDateTime::currentSecsSinceEpoch(); + + if (pchTask.includes.empty()) + return; + auto content = generatePchIncludeFileContent(pchTask.includes); auto pchOutputPath = generatePchFilePath(); @@ -180,7 +183,7 @@ void PchCreator::doInMainThreadAfterFinished() m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified, m_projectPartPch.projectPartId); m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingSources}}); - m_pchManagerClient.precompiledHeadersUpdated({m_projectPartPch}); + m_pchManagerClient.precompiledHeadersUpdated({m_projectPartPch.projectPartId}); } } diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp index c1c12121aac..9cce6ef4694 100644 --- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -57,18 +58,29 @@ void PchManagerServer::end() QCoreApplication::exit(); } +namespace { +ProjectPartIds toProjectPartIds(const ProjectPartContainers &projectParts) +{ + return Utils::transform(projectParts, [](const auto &projectPart) { + return projectPart.projectPartId; + }); +} +} // namespace + void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message) { m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments); - ProjectPartContainers newProjectParts = m_projectPartsManager.update(message.takeProjectsParts()); + auto upToDateProjectParts = m_projectPartsManager.update(message.takeProjectsParts()); if (m_generatedFiles.isValid()) { - m_pchTaskGenerator.addProjectParts(std::move(newProjectParts), + m_pchTaskGenerator.addProjectParts(std::move(upToDateProjectParts.notUpToDate), std::move(message.toolChainArguments)); } else { - m_projectPartsManager.updateDeferred(newProjectParts); + m_projectPartsManager.updateDeferred(upToDateProjectParts.notUpToDate); } + + client()->precompiledHeadersUpdated(toProjectPartIds(upToDateProjectParts.upToDate)); } void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message) diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp index 1edbe15806b..b9d6a48fe39 100644 --- a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp @@ -33,6 +33,8 @@ #include +#include + namespace ClangBackEnd { void PchTaskQueue::addPchTasks(PchTasks &&newPchTasks, PchTasks &destination) @@ -145,7 +147,6 @@ std::vector PchTaskQueue::createProjectTasks(PchTasks &&pchT auto convert = [this](auto &&pchTask) { return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) mutable { const auto projectPartId = pchTask.projectPartId(); - if (pchTask.includes.size()) { pchTask.systemPchPath = m_precompiledHeaderStorage.fetchSystemPrecompiledHeaderPath( projectPartId); pchTask.preIncludeSearchPath = m_environment.preIncludeSearchPath(); @@ -157,9 +158,6 @@ std::vector PchTaskQueue::createProjectTasks(PchTasks &&pchT m_precompiledHeaderStorage.insertProjectPrecompiledHeader( projectPartId, projectPartPch.pchPath, projectPartPch.lastModified); } - } else { - m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId); - } }; }; @@ -179,7 +177,6 @@ std::vector PchTaskQueue::createSystemTasks(PchTasks &&pchTa auto convert = [this](auto &&pchTask) { return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) mutable { const auto projectPartIds = pchTask.projectPartIds; - if (pchTask.includes.size()) { pchTask.preIncludeSearchPath = m_environment.preIncludeSearchPath(); pchCreator.generatePch(std::move(pchTask)); const auto &projectPartPch = pchCreator.projectPartPch(); @@ -189,9 +186,6 @@ std::vector PchTaskQueue::createSystemTasks(PchTasks &&pchTa m_precompiledHeaderStorage.insertSystemPrecompiledHeaders( projectPartIds, projectPartPch.pchPath, projectPartPch.lastModified); } - } else { - m_precompiledHeaderStorage.deleteSystemPrecompiledHeaders(projectPartIds); - } }; }; diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp index cc4ca53d7d5..191a13e16b9 100644 --- a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp +++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.cpp @@ -44,34 +44,35 @@ ProjectPartIds toProjectPartIds(const ProjectPartContainers &projectsParts) return ids; } -ProjectPartContainers ProjectPartsManager::update(ProjectPartContainers &&projectsParts) +ProjectPartsManager::UpToDataProjectParts ProjectPartsManager::update(ProjectPartContainers &&projectsParts) { - auto updatedProjectParts = filterNewProjectParts(std::move(projectsParts), m_projectParts); + auto notUpToDateProjectParts = filterProjectParts(projectsParts, m_projectParts); - if (updatedProjectParts.empty()) - return {}; + if (notUpToDateProjectParts.empty()) + return {std::move(projectsParts), {}}; auto persistentProjectParts = m_projectPartsStorage.fetchProjectParts( - toProjectPartIds(updatedProjectParts)); + toProjectPartIds(notUpToDateProjectParts)); if (persistentProjectParts.size() > 0) { mergeProjectParts(persistentProjectParts); - updatedProjectParts = filterNewProjectParts(std::move(updatedProjectParts), - persistentProjectParts); + notUpToDateProjectParts = filterProjectParts(notUpToDateProjectParts, persistentProjectParts); - if (updatedProjectParts.empty()) + if (notUpToDateProjectParts.empty()) return {}; } - m_projectPartsStorage.updateProjectParts(updatedProjectParts); - m_projectPartsStorage.resetIndexingTimeStamps(updatedProjectParts); + m_projectPartsStorage.updateProjectParts(notUpToDateProjectParts); + m_projectPartsStorage.resetIndexingTimeStamps(notUpToDateProjectParts); m_precompiledHeaderStorage.deleteProjectPrecompiledHeaders( - toProjectPartIds(updatedProjectParts)); + toProjectPartIds(notUpToDateProjectParts)); - mergeProjectParts(updatedProjectParts); + mergeProjectParts(notUpToDateProjectParts); - return updatedProjectParts; + auto upToDateProjectParts = filterProjectParts(projectsParts, notUpToDateProjectParts); + + return {upToDateProjectParts, notUpToDateProjectParts}; } void ProjectPartsManager::remove(const ProjectPartIds &projectPartIds) @@ -176,8 +177,8 @@ ProjectPartContainers ProjectPartsManager::deferredUpdates() return deferredProjectParts; } -ProjectPartContainers ProjectPartsManager::filterNewProjectParts( - ProjectPartContainers &&projectsParts, const ProjectPartContainers &oldProjectParts) +ProjectPartContainers ProjectPartsManager::filterProjectParts( + const ProjectPartContainers &projectsParts, const ProjectPartContainers &oldProjectParts) { ProjectPartContainers updatedProjectPartContainers; updatedProjectPartContainers.reserve(projectsParts.size()); diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h index 323e6c68253..35d9e41c1cc 100644 --- a/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h +++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanager.h @@ -36,6 +36,7 @@ namespace ClangBackEnd { inline namespace Pch { + class ProjectPartsManager final : public ProjectPartsManagerInterface { public: @@ -45,14 +46,14 @@ public: , m_precompiledHeaderStorage(precompiledHeaderStorage) {} - ProjectPartContainers update(ProjectPartContainers &&projectsParts) override; + UpToDataProjectParts update(ProjectPartContainers &&projectsParts) override; void remove(const ProjectPartIds &projectPartIds) override; ProjectPartContainers projects(const ProjectPartIds &projectPartIds) const override; void updateDeferred(const ProjectPartContainers &projectsParts) override; ProjectPartContainers deferredUpdates() override; - static ProjectPartContainers filterNewProjectParts(ProjectPartContainers &&newProjectsParts, - const ProjectPartContainers &oldProjectParts); + static ProjectPartContainers filterProjectParts(const ProjectPartContainers &newProjectsParts, + const ProjectPartContainers &oldProjectParts); void mergeProjectParts(const ProjectPartContainers &projectsParts); const ProjectPartContainers &projectParts() const; diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h b/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h index ee80173f8a9..54bae58c1ad 100644 --- a/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h +++ b/src/tools/clangpchmanagerbackend/source/projectpartsmanagerinterface.h @@ -32,11 +32,18 @@ namespace ClangBackEnd { class ProjectPartsManagerInterface { public: + class UpToDataProjectParts + { + public: + ProjectPartContainers upToDate; + ProjectPartContainers notUpToDate; + }; + ProjectPartsManagerInterface() = default; ProjectPartsManagerInterface(const ProjectPartsManagerInterface &) = delete; ProjectPartsManagerInterface &operator=(const ProjectPartsManagerInterface &) = delete; - virtual ProjectPartContainers update(ProjectPartContainers &&projectsParts) = 0; + virtual UpToDataProjectParts update(ProjectPartContainers &&projectsParts) = 0; virtual void remove(const ProjectPartIds &projectPartIds) = 0; virtual ProjectPartContainers projects(const ProjectPartIds &projectPartIds) const = 0; virtual void updateDeferred(const ProjectPartContainers &projectsParts) = 0; diff --git a/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.cpp b/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.cpp index b26b2b801c5..770d46f5e14 100644 --- a/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.cpp +++ b/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.cpp @@ -48,7 +48,6 @@ void UsedMacroAndSourcesCollector::collect() auto action = std::make_unique( m_usedMacros, m_filePathCache, - m_sourcesManager, m_sourceDependencies, m_sourceFiles, m_fileStatuses); diff --git a/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.h b/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.h index a5b5749c127..9b72201fbb6 100644 --- a/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.h +++ b/src/tools/clangpchmanagerbackend/source/usedmacrosandsourcescollector.h @@ -74,7 +74,6 @@ public: private: ClangTool m_clangTool; - SourcesManager m_sourcesManager; UsedMacros m_usedMacros; FilePathCachingInterface &m_filePathCache; FilePathIds m_sourceFiles; diff --git a/src/tools/clangrefactoringbackend/source/CMakeLists.txt b/src/tools/clangrefactoringbackend/source/CMakeLists.txt index 213ce6ffd76..d43472fd60b 100644 --- a/src/tools/clangrefactoringbackend/source/CMakeLists.txt +++ b/src/tools/clangrefactoringbackend/source/CMakeLists.txt @@ -6,7 +6,7 @@ add_qtc_library(clangrefactoringbackend_lib STATIC clangHandleCXX clangIndex clangLex clangSerialization clangTooling clangQuery ClangSupport - DEFINES CLANGSUPPORT_BUILD_LIB + PUBLIC_DEFINES CLANGSUPPORT_BUILD_LIB PUBLIC_INCLUDES ${CLANG_INCLUDE_DIRS} "../../clangpchmanagerbackend/source" @@ -20,6 +20,7 @@ add_qtc_library(clangrefactoringbackend_lib STATIC collectsymbolsaction.cpp collectsymbolsaction.h filestatus.h filestatuscache.cpp filestatuscache.h + filestatuspreprocessorcallbacks.cpp filestatuspreprocessorcallbacks.h findcursorusr.h findlocationsofusrs.h findusrforcursoraction.cpp findusrforcursoraction.h diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri index fcac51f226d..e7e83da7884 100644 --- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri +++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri @@ -2,6 +2,7 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/clangrefactoringbackend_global.h \ + $$PWD/filestatuspreprocessorcallbacks.h \ $$PWD/sourcerangefilter.h \ $$PWD/symbolindexer.h \ $$PWD/symbolentry.h \ @@ -64,6 +65,7 @@ HEADERS += \ } SOURCES += \ + $$PWD/filestatuspreprocessorcallbacks.cpp \ $$PWD/sourcerangefilter.cpp \ $$PWD/symbolindexer.cpp \ $$PWD/filestatuscache.cpp diff --git a/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h b/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h index 1d16b0f5e1c..b0d59607e23 100644 --- a/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h +++ b/src/tools/clangrefactoringbackend/source/collectmacrospreprocessorcallbacks.h @@ -56,18 +56,16 @@ public: SourceDependencies &sourceDependencies, FilePathCachingInterface &filePathCache, const clang::SourceManager &sourceManager, - std::shared_ptr &&preprocessor, - SourcesManager &sourcesManager) + std::shared_ptr &&preprocessor) : CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(usedMacros, filePathCache, sourceManager, - sourcesManager, std::move(preprocessor), sourceDependencies, sourceFiles, - fileStatuses), - m_symbolEntries(symbolEntries), - m_sourceLocationEntries(sourceLocationEntries) + fileStatuses) + , m_symbolEntries(symbolEntries) + , m_sourceLocationEntries(sourceLocationEntries) { } @@ -88,17 +86,15 @@ public: } void InclusionDirective(clang::SourceLocation hashLocation, - const clang::Token &/*includeToken*/, + const clang::Token & /*includeToken*/, llvm::StringRef /*fileName*/, bool /*isAngled*/, clang::CharSourceRange /*fileNameRange*/, const clang::FileEntry *file, llvm::StringRef /*searchPath*/, llvm::StringRef /*relativePath*/, - const clang::Module * /*imported*/ -#if LLVM_VERSION_MAJOR >= 7 - , clang::SrcMgr::CharacteristicKind /*fileType*/ -#endif + const clang::Module * /*imported*/, + clang::SrcMgr::CharacteristicKind /*fileType*/ ) override { if (!m_skipInclude && file) @@ -174,7 +170,6 @@ public: { filterOutHeaderGuards(); mergeUsedMacros(); - m_sourcesManager.updateModifiedTimeStamps(); } static const clang::MacroInfo *firstMacroInfo(const clang::MacroDirective *macroDirective) diff --git a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp index d96fb05026c..d360b727c4b 100644 --- a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp +++ b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.cpp @@ -34,16 +34,15 @@ namespace ClangBackEnd { bool CollectMacrosSourceFileCallbacks::handleBeginSource(clang::CompilerInstance &compilerInstance) { auto callbacks = std::make_unique( - m_symbolEntries, - m_sourceLocationEntries, - m_sourceFiles, - m_usedMacros, - m_fileStatuses, - m_sourceDependencies, - m_filePathCache, - compilerInstance.getSourceManager(), - compilerInstance.getPreprocessorPtr(), - m_sourcesManager); + m_symbolEntries, + m_sourceLocationEntries, + m_sourceFiles, + m_usedMacros, + m_fileStatuses, + m_sourceDependencies, + m_filePathCache, + compilerInstance.getSourceManager(), + compilerInstance.getPreprocessorPtr()); compilerInstance.getPreprocessorPtr()->addPPCallbacks(std::move(callbacks)); diff --git a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h index 23922381065..16ba5a4f536 100644 --- a/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h +++ b/src/tools/clangrefactoringbackend/source/collectmacrossourcefilecallbacks.h @@ -44,12 +44,10 @@ class CollectMacrosSourceFileCallbacks : public clang::tooling::SourceFileCallba public: CollectMacrosSourceFileCallbacks(SymbolEntries &symbolEntries, SourceLocationEntries &sourceLocationEntries, - FilePathCachingInterface &filePathCache, - SourcesManager &sourcesManager) - : m_symbolEntries(symbolEntries), - m_sourceLocationEntries(sourceLocationEntries), - m_filePathCache(filePathCache), - m_sourcesManager(sourcesManager) + FilePathCachingInterface &filePathCache) + : m_symbolEntries(symbolEntries) + , m_sourceLocationEntries(sourceLocationEntries) + , m_filePathCache(filePathCache) { } @@ -96,7 +94,6 @@ private: SymbolEntries &m_symbolEntries; SourceLocationEntries &m_sourceLocationEntries; FilePathCachingInterface &m_filePathCache; - SourcesManager &m_sourcesManager; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp index 91c0dd28d85..301f50beaef 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.cpp @@ -33,8 +33,7 @@ std::unique_ptr CollectSymbolsAction::newASTConsumer( clang::CompilerInstance &compilerInstance, llvm::StringRef inFile) { - m_indexDataConsumer->setSourceManager(&compilerInstance.getSourceManager()); - return m_action.CreateASTConsumer(compilerInstance, inFile); + return clang::WrapperFrontendAction::CreateASTConsumer(compilerInstance, inFile); } } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h index 2074a25a6e5..a38f1c4f879 100644 --- a/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h +++ b/src/tools/clangrefactoringbackend/source/collectsymbolsaction.h @@ -26,8 +26,8 @@ #pragma once #include "clangrefactoringbackend_global.h" -#include "sourcelocationentry.h" #include "indexdataconsumer.h" +#include "sourcelocationentry.h" #include "symbolentry.h" #include @@ -37,53 +37,68 @@ #include #include #include +#include #include namespace ClangBackEnd { -class CollectSymbolsAction +class CollectSymbolsAction : public clang::WrapperFrontendAction { public: CollectSymbolsAction(std::shared_ptr indexDataConsumer) - : m_action(indexDataConsumer, createIndexingOptions()), - m_indexDataConsumer(indexDataConsumer.get()) + : clang::WrapperFrontendAction( + clang::index::createIndexingAction(indexDataConsumer, createIndexingOptions(), nullptr)) + , m_indexDataConsumer(indexDataConsumer) {} std::unique_ptr newASTConsumer(clang::CompilerInstance &compilerInstance, llvm::StringRef inFile); -private: - class WrappedIndexAction final : public clang::WrapperFrontendAction - { - public: - WrappedIndexAction(std::shared_ptr indexDataConsumer, - clang::index::IndexingOptions indexingOptions) - : clang::WrapperFrontendAction( - clang::index::createIndexingAction(indexDataConsumer, indexingOptions, nullptr)) - {} - std::unique_ptr - CreateASTConsumer(clang::CompilerInstance &compilerInstance, - llvm::StringRef inFile) override - { - return WrapperFrontendAction::CreateASTConsumer(compilerInstance, inFile); - } - }; - - static - clang::index::IndexingOptions createIndexingOptions() + static clang::index::IndexingOptions createIndexingOptions() { clang::index::IndexingOptions options; options.SystemSymbolFilter = clang::index::IndexingOptions::SystemSymbolFilterKind::None; options.IndexFunctionLocals = true; + options.IndexMacrosInPreprocessor = true; return options; } + bool BeginInvocation(clang::CompilerInstance &compilerInstance) override + { + m_indexDataConsumer->setSourceManager(&compilerInstance.getSourceManager()); + compilerInstance.getPreprocessorOpts().AllowPCHWithCompilerErrors = true; + compilerInstance.getDiagnosticOpts().ErrorLimit = 1; + + return clang::WrapperFrontendAction::BeginInvocation(compilerInstance); + } + + bool BeginSourceFileAction(clang::CompilerInstance &compilerInstance) override + { + compilerInstance.getPreprocessor().SetSuppressIncludeNotFoundError(true); + + return clang::WrapperFrontendAction::BeginSourceFileAction(compilerInstance); + } + + void EndSourceFileAction() override { clang::WrapperFrontendAction::EndSourceFileAction(); } + + bool PrepareToExecuteAction(clang::CompilerInstance &instance) override + { + return clang::WrapperFrontendAction::PrepareToExecuteAction(instance); + } + + void ExecuteAction() override { clang::WrapperFrontendAction::ExecuteAction(); } + + std::unique_ptr CreateASTConsumer(clang::CompilerInstance &compilerInstance, + llvm::StringRef inFile) override + { + return WrapperFrontendAction::CreateASTConsumer(compilerInstance, inFile); + } + private: - WrappedIndexAction m_action; - IndexDataConsumer *m_indexDataConsumer; + std::shared_ptr m_indexDataConsumer; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp new file mode 100644 index 00000000000..28efe39f9bb --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "filestatuspreprocessorcallbacks.h" + +namespace ClangBackEnd { + +void FileStatusPreprocessorCallbacks::FileChanged(clang::SourceLocation sourceLocation, + clang::PPCallbacks::FileChangeReason reason, + clang::SrcMgr::CharacteristicKind, + clang::FileID) +{ + if (reason == clang::PPCallbacks::EnterFile) { + const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID( + m_sourceManager->getFileID(sourceLocation)); + if (fileEntry) + addFileStatus(fileEntry); + } +} + +void FileStatusPreprocessorCallbacks::addFileStatus(const clang::FileEntry *fileEntry) +{ + auto id = filePathId(fileEntry); + + auto found = std::lower_bound(m_fileStatuses.begin(), + m_fileStatuses.end(), + id, + [](const auto &first, const auto &second) { + return first.filePathId < second; + }); + + if (found == m_fileStatuses.end() || found->filePathId != id) { + m_fileStatuses.emplace(found, id, fileEntry->getSize(), fileEntry->getModificationTime()); + } +} + +} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/projectpartpchproviderinterface.h b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h similarity index 55% rename from src/libs/clangsupport/projectpartpchproviderinterface.h rename to src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h index 282e541cfd8..ad7bc4f4d60 100644 --- a/src/libs/clangsupport/projectpartpchproviderinterface.h +++ b/src/tools/clangrefactoringbackend/source/filestatuspreprocessorcallbacks.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,26 +25,35 @@ #pragma once -#include "projectpartpch.h" +#include "filestatus.h" +#include "symbolsvisitorbase.h" -#include +#include + +#include namespace ClangBackEnd { -class ProjectPartPchProviderInterface +class FileStatusPreprocessorCallbacks final : public clang::PPCallbacks, public SymbolsVisitorBase { public: - ProjectPartPchProviderInterface() = default; - ProjectPartPchProviderInterface(const ProjectPartPchProviderInterface &) = delete; - ProjectPartPchProviderInterface &operator=(const ProjectPartPchProviderInterface &) = delete; + FileStatusPreprocessorCallbacks(FileStatuses &fileStatuses, + const FilePathCachingInterface &filePathCache, + const clang::SourceManager *sourceManager, + FilePathIds &filePathIndices) + : SymbolsVisitorBase(filePathCache, sourceManager, filePathIndices) + , m_fileStatuses(fileStatuses) + {} - virtual Utils::optional projectPartPch( - ClangBackEnd::ProjectPartId projectPartId) const = 0; - virtual const ClangBackEnd::ProjectPartPchs &projectPartPchs() const = 0; + void FileChanged(clang::SourceLocation sourceLocation, + clang::PPCallbacks::FileChangeReason reason, + clang::SrcMgr::CharacteristicKind, + clang::FileID) override; + void addFileStatus(const clang::FileEntry *fileEntry); -protected: - ~ProjectPartPchProviderInterface() = default; +private: + FileStatuses &m_fileStatuses; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp b/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp index 86e5fb597ce..1fa60434619 100644 --- a/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp +++ b/src/tools/clangrefactoringbackend/source/indexdataconsumer.cpp @@ -24,14 +24,18 @@ ****************************************************************************/ #include "indexdataconsumer.h" +#include "collectsymbolsaction.h" +#include "filestatuspreprocessorcallbacks.h" +#include #include #include -#include -#include +#include #include +#include + namespace ClangBackEnd { namespace { @@ -113,23 +117,33 @@ bool isReference(clang::index::SymbolRoleSet symbolRoles) return symbolRoles & (uint(SymbolRole::Reference) | uint(SymbolRole::Call)); } -} +} // namespace bool IndexDataConsumer::skipSymbol(clang::FileID fileId, clang::index::SymbolRoleSet symbolRoles) { - bool alreadyParsed = isAlreadyParsed(fileId); - bool isParsedDeclaration = alreadyParsed && isDeclaration(symbolRoles); - bool isParsedReference = alreadyParsed && !dependentFilesAreModified() && isReference(symbolRoles); - - return isParsedDeclaration || isParsedReference; + return isAlreadyParsed(fileId, m_symbolSourcesManager) + && !m_symbolSourcesManager.dependentFilesModified(); } -bool IndexDataConsumer::handleDeclOccurence( - const clang::Decl *declaration, - clang::index::SymbolRoleSet symbolRoles, - llvm::ArrayRef /*symbolRelations*/, - clang::SourceLocation sourceLocation, - IndexDataConsumer::ASTNodeInfo /*astNodeInfo*/) +bool IndexDataConsumer::isAlreadyParsed(clang::FileID fileId, SourcesManager &sourcesManager) +{ + const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(fileId); + if (!fileEntry) + return false; + return sourcesManager.alreadyParsed(filePathId(fileEntry), fileEntry->getModificationTime()); +} + +void IndexDataConsumer::setPreprocessor(std::shared_ptr preprocessor) +{ + preprocessor->addPPCallbacks(std::make_unique( + m_fileStatuses, m_filePathCache, m_sourceManager, m_filePathIndices)); +} + +bool IndexDataConsumer::handleDeclOccurence(const clang::Decl *declaration, + clang::index::SymbolRoleSet symbolRoles, + llvm::ArrayRef /*symbolRelations*/, + clang::SourceLocation sourceLocation, + IndexDataConsumer::ASTNodeInfo /*astNodeInfo*/) { const auto *namedDeclaration = clang::dyn_cast(declaration); if (namedDeclaration) { @@ -137,7 +151,6 @@ bool IndexDataConsumer::handleDeclOccurence( return true; if (skipSymbol(m_sourceManager->getFileID(sourceLocation), symbolRoles)) - return true; SymbolIndex globalId = toSymbolIndex(declaration->getCanonicalDecl()); @@ -165,4 +178,64 @@ bool IndexDataConsumer::handleDeclOccurence( return true; } +namespace { + +SourceLocationKind macroSymbolType(clang::index::SymbolRoleSet roles) +{ + if (roles & static_cast(clang::index::SymbolRole::Definition)) + return SourceLocationKind::MacroDefinition; + + if (roles & static_cast(clang::index::SymbolRole::Undefinition)) + return SourceLocationKind::MacroUndefinition; + + if (roles & static_cast(clang::index::SymbolRole::Reference)) + return SourceLocationKind::MacroUsage; + + return SourceLocationKind::None; +} + +} // namespace + +bool IndexDataConsumer::handleMacroOccurence(const clang::IdentifierInfo *identifierInfo, + const clang::MacroInfo *macroInfo, + clang::index::SymbolRoleSet roles, + clang::SourceLocation sourceLocation) +{ + if (macroInfo && sourceLocation.isFileID() + && !isAlreadyParsed(m_sourceManager->getFileID(sourceLocation), m_macroSourcesManager) + && !isInSystemHeader(sourceLocation)) { + FilePathId fileId = filePathId(sourceLocation); + if (fileId.isValid()) { + auto macroName = identifierInfo->getName(); + SymbolIndex globalId = toSymbolIndex(macroInfo); + + auto found = m_symbolEntries.find(globalId); + if (found == m_symbolEntries.end()) { + Utils::optional usr = generateUSR(macroName, sourceLocation); + if (usr) { + m_symbolEntries.emplace(std::piecewise_construct, + std::forward_as_tuple(globalId), + std::forward_as_tuple(std::move(*usr), + macroName, + SymbolKind::Macro)); + } + } + + m_sourceLocationEntries.emplace_back(globalId, + fileId, + lineColum(sourceLocation), + macroSymbolType(roles)); + } + } + + return true; +} + +void IndexDataConsumer::finish() +{ + m_macroSourcesManager.updateModifiedTimeStamps(); + m_symbolSourcesManager.updateModifiedTimeStamps(); + m_filePathIndices.clear(); +} + } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/indexdataconsumer.h b/src/tools/clangrefactoringbackend/source/indexdataconsumer.h index 6db595391c3..730ca12b232 100644 --- a/src/tools/clangrefactoringbackend/source/indexdataconsumer.h +++ b/src/tools/clangrefactoringbackend/source/indexdataconsumer.h @@ -26,6 +26,7 @@ #pragma once #include "clangrefactoringbackend_global.h" +#include "filestatus.h" #include "sourcelocationentry.h" #include "symbolentry.h" #include "symbolsvisitorbase.h" @@ -42,28 +43,48 @@ class IndexDataConsumer : public clang::index::IndexDataConsumer, public: IndexDataConsumer(SymbolEntries &symbolEntries, SourceLocationEntries &sourceLocationEntries, + FileStatuses &fileStatuses, FilePathCachingInterface &filePathCache, - SourcesManager &sourcesManager) - : SymbolsVisitorBase(filePathCache, nullptr, sourcesManager), - m_symbolEntries(symbolEntries), - m_sourceLocationEntries(sourceLocationEntries) + SourcesManager &symbolSourcesManager, + SourcesManager ¯oSourcesManager) + : SymbolsVisitorBase(filePathCache, nullptr, m_filePathIndices) + , m_symbolEntries(symbolEntries) + , m_sourceLocationEntries(sourceLocationEntries) + , m_fileStatuses(fileStatuses) + , m_symbolSourcesManager(symbolSourcesManager) + , m_macroSourcesManager(macroSourcesManager) + {} IndexDataConsumer(const IndexDataConsumer &) = delete; IndexDataConsumer &operator=(const IndexDataConsumer &) = delete; + void setPreprocessor(std::shared_ptr preprocessor) override; + bool handleDeclOccurence(const clang::Decl *declaration, clang::index::SymbolRoleSet symbolRoles, llvm::ArrayRef symbolRelations, clang::SourceLocation sourceLocation, ASTNodeInfo astNodeInfo) override; -private: - bool skipSymbol(clang::FileID fileId, clang::index::SymbolRoleSet symbolRoles); + bool handleMacroOccurence(const clang::IdentifierInfo *identifierInfo, + const clang::MacroInfo *macroInfo, + clang::index::SymbolRoleSet roles, + clang::SourceLocation sourceLocation) override; + + void finish() override; private: + bool skipSymbol(clang::FileID fileId, clang::index::SymbolRoleSet symbolRoles); + bool isAlreadyParsed(clang::FileID fileId, SourcesManager &sourcesManager); + +private: + FilePathIds m_filePathIndices; SymbolEntries &m_symbolEntries; SourceLocationEntries &m_sourceLocationEntries; + FileStatuses &m_fileStatuses; + SourcesManager &m_symbolSourcesManager; + SourcesManager &m_macroSourcesManager; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp index 9c84c4666a6..1ee61eb67c2 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp @@ -144,6 +144,8 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart) } } + m_pathWatcher.updateIdPaths( + {{projectPartId, m_buildDependencyStorage.fetchSources(projectPartId)}}); m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask)); m_symbolIndexerTaskQueue.processEntries(); } diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h index 7ca35132846..1f15f2ffaa0 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -38,10 +39,6 @@ #include #include -namespace Sqlite { -class TransactionInterface; -} - namespace ClangBackEnd { class SymbolsCollectorInterface; @@ -53,9 +50,11 @@ public: using Task = SymbolIndexerTask::Callable; SymbolIndexerTaskQueue(TaskSchedulerInterface &symbolIndexerTaskScheduler, - ProgressCounter &progressCounter) - : m_symbolIndexerScheduler(symbolIndexerTaskScheduler), - m_progressCounter(progressCounter) + ProgressCounter &progressCounter, + Sqlite::DatabaseInterface &database) + : m_symbolIndexerScheduler(symbolIndexerTaskScheduler) + , m_progressCounter(progressCounter) + , m_database(database) {} void addOrUpdateTasks(std::vector &&tasks) @@ -94,12 +93,21 @@ public: void processEntries() { - uint taskCount = m_symbolIndexerScheduler.slotUsage().free; + auto slotUsage = m_symbolIndexerScheduler.slotUsage(); + uint taskCount = slotUsage.free; auto newEnd = std::prev(m_tasks.end(), std::min(int(taskCount), int(m_tasks.size()))); m_symbolIndexerScheduler.addTasks({std::make_move_iterator(newEnd), std::make_move_iterator(m_tasks.end())}); m_tasks.erase(newEnd, m_tasks.end()); + + if (m_tasks.empty() && slotUsage.used == 0) { + try { + m_database.walCheckpointFull(); + } catch (Sqlite::Exception &exception) { + exception.printWarning(); + } + } } void syncTasks(); @@ -108,6 +116,7 @@ private: std::vector m_tasks; TaskSchedulerInterface &m_symbolIndexerScheduler; ProgressCounter &m_progressCounter; + Sqlite::DatabaseInterface &m_database; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h index d4e36499b12..5c391503bff 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexing.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h @@ -105,6 +105,7 @@ public: m_projectPartsStorage, m_modifiedTimeChecker, environment) + , m_indexerQueue(m_indexerScheduler, m_progressCounter, database) , m_indexerScheduler(m_collectorManger, m_indexerQueue, m_progressCounter, @@ -152,7 +153,7 @@ private: ModifiedTimeChecker m_modifiedTimeChecker{getModifiedTime, m_filePathCache}; SymbolIndexer m_indexer; - SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter}; + SymbolIndexerTaskQueue m_indexerQueue; SymbolIndexerTaskScheduler m_indexerScheduler; }; diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp index 1634512b500..071837ac528 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollector.cpp +++ b/src/tools/clangrefactoringbackend/source/symbolscollector.cpp @@ -32,10 +32,14 @@ namespace ClangBackEnd { SymbolsCollector::SymbolsCollector(Sqlite::Database &database) - : m_filePathCache(database), - m_indexDataConsumer(std::make_shared(m_symbolEntries, m_sourceLocationEntries, m_filePathCache, m_sourcesManager)), - m_collectSymbolsAction(m_indexDataConsumer), - m_collectMacrosSourceFileCallbacks(m_symbolEntries, m_sourceLocationEntries, m_filePathCache, m_sourcesManager) + : m_filePathCache(database) + , m_indexDataConsumer(std::make_shared(m_symbolEntries, + m_sourceLocationEntries, + m_fileStatuses, + m_filePathCache, + m_symbolSourcesManager, + m_macroSourcesManager)) + , m_collectSymbolsAction(m_indexDataConsumer) { } @@ -43,7 +47,6 @@ void SymbolsCollector::addFiles(const FilePathIds &filePathIds, const Utils::SmallStringVector &arguments) { m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments); - m_collectMacrosSourceFileCallbacks.addSourceFiles(filePathIds); } void SymbolsCollector::setFile(FilePathId filePathId, const Utils::SmallStringVector &arguments) @@ -58,91 +61,73 @@ void SymbolsCollector::setUnsavedFiles(const V2::FileContainers &unsavedFiles) void SymbolsCollector::clear() { - m_indexDataConsumer->clear(); - m_collectMacrosSourceFileCallbacks.clear(); m_symbolEntries.clear(); m_sourceLocationEntries.clear(); + m_fileStatuses.clear(); m_clangTool = ClangTool(); } -template -std::unique_ptr -newFrontendActionFactory(Factory *consumerFactory, - clang::tooling::SourceFileCallbacks *sourceFileCallbacks) +std::unique_ptr newFrontendActionFactory(CollectSymbolsAction *action) { class FrontendActionFactoryAdapter : public clang::tooling::FrontendActionFactory { public: - explicit FrontendActionFactoryAdapter(Factory *consumerFactory, - clang::tooling::SourceFileCallbacks *sourceFileCallbacks) - : m_consumerFactory(consumerFactory), - m_sourceFileCallbacks(sourceFileCallbacks) + explicit FrontendActionFactoryAdapter(CollectSymbolsAction *consumerFactory) + : m_action(consumerFactory) {} - clang::FrontendAction *create() override { - return new ConsumerFactoryAdaptor(m_consumerFactory, m_sourceFileCallbacks); - } + clang::FrontendAction *create() override { return new AdaptorAction(m_action); } private: - class ConsumerFactoryAdaptor : public clang::ASTFrontendAction { + class AdaptorAction : public clang::ASTFrontendAction + { public: - ConsumerFactoryAdaptor(Factory *consumerFactory, - clang::tooling::SourceFileCallbacks *sourceFileCallbacks) - : m_consumerFactory(consumerFactory), - m_sourceFileCallbacks(sourceFileCallbacks) + AdaptorAction(CollectSymbolsAction *action) + : m_action(action) {} std::unique_ptr CreateASTConsumer(clang::CompilerInstance &instance, llvm::StringRef inFile) override { - return m_consumerFactory->newASTConsumer(instance, inFile); + return m_action->newASTConsumer(instance, inFile); } - protected: - bool BeginInvocation(clang::CompilerInstance &compilerInstance) override + bool BeginInvocation(clang::CompilerInstance &instance) override { - compilerInstance.getPreprocessorOpts().AllowPCHWithCompilerErrors = true; - compilerInstance.getDiagnosticOpts().ErrorLimit = 1; - - return clang::ASTFrontendAction::BeginInvocation(compilerInstance); + return m_action->BeginInvocation(instance); } - - bool BeginSourceFileAction(clang::CompilerInstance &compilerInstance) override + bool BeginSourceFileAction(clang::CompilerInstance &instance) override { - compilerInstance.getPreprocessor().SetSuppressIncludeNotFoundError(true); - - if (!clang::ASTFrontendAction::BeginSourceFileAction(compilerInstance)) - return false; - if (m_sourceFileCallbacks) - return m_sourceFileCallbacks->handleBeginSource(compilerInstance); - return true; + return m_action->BeginSourceFileAction(instance); } - void EndSourceFileAction() override + bool PrepareToExecuteAction(clang::CompilerInstance &instance) override { - if (m_sourceFileCallbacks) - m_sourceFileCallbacks->handleEndSource(); - clang::ASTFrontendAction::EndSourceFileAction(); + return m_action->PrepareToExecuteAction(instance); } + void ExecuteAction() override { m_action->ExecuteAction(); } + void EndSourceFileAction() override { m_action->EndSourceFileAction(); } + + bool hasPCHSupport() const override { return m_action->hasPCHSupport(); } + bool hasASTFileSupport() const override { return m_action->hasASTFileSupport(); } + bool hasIRSupport() const override { return false; } + bool hasCodeCompletionSupport() const override { return false; } private: - Factory *m_consumerFactory; - clang::tooling::SourceFileCallbacks *m_sourceFileCallbacks; + CollectSymbolsAction *m_action; }; - Factory *m_consumerFactory; - clang::tooling::SourceFileCallbacks *m_sourceFileCallbacks; + CollectSymbolsAction *m_action; }; - return std::unique_ptr( - new FrontendActionFactoryAdapter(consumerFactory, sourceFileCallbacks)); + return std::unique_ptr( + new FrontendActionFactoryAdapter(action)); } bool SymbolsCollector::collectSymbols() { auto tool = m_clangTool.createTool(); - auto actionFactory = ClangBackEnd::newFrontendActionFactory(&m_collectSymbolsAction, - &m_collectMacrosSourceFileCallbacks); + auto actionFactory = ClangBackEnd::newFrontendActionFactory(&m_collectSymbolsAction); return tool.run(actionFactory.get()) != 1; } @@ -161,24 +146,9 @@ const SourceLocationEntries &SymbolsCollector::sourceLocations() const return m_sourceLocationEntries; } -const FilePathIds &SymbolsCollector::sourceFiles() const -{ - return m_collectMacrosSourceFileCallbacks.sourceFiles(); -} - -const UsedMacros &SymbolsCollector::usedMacros() const -{ - return m_collectMacrosSourceFileCallbacks.usedMacros(); -} - const FileStatuses &SymbolsCollector::fileStatuses() const { - return m_collectMacrosSourceFileCallbacks.fileStatuses(); -} - -const SourceDependencies &SymbolsCollector::sourceDependencies() const -{ - return m_collectMacrosSourceFileCallbacks.sourceDependencies(); + return m_fileStatuses; } bool SymbolsCollector::isUsed() const diff --git a/src/tools/clangrefactoringbackend/source/symbolscollector.h b/src/tools/clangrefactoringbackend/source/symbolscollector.h index b37647e9694..cc7ca4396c9 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollector.h +++ b/src/tools/clangrefactoringbackend/source/symbolscollector.h @@ -58,10 +58,7 @@ public: const SymbolEntries &symbols() const override; const SourceLocationEntries &sourceLocations() const override; - const FilePathIds &sourceFiles() const override; - const UsedMacros &usedMacros() const override; const FileStatuses &fileStatuses() const override; - const SourceDependencies &sourceDependencies() const override; bool isUsed() const override; void setIsUsed(bool isUsed) override; @@ -71,10 +68,11 @@ private: ClangTool m_clangTool; SymbolEntries m_symbolEntries; SourceLocationEntries m_sourceLocationEntries; + FileStatuses m_fileStatuses; std::shared_ptr m_indexDataConsumer; CollectSymbolsAction m_collectSymbolsAction; - CollectMacrosSourceFileCallbacks m_collectMacrosSourceFileCallbacks; - SourcesManager m_sourcesManager; + SourcesManager m_symbolSourcesManager; + SourcesManager m_macroSourcesManager; bool m_isUsed = false; }; diff --git a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h index 94b31423718..07b5de223ce 100644 --- a/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h +++ b/src/tools/clangrefactoringbackend/source/symbolscollectorinterface.h @@ -48,10 +48,7 @@ public: virtual const SymbolEntries &symbols() const = 0; virtual const SourceLocationEntries &sourceLocations() const = 0; - virtual const FilePathIds &sourceFiles() const = 0; - virtual const UsedMacros &usedMacros() const = 0; virtual const FileStatuses &fileStatuses() const = 0; - virtual const SourceDependencies &sourceDependencies() const = 0; }; } // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h b/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h index ff2142f40e2..7b63cb223ec 100644 --- a/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h +++ b/src/tools/clangrefactoringbackend/source/symbolsvisitorbase.h @@ -46,10 +46,10 @@ class SymbolsVisitorBase public: SymbolsVisitorBase(const FilePathCachingInterface &filePathCache, const clang::SourceManager *sourceManager, - SourcesManager &sourcesManager) - : m_filePathCache(filePathCache), - m_sourceManager(sourceManager), - m_sourcesManager(sourcesManager) + FilePathIds &filePathIndices) + : m_filePathCache(filePathCache) + , m_sourceManager(sourceManager) + , m_filePathIndices(filePathIndices) {} FilePathId filePathId(clang::SourceLocation sourceLocation) @@ -60,25 +60,6 @@ public: return filePathId(fileEntry); } - bool dependentFilesAreModified() - { - return m_sourcesManager.dependentFilesModified(); - } - - bool isAlreadyParsed(clang::FileID fileId) - { - const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(fileId); - if (!fileEntry) - return false; - return m_sourcesManager.alreadyParsed(filePathId(fileEntry), - fileEntry->getModificationTime()); - } - - bool alreadyParsed(clang::SourceLocation sourceLocation) - { - return isAlreadyParsed(m_sourceManager->getFileID(sourceLocation)); - } - FilePathId filePathId(const clang::FileEntry *fileEntry) { if (fileEntry) { @@ -156,22 +137,26 @@ public: return isSystem(m_sourceManager->getSLocEntry(fileId).getFile().getFileCharacteristic()); } + bool isInSystemHeader(clang::SourceLocation sourceLocation) const + { + return m_sourceManager->isInSystemHeader(sourceLocation); + } + static bool isSystem(clang::SrcMgr::CharacteristicKind kind) { return clang::SrcMgr::isSystem(kind); } - void clear() - { - m_filePathIndices.clear(); - } + const FilePathCachingInterface &filePathCache() const { return m_filePathCache; } + const clang::SourceManager *sourceManager() const { return m_sourceManager; } protected: - std::vector m_filePathIndices; const FilePathCachingInterface &m_filePathCache; const clang::SourceManager *m_sourceManager = nullptr; - SourcesManager &m_sourcesManager; + +private: + FilePathIds &m_filePathIndices; }; } // namespace ClangBackend diff --git a/tests/auto/cplusplus/checksymbols/CMakeLists.txt b/tests/auto/cplusplus/checksymbols/CMakeLists.txt index b46c1e8a63d..f889839ed23 100644 --- a/tests/auto/cplusplus/checksymbols/CMakeLists.txt +++ b/tests/auto/cplusplus/checksymbols/CMakeLists.txt @@ -1,4 +1,4 @@ add_qtc_test(tst_cplusplus_checksymbols - DEPENDS CppTools + DEPENDS CppTools TextEditor SOURCES tst_checksymbols.cpp ) diff --git a/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp b/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp index 71e5d50735d..79ce9cec1be 100644 --- a/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp +++ b/tests/auto/qml/codemodel/dependencies/tst_dependencies.cpp @@ -112,7 +112,7 @@ private: void tst_Dependencies::initTestCase() { - m_path = QLatin1Literal(TESTSRCDIR "/samples"); + m_path = QLatin1String(TESTSRCDIR "/samples"); m_basePaths.append(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath)); diff --git a/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp b/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp index f178338bd16..735daa04f71 100644 --- a/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp +++ b/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp @@ -134,13 +134,13 @@ void tst_Ecmascript::initTestCase() QDirIterator it(sampledir, QDirIterator::Subdirectories); - QStringList skipList = readSkipList(sampledir, QLatin1Literal("skip.txt")); + QStringList skipList = readSkipList(sampledir, QLatin1String("skip.txt")); while (it.hasNext()) { QString path = it.next(); if (skipList.contains(path)) continue; QFileInfo f(path); - if (f.isFile() && f.suffix() == QLatin1Literal("js")) + if (f.isFile() && f.suffix() == QLatin1String("js")) m_files << f; } diff --git a/tests/unit/mockup/projectexplorer/project.h b/tests/unit/mockup/projectexplorer/project.h index 3e0fef904b8..c69eb6e47ba 100644 --- a/tests/unit/mockup/projectexplorer/project.h +++ b/tests/unit/mockup/projectexplorer/project.h @@ -47,6 +47,6 @@ public: void setNamedSettings(const QString &name, const QVariant &value) { settings[name] = value; } Utils::FileName rootProjectDirectoryPath; - std::map settings; + mutable std::map settings; }; } // namespace ProjectExplorer diff --git a/tests/unit/unittest/builddependenciesstorage-test.cpp b/tests/unit/unittest/builddependenciesstorage-test.cpp index aa823704857..052ed452f09 100644 --- a/tests/unit/unittest/builddependenciesstorage-test.cpp +++ b/tests/unit/unittest/builddependenciesstorage-test.cpp @@ -70,6 +70,7 @@ protected: MockSqliteWriteStatement &updatePchCreationTimeStampStatement = storage.updatePchCreationTimeStampStatement; MockSqliteWriteStatement &deleteAllProjectPartsFilesWithProjectPartNameStatement = storage.deleteAllProjectPartsFilesWithProjectPartNameStatement; + MockSqliteReadStatement &fetchProjectPartsFilesStatement = storage.fetchProjectPartsFilesStatement; }; TEST_F(BuildDependenciesStorage, ConvertStringsToJson) @@ -232,5 +233,13 @@ TEST_F(BuildDependenciesStorage, FetchUsedMacros) ASSERT_THAT(usedMacros, result); } -} +TEST_F(BuildDependenciesStorage, FetchSources) +{ + ClangBackEnd::FilePathIds result{3, 5, 7}; + EXPECT_CALL(fetchProjectPartsFilesStatement, valuesReturnFilePathIds(_, 22)).WillOnce(Return(result)); + auto sources = storage.fetchSources(22); + + ASSERT_THAT(sources, result); +} +} // namespace diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 6b3433ef104..7ac4a676e3e 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -51,7 +51,7 @@ #include #include #include -#include +#include #include #include #include @@ -719,18 +719,14 @@ std::ostream &operator<<(std::ostream &out, const NativeFilePath &filePath) std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessage &message) { - out << "(" - << message.projectPartPchs - << ")"; + out << "(" << message.projectPartIds << ")"; return out; } std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch) { - out << "(" - << projectPartPch.projectPartId << ", " - << projectPartPch.pchPath << ", " + out << "(" << projectPartPch.projectPartId << ", " << projectPartPch.pchPath << ", " << projectPartPch.lastModified << ")"; return out; diff --git a/tests/unit/unittest/mockbuilddependenciesstorage.h b/tests/unit/unittest/mockbuilddependenciesstorage.h index 46c201de55f..a4d34e481dc 100644 --- a/tests/unit/unittest/mockbuilddependenciesstorage.h +++ b/tests/unit/unittest/mockbuilddependenciesstorage.h @@ -51,5 +51,7 @@ public: ClangBackEnd::ProjectPartId(Utils::SmallStringView projectPartName)); MOCK_METHOD2(updatePchCreationTimeStamp, void(long long pchCreationTimeStamp, ClangBackEnd::ProjectPartId projectPartId)); + MOCK_CONST_METHOD1(fetchSources, + ClangBackEnd::FilePathIds(ClangBackEnd::ProjectPartId projectPartId)); }; diff --git a/tests/unit/unittest/mockpchmanagernotifier.h b/tests/unit/unittest/mockpchmanagernotifier.h index 600b37bd2ee..8db9a63c40c 100644 --- a/tests/unit/unittest/mockpchmanagernotifier.h +++ b/tests/unit/unittest/mockpchmanagernotifier.h @@ -36,9 +36,6 @@ public: : ClangPchManager::PchManagerNotifierInterface(pchManagerClient) {} - MOCK_METHOD3(precompiledHeaderUpdated, - void(ClangBackEnd::ProjectPartId projectPartId, - const QString &pchFilePath, - long long lastModified)); + MOCK_METHOD1(precompiledHeaderUpdated, void(ClangBackEnd::ProjectPartId projectPartId)); MOCK_METHOD1(precompiledHeaderRemoved, void(ClangBackEnd::ProjectPartId projectPartId)); }; diff --git a/tests/unit/unittest/mockprojectpartsmanager.h b/tests/unit/unittest/mockprojectpartsmanager.h index b2cab59060c..613faf7dfca 100644 --- a/tests/unit/unittest/mockprojectpartsmanager.h +++ b/tests/unit/unittest/mockprojectpartsmanager.h @@ -33,7 +33,7 @@ class MockProjectPartsManager : public ClangBackEnd::ProjectPartsManagerInterfac { public: MOCK_METHOD1(update, - ClangBackEnd::ProjectPartContainers( + ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts( const ClangBackEnd::ProjectPartContainers &projectsParts)); MOCK_METHOD1(remove, void(const ClangBackEnd::ProjectPartIds &projectPartIds)); MOCK_CONST_METHOD1( @@ -42,7 +42,8 @@ public: MOCK_METHOD1(updateDeferred, void(const ClangBackEnd::ProjectPartContainers &projectsParts)); MOCK_METHOD0(deferredUpdates, ClangBackEnd::ProjectPartContainers()); - ClangBackEnd::ProjectPartContainers update(ClangBackEnd::ProjectPartContainers &&projectsParts) override + ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts update( + ClangBackEnd::ProjectPartContainers &&projectsParts) override { return update(projectsParts); } diff --git a/tests/unit/unittest/mocksqlitedatabase.h b/tests/unit/unittest/mocksqlitedatabase.h index 5bef2ba8c51..05f6f4e9581 100644 --- a/tests/unit/unittest/mocksqlitedatabase.h +++ b/tests/unit/unittest/mocksqlitedatabase.h @@ -31,12 +31,13 @@ #include "mocksqlitetransactionbackend.h" #include "mocksqlitewritestatement.h" +#include #include #include #include -class MockSqliteDatabase : public MockSqliteTransactionBackend +class MockSqliteDatabase : public MockSqliteTransactionBackend, public Sqlite::DatabaseInterface { public: using ReadStatement = NiceMock; @@ -56,5 +57,7 @@ public: MOCK_METHOD1(setIsInitialized, void (bool)); + + MOCK_METHOD0(walCheckpointFull, void()); }; diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 19bc087ca6d..0cf84a983dd 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -203,8 +203,8 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient) EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated( - Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartPchs, - ElementsAre(Eq(creator.projectPartPch()))))); + Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, + ElementsAre(Eq(creator.projectPartPch().projectPartId))))); creator.doInMainThreadAfterFinished(); } @@ -315,6 +315,36 @@ TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask Field(&ProjectPartPch::lastModified, Gt(0)))); } +TEST_F(PchCreatorSlowTest, NoIncludes) +{ + pchTask1.includes = {}; + + creator.generatePch(std::move(pchTask1)); + + ASSERT_THAT(creator.projectPartPch(), + AllOf(Field(&ProjectPartPch::projectPartId, Eq(pchTask1.projectPartId())), + Field(&ProjectPartPch::pchPath, IsEmpty()), + Field(&ProjectPartPch::lastModified, Gt(0)))); +} + +TEST_F(PchCreatorSlowTest, NoIncludesInTheMainThreadCalls) +{ + pchTask1.includes = {}; + creator.generatePch(std::move(pchTask1)); + + EXPECT_CALL(mockPchManagerClient, + precompiledHeadersUpdated( + Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, + ElementsAre(Eq(creator.projectPartPch().projectPartId))))); + EXPECT_CALL(mockClangPathWatcher, + updateIdPaths( + ElementsAre(AllOf(Field(&ClangBackEnd::IdPaths::id, 1), + Field(&ClangBackEnd::IdPaths::filePathIds, IsEmpty()))))); + EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(Gt(0), Eq(1))); + + creator.doInMainThreadAfterFinished(); +} + TEST_F(PchCreatorVerySlowTest, GeneratedFile) { creator.clear(); diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp index 5f9fffbf010..6e107b4a55c 100644 --- a/tests/unit/unittest/pchmanagerclient-test.cpp +++ b/tests/unit/unittest/pchmanagerclient-test.cpp @@ -68,11 +68,9 @@ protected: mockProjectPartsStorage, settingsManager}; ClangBackEnd::ProjectPartId projectPartId{1}; - ClangBackEnd::FilePath pchFilePath{"/path/to/pch"}; - PrecompiledHeadersUpdatedMessage message{{{projectPartId, pchFilePath.clone(), 1}}}; + PrecompiledHeadersUpdatedMessage message{{projectPartId}}; ClangBackEnd::ProjectPartId projectPartId2{2}; - ClangBackEnd::FilePath pchFilePath2{"/path/to/pch2"}; - PrecompiledHeadersUpdatedMessage message2{{{projectPartId2, pchFilePath2.clone(), 1}}}; + PrecompiledHeadersUpdatedMessage message2{{projectPartId2}}; }; TEST_F(PchManagerClient, NotifierAttached) @@ -96,8 +94,7 @@ TEST_F(PchManagerClient, NotifierDetached) TEST_F(PchManagerClient, Update) { - EXPECT_CALL(mockPchManagerNotifier, - precompiledHeaderUpdated(projectPartId, pchFilePath.toQString(), Eq(1))); + EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderUpdated(projectPartId)); client.precompiledHeadersUpdated(message.clone()); } @@ -109,58 +106,6 @@ TEST_F(PchManagerClient, Remove) projectUpdater.removeProjectParts({projectPartId, projectPartId}); } -TEST_F(PchManagerClient, GetNoProjectPartPchForWrongProjectPartId) -{ - auto optional = client.projectPartPch(23); - - ASSERT_FALSE(optional); -} - -TEST_F(PchManagerClient, GetProjectPartPchForProjectPartId) -{ - client.precompiledHeadersUpdated(std::move(message)); - - auto optional = client.projectPartPch(projectPartId); - - ASSERT_TRUE(optional); -} - -TEST_F(PchManagerClient, ProjectPartPchRemoved) -{ - client.precompiledHeadersUpdated(std::move(message)); - - client.precompiledHeaderRemoved(projectPartId); - - ASSERT_FALSE(client.projectPartPch(projectPartId)); -} - -TEST_F(PchManagerClient, ProjectPartPchHasNoDublicateEntries) -{ - client.precompiledHeadersUpdated(message.clone()); - client.precompiledHeadersUpdated(message2.clone()); - - client.precompiledHeadersUpdated(message.clone()); - - ASSERT_THAT(client.projectPartPchs(), SizeIs(2)); -} - -TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdLastModified) -{ - client.precompiledHeadersUpdated(std::move(message)); - - ASSERT_THAT(client.projectPartPch(projectPartId)->lastModified, 1); -} - -TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdIsUpdated) -{ - client.precompiledHeadersUpdated(message.clone()); - PrecompiledHeadersUpdatedMessage updateMessage{{{projectPartId, pchFilePath.clone(), 42}}}; - - client.precompiledHeadersUpdated(updateMessage.clone()); - - ASSERT_THAT(client.projectPartPch(projectPartId)->lastModified, 42); -} - TEST_F(PchManagerClient, SetPchCreationProgress) { EXPECT_CALL(mockPchCreationProgressManager, setProgress(10, 20)); diff --git a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp index e55b71f8605..194f52afd3b 100644 --- a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp +++ b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp @@ -148,7 +148,7 @@ TEST_F(PchManagerClientServerInProcess, SendRemoveGeneratedFilesMessage) TEST_F(PchManagerClientServerInProcess, SendPrecompiledHeaderUpdatedMessage) { - PrecompiledHeadersUpdatedMessage message{{{1, "/path/to/pch", 1}}}; + PrecompiledHeadersUpdatedMessage message{1}; EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(message)); diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp index 502b51bc8c0..47b7d987ab7 100644 --- a/tests/unit/unittest/pchmanagerserver-test.cpp +++ b/tests/unit/unittest/pchmanagerserver-test.cpp @@ -48,6 +48,7 @@ using ClangBackEnd::V2::FileContainer; using ClangBackEnd::V2::FileContainers; using ClangBackEnd::ProjectPartContainer; using ClangBackEnd::ProjectPartContainers; +using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts; class PchManagerServer : public ::testing::Test { @@ -55,7 +56,8 @@ class PchManagerServer : public ::testing::Test { server.setClient(&mockPchManagerClient); - ON_CALL(mockProjectPartsManager, update(projectParts)).WillByDefault(Return(projectParts)); + ON_CALL(mockProjectPartsManager, update(projectParts)) + .WillByDefault(Return(UpToDataProjectParts{{}, projectParts})); ON_CALL(mockGeneratedFiles, isValid()).WillByDefault(Return(true)); } @@ -107,7 +109,8 @@ protected: Utils::LanguageVersion::C11, Utils::LanguageExtension::All}; std::vector projectParts{projectPart1, projectPart2}; - std::vector projectParts2{projectPart2}; + std::vector projectParts1{projectPart1}; + std::vector projectParts2{projectPart2}; FileContainer generatedFile{{"/path/to/", "file"}, "content", {}}; ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{ Utils::clone(projectParts), {"toolChainArgument"}}; @@ -120,7 +123,7 @@ TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue) InSequence s; EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts)) - .WillOnce(Return(projectParts2)); + .WillOnce(Return(UpToDataProjectParts{{}, projectParts2})); EXPECT_CALL( mockPchTaskGenerator, addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument"))); @@ -219,7 +222,7 @@ TEST_F(PchManagerServer, DontGeneratePchIfGeneratedFilesAreNotValid) InSequence s; EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1))) - .WillOnce(Return(ProjectPartContainers{projectPart1})); + .WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}})); EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(false)); EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0); EXPECT_CALL(mockProjectPartsManager, updateDeferred(ElementsAre(projectPart1))); @@ -233,7 +236,7 @@ TEST_F(PchManagerServer, GeneratePchIfGeneratedFilesAreValid) InSequence s; EXPECT_CALL(mockProjectPartsManager, update(ElementsAre(projectPart1))) - .WillOnce(Return(ProjectPartContainers{projectPart1})); + .WillOnce(Return(UpToDataProjectParts{{}, ProjectPartContainers{projectPart1}})); EXPECT_CALL(mockGeneratedFiles, isValid()).WillOnce(Return(true)); EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)); EXPECT_CALL(mockProjectPartsManager, updateDeferred(_)).Times(0); @@ -276,4 +279,19 @@ TEST_F(PchManagerServer, AfterUpdatingGeneratedFilesAreStillInvalidSoNoPchsGener server.updateGeneratedFiles(updateGeneratedFilesMessage.clone()); } +TEST_F(PchManagerServer, SentUpToDateProjectPartIdsToClient) +{ + InSequence s; + + EXPECT_CALL(mockProjectPartsManager, update(updateProjectPartsMessage.projectsParts)) + .WillOnce(Return(UpToDataProjectParts{projectParts1, projectParts2})); + EXPECT_CALL(mockPchTaskGenerator, + addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument"))); + EXPECT_CALL(mockPchManagerClient, + precompiledHeadersUpdated( + Field(&ClangBackEnd::PrecompiledHeadersUpdatedMessage::projectPartIds, + ElementsAre(Eq(projectPart1.projectPartId))))); + + server.updateProjectParts(updateProjectPartsMessage.clone()); } +} // namespace diff --git a/tests/unit/unittest/pchtaskqueue-test.cpp b/tests/unit/unittest/pchtaskqueue-test.cpp index 0851224d9d0..1754cea5623 100644 --- a/tests/unit/unittest/pchtaskqueue-test.cpp +++ b/tests/unit/unittest/pchtaskqueue-test.cpp @@ -331,22 +331,6 @@ TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfNoPchIsGenerated) tasks.front()(mockPchCreator); } -TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfTasksHasNoIncludes) -{ - InSequence s; - MockPchCreator mockPchCreator; - ClangBackEnd::ProjectPartPch projectPartPch{{}, "", 0}; - projectTask1.includes = {}; - auto tasks = queue.createProjectTasks({projectTask1}); - - EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(_)).Times(0); - EXPECT_CALL(mockPchCreator, generatePch(_)).Times(0); - EXPECT_CALL(mockPchCreator, projectPartPch()).Times(0); - EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq(1))); - - tasks.front()(mockPchCreator); -} - TEST_F(PchTaskQueue, CreateSystemTasksSizeEqualsInputSize) { auto tasks = queue.createSystemTasks({systemTask1, systemTask2}); @@ -388,19 +372,4 @@ TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfNoPchIsGenerated) tasks.front()(mockPchCreator); } -TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfTasksHasNoIncludes) -{ - InSequence s; - MockPchCreator mockPchCreator; - ClangBackEnd::ProjectPartPch projectPartPch{{}, "", 0}; - systemTask4.includes = {}; - auto tasks = queue.createSystemTasks({systemTask4}); - - EXPECT_CALL(mockPchCreator, generatePch(_)).Times(0); - EXPECT_CALL(mockPchCreator, projectPartPch()).Times(0); - EXPECT_CALL(mockPrecompiledHeaderStorage, - deleteSystemPrecompiledHeaders(UnorderedElementsAre(1, 3))); - - tasks.front()(mockPchCreator); -} } // namespace diff --git a/tests/unit/unittest/projectpartsmanager-test.cpp b/tests/unit/unittest/projectpartsmanager-test.cpp index b12cbb6b2e9..d86543e9c26 100644 --- a/tests/unit/unittest/projectpartsmanager-test.cpp +++ b/tests/unit/unittest/projectpartsmanager-test.cpp @@ -36,6 +36,7 @@ namespace { using ClangBackEnd::FilePathId; using ClangBackEnd::ProjectPartContainer; using ClangBackEnd::ProjectPartContainers; +using UpToDataProjectParts = ClangBackEnd::ProjectPartsManagerInterface::UpToDataProjectParts; class ProjectPartsManager : public testing::Test { @@ -111,16 +112,20 @@ protected: TEST_F(ProjectPartsManager, GetNoProjectPartsForAddingEmptyProjectParts) { - auto updatedProjectParts = manager.update({}); + auto projectParts = manager.update({}); - ASSERT_THAT(updatedProjectParts, IsEmpty()); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, IsEmpty()))); } TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPart) { - auto updatedProjectParts = manager.update({projectPartContainer1}); + auto projectParts = manager.update({projectPartContainer1}); - ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1)))); } TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlreadyInTheDatabase) @@ -128,9 +133,11 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithProjectPartAlr ON_CALL(mockProjectPartsStorage, fetchProjectParts(_)) .WillByDefault(Return(ProjectPartContainers{projectPartContainer1})); - auto updatedProjectParts = manager.update({projectPartContainer1, projectPartContainer2}); + auto projectParts = manager.update({projectPartContainer1, projectPartContainer2}); - ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer2)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)), + Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer2)))); } TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPartAlreadyInTheDatabase) @@ -138,9 +145,12 @@ TEST_F(ProjectPartsManager, GetProjectPartForAddingProjectPartWithOlderProjectPa ON_CALL(mockProjectPartsStorage, fetchProjectParts(_)) .WillByDefault(Return(ProjectPartContainers{projectPartContainer1})); - auto updatedProjectParts = manager.update({updatedProjectPartContainer1, projectPartContainer2}); + auto projectParts = manager.update({updatedProjectPartContainer1, projectPartContainer2}); - ASSERT_THAT(updatedProjectParts, ElementsAre(updatedProjectPartContainer1, projectPartContainer2)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, + ElementsAre(updatedProjectPartContainer1, projectPartContainer2)))); } TEST_F(ProjectPartsManager, ProjectPartAdded) @@ -184,9 +194,11 @@ TEST_F(ProjectPartsManager, DoNotUpdateNotNewProjectPart) { manager.update({projectPartContainer1}); - auto updatedProjectParts = manager.update({projectPartContainer1}); + auto projectParts = manager.update({projectPartContainer1}); - ASSERT_THAT(updatedProjectParts, IsEmpty()); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, ElementsAre(projectPartContainer1)), + Field(&UpToDataProjectParts::notUpToDate, IsEmpty()))); } TEST_F(ProjectPartsManager, NoDuplicateProjectPartAfterUpdatingWithNotNewProjectPart) @@ -216,8 +228,8 @@ TEST_F(ProjectPartsManager, MergeProjectMultipleTimesParts) TEST_F(ProjectPartsManager, GetNewProjectParts) { - auto newProjectParts = manager.filterNewProjectParts({projectPartContainer1, projectPartContainer2}, - {projectPartContainer2}); + auto newProjectParts = manager.filterProjectParts({projectPartContainer1, projectPartContainer2}, + {projectPartContainer2}); ASSERT_THAT(newProjectParts, ElementsAre(projectPartContainer1)); } @@ -226,9 +238,12 @@ TEST_F(ProjectPartsManager, GetUpdatedProjectPart) { manager.update({projectPartContainer1, projectPartContainer2}); - auto updatedProjectParts = manager.update({updatedProjectPartContainer1}); + auto projectParts = manager.update({updatedProjectPartContainer1}); - ASSERT_THAT(updatedProjectParts, ElementsAre(updatedProjectPartContainer1)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, + ElementsAre(updatedProjectPartContainer1)))); } TEST_F(ProjectPartsManager, ProjectPartIsReplacedWithUpdatedProjectPart) @@ -280,14 +295,14 @@ TEST_F(ProjectPartsManager, UpdateDeferred) TEST_F(ProjectPartsManager, NotUpdateDeferred) { - auto projectPartContainers = manager.update({projectPartContainer1, projectPartContainer2}); + manager.update({projectPartContainer1, projectPartContainer2}); ASSERT_THAT(manager.deferredUpdates(), IsEmpty()); } TEST_F(ProjectPartsManager, UpdateDeferredCleansDeferredUpdates) { - auto projectPartContainers = manager.update({projectPartContainer1, projectPartContainer2}); + manager.update({projectPartContainer1, projectPartContainer2}); manager.updateDeferred({projectPartContainer1}); manager.deferredUpdates(); @@ -386,9 +401,11 @@ TEST_F(ProjectPartsManager, ON_CALL(mockProjectPartsStorage, fetchProjectParts(_)) .WillByDefault(Return(ProjectPartContainers{projectPartContainerWithoutPrecompiledHeader1})); - auto updatedProjectParts = manager.update({projectPartContainer1}); + auto projectParts = manager.update({projectPartContainer1}); - ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1)); + ASSERT_THAT(projectParts, + AllOf(Field(&UpToDataProjectParts::upToDate, IsEmpty()), + Field(&UpToDataProjectParts::notUpToDate, ElementsAre(projectPartContainer1)))); } TEST_F(ProjectPartsManager, ProjectPartAddedWithProjectPartAlreadyInTheDatabaseButWithoutEntries) diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp index c4744148abc..1a5e6ebe0be 100644 --- a/tests/unit/unittest/projectupdater-test.cpp +++ b/tests/unit/unittest/projectupdater-test.cpp @@ -89,7 +89,7 @@ protected: void SetUp() override { - project.rootProjectDirectoryPath.pathAppended("project"); + project.rootProjectDirectoryPath = Utils::FilePath::fromString("project"); projectPart.project = &project; projectPart.files.push_back(header1ProjectFile); projectPart.files.push_back(header2ProjectFile); diff --git a/tests/unit/unittest/refactoringprojectupdater-test.cpp b/tests/unit/unittest/refactoringprojectupdater-test.cpp index 6331fc3016e..eddeefa24c7 100644 --- a/tests/unit/unittest/refactoringprojectupdater-test.cpp +++ b/tests/unit/unittest/refactoringprojectupdater-test.cpp @@ -104,7 +104,7 @@ TEST_F(RefactoringProjectUpdater, DontUpdateProjectPartIfNoProjectPartExistsForI EXPECT_CALL(mockCppModelManager, projectPartForId(Eq(QString("project1")))); EXPECT_CALL(mockRefactoringServer, updateProjectParts(_)).Times(0); - pchManagerClient.precompiledHeadersUpdated({{{3, "/path/to/pch", 12}}}); + pchManagerClient.precompiledHeadersUpdated({3}); } TEST_F(RefactoringProjectUpdater, UpdateProjectPart) @@ -121,7 +121,7 @@ TEST_F(RefactoringProjectUpdater, UpdateProjectPart) updateProjectParts(Field(&UpdateProjectPartsMessage::projectsParts, ElementsAre(IsProjectPartContainer(3))))); - pchManagerClient.precompiledHeadersUpdated({{{3, "/path/to/pch", 12}}}); + pchManagerClient.precompiledHeadersUpdated({3}); } TEST_F(RefactoringProjectUpdater, RemoveProjectPart) diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index 2972e2019e9..2db11dc5fbe 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -267,7 +267,8 @@ protected: mockProjectPartsStorage, mockModifiedTimeChecker, testEnvironment}; - SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter}; + NiceMock mockSqliteDatabase; + SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter, mockSqliteDatabase}; Scheduler indexerScheduler{collectorManger, indexerQueue, progressCounter, @@ -921,6 +922,21 @@ TEST_F(SymbolIndexer, DependentSourceAreUpToDate) indexer.updateProjectParts({projectPart1}); } +TEST_F(SymbolIndexer, SourcesAreWatched) +{ + using ClangBackEnd::IdPaths; + InSequence s; + FilePathIds sourcePathIds{4, 6, 8}; + + EXPECT_CALL(mockBuildDependenciesStorage, fetchSources(projectPart1.projectPartId)) + .WillOnce(Return(sourcePathIds)); + EXPECT_CALL(mockPathWatcher, + updateIdPaths(ElementsAre(AllOf(Field(&IdPaths::id, projectPart1.projectPartId), + Field(&IdPaths::filePathIds, sourcePathIds))))); + + indexer.updateProjectParts({projectPart1}); +} + TEST_F(SymbolIndexer, CallSetNotifier) { EXPECT_CALL(mockPathWatcher, setNotifier(_)); diff --git a/tests/unit/unittest/symbolindexertaskqueue-test.cpp b/tests/unit/unittest/symbolindexertaskqueue-test.cpp index 2932310eb0f..1364091161a 100644 --- a/tests/unit/unittest/symbolindexertaskqueue-test.cpp +++ b/tests/unit/unittest/symbolindexertaskqueue-test.cpp @@ -25,6 +25,7 @@ #include "googletest.h" +#include "mocksqlitedatabase.h" #include "mocktaskscheduler.h" #include @@ -54,7 +55,8 @@ protected: NiceMock> mockSetProgressCallback; ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()}; NiceMock> mockTaskScheduler; - ClangBackEnd::SymbolIndexerTaskQueue queue{mockTaskScheduler, progressCounter}; + NiceMock mockSqliteDatabase; + ClangBackEnd::SymbolIndexerTaskQueue queue{mockTaskScheduler, progressCounter, mockSqliteDatabase}; }; TEST_F(SymbolIndexerTaskQueue, AddTasks) @@ -208,4 +210,35 @@ TEST_F(SymbolIndexerTaskQueue, ProcessTasksRemovesProcessedTasks) ASSERT_THAT(queue.tasks(), SizeIs(1)); } + +TEST_F(SymbolIndexerTaskQueue, + ProcessTasksWritesBackTheDatabaseLogIfTheQueueIsEmptyAndTheIndexerHasNothingToDo) +{ + InSequence s; + + EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0})); + EXPECT_CALL(mockSqliteDatabase, walCheckpointFull()); + + queue.processEntries(); } + +TEST_F(SymbolIndexerTaskQueue, ProcessTasksDoesNotWritesBackTheDatabaseLogIfTheIndexerHasSomethingToDo) +{ + InSequence s; + + EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{1, 1})); + EXPECT_CALL(mockSqliteDatabase, walCheckpointFull()).Times(0); + + queue.processEntries(); +} + +TEST_F(SymbolIndexerTaskQueue, HandleExeptionInWalCheckPoint) +{ + InSequence s; + + EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0})); + EXPECT_CALL(mockSqliteDatabase, walCheckpointFull()).WillOnce(Throw(Sqlite::DatabaseIsBusy{""})); + + queue.processEntries(); +} +} // namespace diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index 48e4420dc12..f0080a5d2c3 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -271,56 +271,6 @@ TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile)) Contains(HasSymbolName("function"))); } -TEST_F(SymbolsCollector, SourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceFiles(), - UnorderedElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), - filePathId(TESTDATA_DIR "/symbolscollector/header1.h"), - filePathId(TESTDATA_DIR "/symbolscollector/header2.h"))); -} - -TEST_F(SymbolsCollector, MainFileInSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - ASSERT_THAT(collector.sourceFiles(), - ElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"))); -} - -TEST_F(SymbolsCollector, ResetMainFileInSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - ASSERT_THAT(collector.sourceFiles(), - ElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"))); -} - -TEST_F(SymbolsCollector, DontDuplicateSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - collector.collectSymbols(); - - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceFiles(), - UnorderedElementsAre(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), - filePathId(TESTDATA_DIR "/symbolscollector/header1.h"), - filePathId(TESTDATA_DIR "/symbolscollector/header2.h"))); -} - -TEST_F(SymbolsCollector, ClearSourceFiles) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - - ASSERT_THAT(collector.sourceFiles(), IsEmpty()); -} - TEST_F(SymbolsCollector, ClearSymbols) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); @@ -351,27 +301,6 @@ TEST_F(SymbolsCollector, ClearFileStatus) ASSERT_THAT(collector.fileStatuses(), IsEmpty()); } -TEST_F(SymbolsCollector, ClearUsedMacros) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/defines.h"), {"cc"}); - collector.collectSymbols(); - - collector.clear(); - - ASSERT_THAT(collector.usedMacros(), IsEmpty()); -} - -TEST_F(SymbolsCollector, ClearSourceDependencies) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main2.cpp"), - {"cc", "-I" TESTDATA_DIR}); - collector.collectSymbols(); - - collector.clear(); - - ASSERT_THAT(collector.sourceDependencies(), IsEmpty()); -} - TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); @@ -382,16 +311,6 @@ TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared) ASSERT_THAT(collector.symbols(), IsEmpty()); } -TEST_F(SymbolsCollector, DontCollectSourceFilesAfterFilesAreCleared) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceFiles(), IsEmpty()); -} - TEST_F(SymbolsCollector, DontCollectFileStatusAfterFilesAreCleared) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); @@ -402,82 +321,6 @@ TEST_F(SymbolsCollector, DontCollectFileStatusAfterFilesAreCleared) ASSERT_THAT(collector.fileStatuses(), IsEmpty()); } -TEST_F(SymbolsCollector, DontCollectUsedMacrosAfterFilesAreCleared) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), IsEmpty()); -} - -TEST_F(SymbolsCollector, DontCollectSourceDependenciesAfterFilesAreCleared) -{ - collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/main.cpp"), {"cc"}); - - collector.clear(); - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceDependencies(), IsEmpty()); -} - -TEST_F(SymbolsCollector, CollectUsedMacrosWithExternalDefine) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), - Eq(UsedMacro{"IF_DEFINE", fileId}), - Eq(UsedMacro{"__clang__", fileId}), - Eq(UsedMacro{"CLASS_EXPORT", fileId}), - Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), - Eq(UsedMacro{"MACRO_EXPANSION", fileId}), - Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); -} - -TEST_F(SymbolsCollector, CollectUsedMacrosWithoutExternalDefine) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), - Eq(UsedMacro{"IF_DEFINE", fileId}), - Eq(UsedMacro{"__clang__", fileId}), - Eq(UsedMacro{"CLASS_EXPORT", fileId}), - Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), - Eq(UsedMacro{"MACRO_EXPANSION", fileId}), - Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); -} - -TEST_F(SymbolsCollector, DontCollectHeaderGuards) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - Not(Contains(Eq(UsedMacro{"SYMBOLSCOLLECTOR_DEFINES_H", fileId})))); -} - -TEST_F(SymbolsCollector, DISABLED_DontCollectDynamicLibraryExports) -{ - auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); - collector.setFile(fileId, {"cc"}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.usedMacros(), - Not(Contains(Eq(UsedMacro{"CLASS_EXPORT", fileId})))); -} - TEST_F(SymbolsCollector, CollectMacroDefinitionSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); @@ -489,7 +332,7 @@ TEST_F(SymbolsCollector, CollectMacroDefinitionSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 4, 9, SourceLocationKind::MacroDefinition))); } -TEST_F(SymbolsCollector, CollectMacroUsageInIfNotDefSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageInIfNotDefSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -500,7 +343,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageInIfNotDefSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 6, 9, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectSecondMacroUsageInIfNotDefSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectSecondMacroUsageInIfNotDefSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -511,7 +354,7 @@ TEST_F(SymbolsCollector, CollectSecondMacroUsageInIfNotDefSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 9, 9, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectMacroUsageCompilerArgumentSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageCompilerArgumentSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -522,7 +365,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageCompilerArgumentSourceLocation) Contains(IsSourceLocationEntry(symbolId("COMPILER_ARGUMENT"), fileId, 12, 9, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectMacroUsageInIfDefSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageInIfDefSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -533,7 +376,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageInIfDefSourceLocation) Contains(IsSourceLocationEntry(symbolId("IF_DEFINE"), fileId, 17, 8, SourceLocationKind::MacroUsage))); } -TEST_F(SymbolsCollector, CollectMacroUsageInDefinedSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageInDefinedSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -566,7 +409,7 @@ TEST_F(SymbolsCollector, CollectMacroUsageUndefSourceLocation) Contains(IsSourceLocationEntry(symbolId("UN_DEFINE"), fileId, 34, 8, SourceLocationKind::MacroUndefinition))); } -TEST_F(SymbolsCollector, CollectMacroUsageBuiltInSourceLocation) +TEST_F(SymbolsCollector, DISABLED_CollectMacroUsageBuiltInSourceLocation) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -588,7 +431,7 @@ TEST_F(SymbolsCollector, CollectMacroDefinitionSymbols) Contains(AllOf(HasSymbolName("IF_NOT_DEFINE"), HasSymbolKind(SymbolKind::Macro)))); } -TEST_F(SymbolsCollector, CollectMacroBuiltInSymbols) +TEST_F(SymbolsCollector, DISABLED_CollectMacroBuiltInSymbols) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc"}); @@ -599,7 +442,7 @@ TEST_F(SymbolsCollector, CollectMacroBuiltInSymbols) Contains(AllOf(HasSymbolName("__clang__"), HasSymbolKind(SymbolKind::Macro)))); } -TEST_F(SymbolsCollector, CollectMacroCompilerArgumentSymbols) +TEST_F(SymbolsCollector, DISABLED_CollectMacroCompilerArgumentSymbols) { auto fileId = filePathId(TESTDATA_DIR "/symbolscollector/defines.h"); collector.setFile(fileId, {"cc", "-DCOMPILER_ARGUMENT"}); @@ -623,23 +466,6 @@ TEST_F(SymbolsCollector, CollectFileStatuses) fileStatus(TESTDATA_DIR "/symbolscollector/header2.h"))); } -TEST_F(SymbolsCollector, CollectSourceDependencies) -{ - auto mainFileId = filePathId(TESTDATA_DIR "/symbolscollector/main2.cpp"); - auto header1FileId = filePathId(TESTDATA_DIR "/symbolscollector/header1.h"); - auto header2FileId = filePathId(TESTDATA_DIR "/symbolscollector/header2.h"); - auto header3FileId = filePathId(TESTDATA_DIR "/symbolscollector/header3.h"); - collector.setFile(mainFileId, {"cc", "-I" TESTDATA_DIR}); - - collector.collectSymbols(); - - ASSERT_THAT(collector.sourceDependencies(), - UnorderedElementsAre(SourceDependency(mainFileId, header1FileId), - SourceDependency(mainFileId, header3FileId), - SourceDependency(header3FileId, header2FileId), - SourceDependency(header1FileId, header2FileId))); -} - TEST_F(SymbolsCollector, IsClassSymbol) { collector.setFile(filePathId(TESTDATA_DIR "/symbolscollector/symbolkind.cpp"), {"cc"}); @@ -770,13 +596,13 @@ TEST_F(SymbolsCollector, DontIndexUnmodifiedHeaderFilesAtSecondRun) collector.collectSymbols(); ASSERT_THAT(collector.symbols(), - AllOf( - Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), - Not(Contains(HasSymbolName("MemberReference"))), - Not(Contains(HasSymbolName("HeaderFunctionReference"))), - Not(Contains(HasSymbolName("HeaderFunction"))), - Not(Contains(HasSymbolName("Class"))), - Not(Contains(HasSymbolName("Member"))))); + AllOf(Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), + Not(Contains(HasSymbolName("MemberReference"))), + Not(Contains(HasSymbolName("HeaderFunctionReference"))), + Not(Contains(HasSymbolName("HeaderFunction"))), + Not(Contains(HasSymbolName("Class"))), + Not(Contains(HasSymbolName("Member"))), + Not(Contains(HasSymbolName("HEADER_DEFINE"))))); } TEST_F(SymbolsCollector, DontIndexUnmodifiedHeaderFilesAtTouchHeader) @@ -792,13 +618,14 @@ TEST_F(SymbolsCollector, DontIndexUnmodifiedHeaderFilesAtTouchHeader) collector.collectSymbols(); ASSERT_THAT(collector.symbols(), - AllOf( - Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), - Not(Contains(HasSymbolName("MemberReference"))), - Not(Contains(HasSymbolName("HeaderFunctionReference"))), - Not(Contains(HasSymbolName("HeaderFunction"))), - Not(Contains(HasSymbolName("Class"))), - Not(Contains(HasSymbolName("Member"))))); + AllOf(Contains(HasSymbolName("TouchHeaderFunction")), + Contains(HasSymbolName("HeaderFunctionReferenceInMainFile")), + Not(Contains(HasSymbolName("MemberReference"))), + Not(Contains(HasSymbolName("HeaderFunctionReference"))), + Not(Contains(HasSymbolName("HeaderFunction"))), + Not(Contains(HasSymbolName("Class"))), + Not(Contains(HasSymbolName("Member"))), + Not(Contains(HasSymbolName("HEADER_DEFINE"))))); } TEST_F(SymbolsCollector, DontIndexSystemIncudes)