Merge remote-tracking branch 'origin/4.7'

Conflicts:
	src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h

Change-Id: I192b9e88f967182f3275b4b98abed1220c26daac
This commit is contained in:
Eike Ziller
2018-05-28 16:10:23 +02:00
206 changed files with 2634 additions and 1715 deletions

51
dist/changes-4.6.2.md vendored Normal file
View File

@@ -0,0 +1,51 @@
Qt Creator version 4.6.2 contains bug fixes.
The most important changes are listed in this document. For a complete
list of changes, see the Git log for the Qt Creator sources that
you can check out from the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline v4.6.1..v4.6.2
General
QMake Projects
* Fixed reparsing after changes (QTCREATORBUG-20113)
Qt Support
* Fixed detection of Qt Quick Compiler in Qt 5.11 (QTCREATORBUG-19993)
C++ Support
* Fixed flags for C files with MSVC (QTCREATORBUG-20198)
Debugging
* Fixed crash when attaching to remote process (QTCREATORBUG-20331)
Platform Specific
macOS
* Fixed signature of pre-built binaries (QTCREATORBUG-20370)
Android
* Fixed path to C++ includes (QTCREATORBUG-20340)
QNX
* Fixed restoring deploy steps (QTCREATORBUG-20248)
Credits for these changes go to:
Alessandro Portale
André Pönitz
Christian Stenger
Eike Ziller
Ivan Donchevskii
Oswald Buddenhagen
Robert Löhning
Ulf Hermann
Vikas Pachdha

129
dist/changes-4.7.0.md vendored
View File

@@ -9,27 +9,77 @@ you can check out from the public Git repository. For example:
General General
* Added option for enabling and disabling HiDPI scaling on Windows and Linux
(QTCREATORBUG-20232)
* Added `Properties` item to context menu on files (QTCREATORBUG-19588)
* Added `New Search` button to search results pane (QTCREATORBUG-17870)
* Added option to show only icons in mode selector (QTCREATORBUG-18845)
* File System View
* Added `New Folder` (QTCREATORBUG-17358)
* Added `Collapse All` (QTCREATORBUG-19212)
* Added option to show folders on top (QTCREATORBUG-7818)
* Made synchronization of root directory with current document optional
(QTCREATORBUG-19322)
Editing Editing
* Made replacement with regular expression search more perl-like (`$<number>`
and `$&` are supported, whereas `&` is no longer used for captures)
(QTCREATORBUG-9602, QTCREATORBUG-15175)
* Added `Context Help` to editor context menu (QTCREATORBUG-55)
* Added previous and next buttons to bookmarks view, and polished their
behavior (QTCREATORBUG-9859, QTCREATORBUG-20061)
* Fixed that extra editor windows were not restored when opening session
(QTCREATORBUG-13840)
* FakeVim
* Added `:<range>sor[t][!]`
Help Help
* Improved performance impact on start up
All Projects All Projects
* Moved kit settings to separate options category * Moved kit settings to separate options category
* Made it easier to abort builds by changing build button to stop button while
building (QTCREATORBUG-20155)
* Added project type specific warnings and errors for kits, and made them
visible in `Projects` mode
* Added shortcut for showing current document in project tree * Added shortcut for showing current document in project tree
(QTCREATORBUG-19625) (QTCREATORBUG-19625)
* Added global option for `Add linker library search paths to run environment`
(QTCREATORBUG-20240)
CMake Projects QMake Projects
Qbs Projects * Added support for `-isystem` in `QMAKE_CXXFLAGS`
* Added deployment rules for devices to widget and console application wizards
(QTCREATORBUG-20358)
C++ Support C++ Support
* Improved resize behavior of editor tool bar
(QTCREATORBUG-15218, QTCREATORBUG-19386)
* Fixed auto-insertion of closing brace and semicolon after classes * Fixed auto-insertion of closing brace and semicolon after classes
(QTCREATORBUG-19726) (QTCREATORBUG-19726)
* Fixed location information of macros (QTCREATORBUG-19905)
* Clang Code Model * Clang Code Model
* Enabled by default
* Switched to Clang 6.0
* Implemented outline pane, outline dropdown and * Implemented outline pane, outline dropdown and
`C++ Symbols in Current Document` locator filter `C++ Symbols in Current Document` locator filter
* Implemented `Follow Symbol` for single translation unit
* Added type highlighting for Objective-C/C++
* Added errors and warnings of current editor to Issues pane
(category `Clang Code Model`)
* Added highlighting style for overloaded operators (QTCREATORBUG-19659)
* Added option to use `.clang-tidy` configuration file or checks string
* Added link to the documentation in tooltip for Clang-Tidy and Clazy
diagnostics
* Improved reparse performance and memory usage
* Improved selecting and deselecting specific Clang-Tidy checks
* Fixed slow completion in case Clang-Tidy or Clazy checks were enabled
* Fixed crashes when closing documents fast
* Built-in Code Model * Built-in Code Model
* Added support for nested namespaces (QTCREATORBUG-16774) * Added support for nested namespaces (QTCREATORBUG-16774)
@@ -37,18 +87,31 @@ QML Support
* Updated parser to Qt 5.10, adding support for user-defined enums * Updated parser to Qt 5.10, adding support for user-defined enums
* Fixed that linter warning `M127` was shown as error (QTCREATORBUG-19534) * Fixed that linter warning `M127` was shown as error (QTCREATORBUG-19534)
* Fixed that reformatting incorrectly removed quotes (QTCREATORBUG-17455)
* Fixed that `.pragma` and `.import` were removed when reformatting
(QTCREATORBUG-13038)
Debugging Python Support
* Added stack traces in application output to Issues pane (category `Python`)
Clang Static Analyzer
* Renamed plugin to `ClangTools`
* Replaced Clang static analyzer by tool that runs Clang-Tidy and Clazy over
whole project or a subset of the project's files
QML Profiler QML Profiler
* Improved performance of timeline * Improved performance of timeline
* Added zooming into flame graph items
Qt Quick Designer
Version Control Systems Version Control Systems
Diff Viewer * Git
* Added `-git-show <ref>` command line parameter
* Gerrit
* Added warning when pushing to wrong branch (QTCREATORBUG-20062)
Image Viewer Image Viewer
@@ -56,16 +119,66 @@ Image Viewer
Test Integration Test Integration
Model Editor * Added `Run Test Under Cursor` to C++ editor
* Added editor marks for failed test locations (QTCREATORBUG-20328)
* Google Test
* Added support for filters
* Fixed issue with jumping to file and line of failing test
(QTCREATORBUG-18725)
* Qt Quick
* Fixed parsing issue with non-ASCII characters (QTCREATORBUG-20105)
Platform Specific Platform Specific
Windows Windows
* Improved parsing of MSVC error messages (QTCREATORBUG-20297)
* Fixed that querying MSVC tool chains at startup could block Qt Creator * Fixed that querying MSVC tool chains at startup could block Qt Creator
* Fixed issue with Clang and Qt 5.8 and later (QTCREATORBUG-20021)
Android Android
Remote Linux * Improved behavior when emulator cannot be started (QTCREATORBUG-20160)
Credits for these changes go to: Credits for these changes go to:
Aleix Pol
Alessandro Portale
Alexander Drozdov
Andre Hartmann
André Pönitz
Antonio Di Monaco
Arnold Dumas
Benjamin Balga
Christian Kandeler
Christian Stenger
Claus Steuer
Colin Duquesnoy
David Schulz
Eike Ziller
Friedemann Kleint
Hugo Holgersson
Ivan Donchevskii
Jaroslaw Kobus
Jay Gupta
Jörg Bornemann
Kari Oikarinen
Leena Miettinen
Marco Benelli
Marco Bubke
Mitch Curtis
Nikita Baryshnikov
Nikolai Kosjar
Orgad Shaneh
Pawel Rutka
Przemyslaw Gorszkowski
Razi Alavizadeh
Robert Löhning
Rune Espeseth
Sergey Morozov
Tasuku Suzuki
Thiago Macieira
Thomas Hartmann
Tim Jenssen
Tobias Hunger
Ulf Hermann
Vikas Pachdha

View File

@@ -65,7 +65,7 @@ qhp.QtCreator.indexRoot =
qhp.QtCreator.subprojects = manual qhp.QtCreator.subprojects = manual
qhp.QtCreator.subprojects.manual.title = Qt Creator Manual qhp.QtCreator.subprojects.manual.title = Qt Creator Manual
qhp.QtCreator.subprojects.manual.indexTitle = Qt Creator TOC qhp.QtCreator.subprojects.manual.indexTitle = All Topics
qhp.QtCreator.subprojects.manual.type = manual qhp.QtCreator.subprojects.manual.type = manual
# Doxygen compatibility commands # Doxygen compatibility commands

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -85,8 +85,8 @@
include several files, processing a single file and all the included files include several files, processing a single file and all the included files
can take a while. can take a while.
The following services are currently implemented in the Clang The Clang code model plugin replaces services of the old C/C++ code model.
code model plugin: Currently the following services are implemented:
\list \list
@@ -100,8 +100,6 @@
\endlist \endlist
To use the plugin, you must activate it and configure it in \QC.
\section1 Code Model Warnings \section1 Code Model Warnings
The predefined configurations request Clang warnings at the following The predefined configurations request Clang warnings at the following
@@ -156,26 +154,6 @@
\l{https://github.com/KDE/clazy/blob/master/README.md#list-of-checks} \l{https://github.com/KDE/clazy/blob/master/README.md#list-of-checks}
{List of Checks} in the Clazy documentation. {List of Checks} in the Clazy documentation.
\section1 Activating Clang Code Model
If you build \QC yourself, ensure that the plugin is also built, as
described in the \QC
\l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/README.md}{README file}.
To activate the plugin:
\list 1
\li Select \uicontrol Help > \uicontrol {About Plugins} >
\uicontrol {C++} > \uicontrol ClangCodeModel to enable the plugin.
\li Restart \QC to be able to use the plugin.
If you build \QC yourself, add \c ${LLVM_INSTALL_DIR}\bin to the
\c PATH variable so the LLVM libraries will be found on startup.
\endlist
\section1 Configuring Clang Code Model \section1 Configuring Clang Code Model
To specify settings for the Clang code model: To specify settings for the Clang code model:

View File

@@ -159,9 +159,19 @@
\uicontrol {Edit Bookmark}. To view the note, move the mouse pointer over \uicontrol {Edit Bookmark}. To view the note, move the mouse pointer over
the bookmark. the bookmark.
To go to previous bookmark in the current session, press \key {Ctrl+,}. To go to the previous bookmark in the current session, select
\uicontrol Tools \uicontrol Bookmarks > \uicontrol {Previous Bookmark}
or press \key {Ctrl+,}.
To go to next bookmark in the current session, press \key {Ctrl+.}. To go to the next bookmark in the current session, select \uicontrol Tools
\uicontrol Bookmarks > \uicontrol {Previous Bookmark} or press
\key {Ctrl+.}.
Bookmarks are listed in the \uicontrol Bookmarks view in the sidebar. To
move between bookmarks, select the \uicontrol {Previous Bookmark} or
\uicontrol {Next Bookmark} button or use the keyboard shortcuts.
\image qtcreator-bookmarks-view.png
\section1 Moving to Symbol Definition or Declaration \section1 Moving to Symbol Definition or Declaration

View File

@@ -1848,6 +1848,12 @@
The search results are stored in the search history from which you can The search results are stored in the search history from which you can
select earlier searches. select earlier searches.
To clear the search results, select the \inlineimage clean_pane_small.png
(\uicontrol Clear) button.
To start a new search, select the \inlineimage qtcreator-new-search-icon.png
(\uicontrol {New Search}) button.
\note You can use \uicontrol {Advanced Find} also to search for symbols. For \note You can use \uicontrol {Advanced Find} also to search for symbols. For
more information, see \l{Finding Symbols}. more information, see \l{Finding Symbols}.
@@ -1999,6 +2005,9 @@
\inlineimage clean_pane_small.png \inlineimage clean_pane_small.png
(\uicontrol Clear) button. (\uicontrol Clear) button.
\li To start a new search, click the
\inlineimage qtcreator-new-search-icon.png
(\uicontrol {New Search}) button.
\endlist \endlist
\section1 Renaming Symbols \section1 Renaming Symbols

View File

@@ -49,7 +49,8 @@
is not available, the tooltip displays type information for the is not available, the tooltip displays type information for the
symbol. symbol.
\li To display the full help on a Qt class or function, press \key F1. \li To display the full help on a Qt class or function, press \key F1 or
select \uicontrol {Context Help} in the context menu.
The documentation is displayed in a The documentation is displayed in a
pane next to the code editor, or, if there is not enough vertical pane next to the code editor, or, if there is not enough vertical
space, in the fullscreen \uicontrol Help mode. space, in the fullscreen \uicontrol Help mode.

View File

@@ -74,7 +74,9 @@
{corresponding keyboard shortcut}. {corresponding keyboard shortcut}.
To hide the mode selector and to save space on the display, select To hide the mode selector and to save space on the display, select
\uicontrol Window > \uicontrol {Show Mode Selector}. \uicontrol Window > \uicontrol {Mode Selector Style} > \uicontrol Hidden.
To only show icons on the mode selector, select the \uicontrol {Icons Only}
style.
The following image displays an example application in \uicontrol Edit mode (1) The following image displays an example application in \uicontrol Edit mode (1)
and \uicontrol Design mode (2). and \uicontrol Design mode (2).
@@ -263,7 +265,9 @@
By default, the contents of the directory that contains the file currently By default, the contents of the directory that contains the file currently
active in the editor are displayed. The path to the active file is displayed active in the editor are displayed. The path to the active file is displayed
as bread crumbs. You can move to any directory along the path by clicking as bread crumbs. You can move to any directory along the path by clicking
it. it. To hide the bread crumbs, select \inlineimage filtericon.png
(\uicontrol Options) and then deselect the \uicontrol {Show Bread Crumbs}
check box.
To move to the root directory of the To move to the root directory of the
file system, select \uicontrol Computer in the menu (1). Select file system, select \uicontrol Computer in the menu (1). Select
@@ -271,12 +275,16 @@
select a project to move to an open project or \uicontrol Projects to open select a project to move to an open project or \uicontrol Projects to open
the \uicontrol Projects view. the \uicontrol Projects view.
By default, folders are separated from files and listed first in the view.
To list all items in alphabetic order, select \uicontrol Options and then
deselect the \uicontrol {Show Folders on Top} check box.
To also show hidden files, select \uicontrol Options >
\uicontrol {Show Hidden Files}.
To stop the synchronization with the file currently opened in the editor, To stop the synchronization with the file currently opened in the editor,
deselect \uicontrol {Synchronize with Editor}. deselect \uicontrol {Synchronize with Editor}.
To also show hidden files, select \uicontrol {Filter Files} >
\uicontrol {Show Hidden Files}.
Use the context menu functions to: Use the context menu functions to:
\list \list
@@ -292,16 +300,22 @@
\li Search from the selected directory. \li Search from the selected directory.
\li View file properties, such as MIME type, default editor, and size.
\li Create new files. For more information, see \li Create new files. For more information, see
\l{Adding Files to Projects}. \l{Adding Files to Projects}.
\li Rename or remove existing files. \li Rename or remove existing files.
\li Create new folders.
\li Compare the selected file with the currently open file in the diff \li Compare the selected file with the currently open file in the diff
editor. For more information, see \l{Comparing Files}. editor. For more information, see \l{Comparing Files}.
\li Display the contents of a particular directory in the view. \li Display the contents of a particular directory in the view.
\li Collapse all open folders.
\endlist \endlist
\section2 Viewing the Class Hierarchy \section2 Viewing the Class Hierarchy
@@ -452,7 +466,7 @@
The figure below shows an example search result for all The figure below shows an example search result for all
occurrences of the search string in the specified directory. occurrences of the search string in the specified directory.
\image qtcreator-search-pane.png \image qtcreator-searchresults.png
For more information about the different search options, see For more information about the different search options, see
\l {Finding and Replacing}. \l {Finding and Replacing}.
@@ -601,6 +615,11 @@
\section1 Platform Notes \section1 Platform Notes
This section describes the cases where the behavior of \QC depends on the
operating system it runs on.
\section2 Location of Functions
\QC uses standard names and locations for standard features, such as \QC uses standard names and locations for standard features, such as
\e options or \e preferences. In this manual, the names and locations on \e options or \e preferences. In this manual, the names and locations on
Windows and Linux are usually used to keep the instructions short. Here are Windows and Linux are usually used to keep the instructions short. Here are
@@ -623,4 +642,70 @@
\uicontrol Keyboard \uicontrol Keyboard
\endtable \endtable
\section2 Location of Settings Files
\QC creates the following files and directories:
\list
\li QtCreator.db
\li QtCreator.ini
\li qtversion.xml
\li toolChains.xml
\li qtcreator
\li qtc-qmldump
\endlist
The location of the above files and directories depends on the platform:
\list
\li On Linux and other Unix platforms, the files are located in
\c {~/.config/QtProject} and
\c {~/.local/share/data/QtProject/qtcreator}.
\li On \macos, the files are located in \c {~/.config/QtProject} and
\c {~/Library/Application Support/QtProject/Qt Creator}.
\li On Windows XP, the files are located in
\c {%SystemDrive%\Documents and Settings\%USERNAME%\Application Data\QtProject} and
\c {%SystemDrive%\Documents and Settings\%USERNAME%\Local Settings\Application Data\QtProject}.
\li On Windows 7, the files are located in
\c {%SystemDrive%\Users\%USERNAME%\AppData\Roaming\QtProject} and
\c {%SystemDrive%\Users\%USERNAME%\AppData\Local\QtProject}.
\endlist
\section2 High DPI Scaling
The operating systems supported by \QC implement high dots-per-inch (DPI)
scaling at varying levels. Therefore, \QC handles high DPI scaling
differently on different operating system:
\list
\li On \macos, high DPI scaling is forced, which means that \QC allows
Qt to use the system scaling factor as the \QC scaling factor.
\li On Windows, if no \l{High DPI Support in Qt}
{scaling environment variables} are set, \QC instructs Qt to detect
the scaling factor and use it for \QC.
\li On Linux, \QC leaves it to the user to enable high DPI scaling,
because the process varies so much on different distributions
and windowing systems that it cannot be reliably done automatically.
\endlist
To override the default approach and always enable high-DPI scaling, select
\uicontrol Tools > \uicontrol Options > \uicontrol Environment >
\uicontrol {Enable high DPI scaling}. The changes will take effect after you
restart \QC.
*/ */

View File

@@ -108,37 +108,10 @@
\b {How do I reset all \QC settings?} \b {How do I reset all \QC settings?}
\QC creates the following files and directories: Remove the settings files created by \QC.
\list For more information about where the files are located on each supported
platform, see \l {Location of Settings Files}.
\li QtCreator.db
\li QtCreator.ini
\li qtversion.xml
\li toolChains.xml
\li qtcreator
\li qtc-qmldump
\endlist
The location depends on the platform. On Linux and other Unix platforms, the files
are located in \c {~/.config/QtProject} and \c {~/.local/share/data/QtProject/qtcreator}.
On \macos, the files are located in \c {~/.config/QtProject} and
\c {~/Library/Application Support/QtProject/Qt Creator}.
On Windows XP, the files are located in
\c {%SystemDrive%\Documents and Settings\%USERNAME%\Application Data\QtProject} and
\c {%SystemDrive%\Documents and Settings\%USERNAME%\Local Settings\Application Data\QtProject}.
On Windows Vista and Windows 7, the files are located in
\c {%SystemDrive%\Users\%USERNAME%\AppData\Roaming\QtProject} and
\c {%SystemDrive%\Users\%USERNAME%\AppData\Local\QtProject}.
\b {\QC comes with MinGW, should I use this version with Qt?} \b {\QC comes with MinGW, should I use this version with Qt?}

View File

@@ -28,10 +28,7 @@
\contentspage {Qt Creator} \contentspage {Qt Creator}
\page qtcreator-toc.html \page qtcreator-toc.html
\title Qt Creator TOC \title All Topics
This file is used only for generating the TOC for the help file to be
displayed in the Qt Creator Help mode Contents view.
\list \list
\li \l{Getting Started} \li \l{Getting Started}

View File

@@ -121,6 +121,8 @@
\li \l{Known Issues} \li \l{Known Issues}
\li \l{Glossary} \li \l{Glossary}
\endlist \endlist
\row
\li {4,1} \l{All Topics}
\row \row
\li {4,1} \note To report bugs and suggestions to the Qt Bug \li {4,1} \note To report bugs and suggestions to the Qt Bug
Tracker, select \uicontrol {Help > Report Bug}. Tracker, select \uicontrol {Help > Report Bug}.

View File

@@ -0,0 +1,179 @@
#!/usr/bin/env python
############################################################################
#
# Copyright (C) 2018 The Qt Company Ltd.
# Contact: https://www.qt.io/licensing/
#
# This file is part of Qt Creator.
#
# Commercial License Usage
# Licensees holding valid commercial Qt licenses may use this file in
# accordance with the commercial license agreement provided with the
# Software or, alternatively, in accordance with the terms contained in
# a written agreement between you and The Qt Company. For licensing terms
# and conditions see https://www.qt.io/terms-conditions. For further
# information use the contact form at https://www.qt.io/contact-us.
#
# GNU General Public License Usage
# Alternatively, this file may be used under the terms of the GNU
# General Public License version 3 as published by the Free Software
# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
# included in the packaging of this file. Please review the following
# information to ensure the GNU General Public License requirements will
# be met: https://www.gnu.org/licenses/gpl-3.0.html.
#
############################################################################
import argparse
import collections
import os
import re
import subprocess
import sys
import common
def next_common(string, common):
remaining_string = string[len(common):]
parts = re.split("[.\-]+", remaining_string)
return string[:(len(common) + len(parts[0]) + 1)]
def extract_similar(group, group_common):
subgroups = {}
for key, val in group.items():
common = next_common(key, group_common)
if common == group_common or common == key:
continue
if key not in group:
continue
subgroup = {}
for subkey, subval in group.items():
if not subkey.startswith(common):
continue
subgroup[subkey] = subval
del group[subkey]
if len(subgroup) == 1:
group[key] = val
else:
extract_similar(subgroup, common)
subgroups[common] = subgroup
group.update(subgroups)
if '' in group:
del group['']
return group
def print_formatted(group, group_name, indent):
index = 0
for key in sorted(group):
index += 1
comma = ','
if index == len(group):
comma = ''
if len(group[key]) == 0:
print indent + '"' + key[len(group_name):] + '"' + comma
else:
print indent + '{'
print indent + ' "' + key[len(group_name):] + '",'
print indent + ' {'
print_formatted(group[key], key, indent + ' ')
print indent + ' }'
print indent + '}' + comma
def print_to_header_file(group):
print '''/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <vector>
namespace CppTools {
namespace Constants {
struct TidyNode
{
const std::vector<TidyNode> children;
const char *name = nullptr;
TidyNode(const char *name, std::vector<TidyNode> &&children)
: children(std::move(children))
, name(name)
{}
TidyNode(const char *name) : name(name) {}
};
// CLANG-UPGRADE-CHECK: Run 'scripts/generateClangTidyChecks.py' after Clang upgrade to
// update this header.
static const TidyNode CLANG_TIDY_CHECKS_ROOT
{
"",
{'''
print_formatted(group, '', ' ')
print ''' }
};
} // namespace Constants
} // namespace CppTools'''
def parse_arguments():
parser = argparse.ArgumentParser(description="Clang-Tidy checks header file generator")
parser.add_argument('--tidy-path', help='path to clang-tidy binary',
default='clang-tidy.exe' if common.is_windows_platform() else 'clang-tidy', dest='tidypath')
return parser.parse_args()
def main():
arguments = parse_arguments()
process = subprocess.Popen([arguments.tidypath, '-checks=*', '-list-checks'], stdout=subprocess.PIPE)
lines = process.stdout.read().splitlines()
lines.pop(0) # 'Enabled checks:'
major_checks = ['android-', 'boost-', 'bugprone-', 'cert-', 'clang-analyzer-',
'cppcoreguidelines-', 'fuchsia-', 'google-', 'hicpp-', 'llvm-', 'misc-', 'modernize-',
'mpi-', 'objc-', 'performance-', 'readability-']
current_major = 0
major_groups = {}
for line in lines:
line = line.strip()
if current_major < (len(major_checks) - 1) and line.startswith(major_checks[current_major + 1]):
current_major += 1
if major_checks[current_major] not in major_groups:
major_groups[major_checks[current_major]] = {}
major_groups[major_checks[current_major]][line] = {}
for major_check, group in major_groups.items():
major_groups[major_check] = extract_similar(group, major_check)
current_path = os.path.dirname(os.path.abspath(__file__))
header_path = os.path.abspath(os.path.join(current_path, '..', 'src', 'plugins', 'cpptools', 'cpptools_clangtidychecks.h'))
default_stdout = sys.stdout
header_file = open(header_path, 'w')
sys.stdout = header_file
print_to_header_file(major_groups)
sys.stdout = default_stdout
header_file.close()
if __name__ == "__main__":
main()

View File

@@ -492,7 +492,7 @@ def qdump__QFile(d, value):
if qtVersion >= 0x050700: if qtVersion >= 0x050700:
if d.isWindowsTarget(): if d.isWindowsTarget():
if d.isMsvcTarget(): if d.isMsvcTarget():
offset = 184 if is32bit else 248 offset = 176 if is32bit else 248
else: else:
offset = 172 if is32bit else 248 offset = 172 if is32bit else 248
else: else:

View File

@@ -36,6 +36,7 @@ Module {
Property { name: "additionalProductTypes"; type: "string"; isList: true } Property { name: "additionalProductTypes"; type: "string"; isList: true }
Property { name: "condition"; type: "bool" } Property { name: "condition"; type: "bool" }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
Property { name: "prefixMapping"; type: "QVariant" }
Property { name: "present"; type: "bool" } Property { name: "present"; type: "bool" }
Property { name: "setupBuildEnvironment"; type: "QVariant" } Property { name: "setupBuildEnvironment"; type: "QVariant" }
Property { name: "setupRunEnvironment"; type: "QVariant" } Property { name: "setupRunEnvironment"; type: "QVariant" }
@@ -114,7 +115,6 @@ Module {
Property { name: "multiplexed"; type: "bool" } Property { name: "multiplexed"; type: "bool" }
Property { name: "multiplexedType"; type: "string"; isList: true } Property { name: "multiplexedType"; type: "string"; isList: true }
Property { name: "name"; type: "string" } Property { name: "name"; type: "string" }
Property { name: "profile"; type: "string" }
Property { name: "profiles"; type: "string"; isList: true } Property { name: "profiles"; type: "string"; isList: true }
Property { name: "qbsSearchPaths"; type: "string"; isList: true } Property { name: "qbsSearchPaths"; type: "string"; isList: true }
Property { name: "targetName"; type: "string" } Property { name: "targetName"; type: "string" }
@@ -146,6 +146,7 @@ Module {
name: "Properties" name: "Properties"
exports: [ "qbs/Properties 1.0" ] exports: [ "qbs/Properties 1.0" ]
prototype: "QQuickItem" prototype: "QQuickItem"
Property { name: "condition"; type: "bool" }
} }
Component { Component {
name: "PropertyOptions" name: "PropertyOptions"
@@ -164,7 +165,9 @@ Module {
Property { name: "auxiliaryInputs"; type: "string"; isList: true } Property { name: "auxiliaryInputs"; type: "string"; isList: true }
Property { name: "condition"; type: "bool" } Property { name: "condition"; type: "bool" }
Property { name: "excludedAuxiliaryInputs"; type: "string"; isList: true } Property { name: "excludedAuxiliaryInputs"; type: "string"; isList: true }
Property { name: "excludedInputs"; type: "string"; isList: true }
Property { name: "explicitlyDependsOn"; type: "string"; isList: true } Property { name: "explicitlyDependsOn"; type: "string"; isList: true }
Property { name: "explicitlyDependsOnFromDependencies"; type: "string"; isList: true }
Property { name: "inputs"; type: "string"; isList: true } Property { name: "inputs"; type: "string"; isList: true }
Property { name: "inputsFromDependencies"; type: "string"; isList: true } Property { name: "inputsFromDependencies"; type: "string"; isList: true }
Property { name: "multiplex"; type: "bool" } Property { name: "multiplex"; type: "bool" }

View File

@@ -107,6 +107,11 @@ int TimelineTraceManager::numEventTypes() const
return d->typeStorage->size(); return d->typeStorage->size();
} }
void TimelineTraceManager::swapEventStorage(std::unique_ptr<TraceEventStorage> &other)
{
d->eventStorage.swap(other);
}
const TraceEventStorage *TimelineTraceManager::eventStorage() const const TraceEventStorage *TimelineTraceManager::eventStorage() const
{ {
return d->eventStorage.get(); return d->eventStorage.get();

View File

@@ -125,6 +125,7 @@ signals:
void recordedFeaturesChanged(quint64 features); void recordedFeaturesChanged(quint64 features);
protected: protected:
void swapEventStorage(std::unique_ptr<TraceEventStorage> &other);
virtual void clearEventStorage(); virtual void clearEventStorage();
virtual void clearTypeStorage(); virtual void clearTypeStorage();

View File

@@ -30,6 +30,8 @@
#include <QFile> #include <QFile>
#include <QDataStream> #include <QDataStream>
#include <memory>
namespace Timeline { namespace Timeline {
template<typename Event> template<typename Event>
@@ -59,21 +61,90 @@ public:
ReplayReadPastEnd ReplayReadPastEnd
}; };
class Iterator
{
private:
friend class TraceStashFile<Event>;
std::unique_ptr<QFile> readFile;
std::unique_ptr<QDataStream> readStream;
Event nextEvent;
bool streamAtEnd;
bool open()
{
if (readFile->open(QIODevice::ReadOnly)) {
readStream->setDevice(readFile.get());
if (readStream->atEnd()) {
streamAtEnd = true;
} else {
(*readStream) >> nextEvent;
if (readPastEnd())
streamAtEnd = true;
}
return true;
}
streamAtEnd = true;
return false;
}
Iterator(const QString &fileName) :
readFile(std::make_unique<QFile>(fileName)),
readStream(std::make_unique<QDataStream>()),
streamAtEnd(false)
{
}
bool readPastEnd() const
{
return readStream->status() == QDataStream::ReadPastEnd;
}
public:
Event next()
{
if (readStream->atEnd()) {
streamAtEnd = true;
return std::move(nextEvent);
}
const Event result = std::move(nextEvent);
(*readStream) >> nextEvent;
if (readPastEnd())
streamAtEnd = true;
return result;
}
const Event &peekNext() const
{
return nextEvent;
}
bool hasNext() const
{
return !streamAtEnd;
}
};
Iterator iterator() const
{
Iterator i(file.fileName());
i.open();
return i;
}
template<typename Loader> template<typename Loader>
ReplayResult replay(const Loader &loader) const ReplayResult replay(const Loader &loader) const
{ {
QFile readFile(file.fileName()); Iterator replayIterator(file.fileName());
if (!readFile.open(QIODevice::ReadOnly)) if (!replayIterator.open())
return ReplayOpenFailed; return ReplayOpenFailed;
QDataStream readStream(&readFile); while (replayIterator.hasNext()) {
while (!readStream.atEnd()) { if (!loader(replayIterator.next()))
Event event;
readStream >> event;
if (readStream.status() == QDataStream::ReadPastEnd)
return ReplayReadPastEnd;
if (!loader(std::move(event)))
return ReplayLoadFailed; return ReplayLoadFailed;
if (replayIterator.readPastEnd())
return ReplayReadPastEnd;
} }
return ReplaySuccess; return ReplaySuccess;

View File

@@ -140,8 +140,9 @@ bool ChangeSet::move_helper(int pos, int length, int to)
{ {
if (hasOverlap(pos, length) if (hasOverlap(pos, length)
|| hasOverlap(to, 0) || hasOverlap(to, 0)
|| overlaps(pos, length, to, 0)) || overlaps(pos, length, to, 0)) {
m_error = true; m_error = true;
}
EditOp cmd(EditOp::Move); EditOp cmd(EditOp::Move);
cmd.pos1 = pos; cmd.pos1 = pos;
@@ -214,8 +215,9 @@ bool ChangeSet::flip_helper(int pos1, int length1, int pos2, int length2)
{ {
if (hasOverlap(pos1, length1) if (hasOverlap(pos1, length1)
|| hasOverlap(pos2, length2) || hasOverlap(pos2, length2)
|| overlaps(pos1, length1, pos2, length2)) || overlaps(pos1, length1, pos2, length2)) {
m_error = true; m_error = true;
}
EditOp cmd(EditOp::Flip); EditOp cmd(EditOp::Flip);
cmd.pos1 = pos1; cmd.pos1 = pos1;
@@ -231,8 +233,9 @@ bool ChangeSet::copy_helper(int pos, int length, int to)
{ {
if (hasOverlap(pos, length) if (hasOverlap(pos, length)
|| hasOverlap(to, 0) || hasOverlap(to, 0)
|| overlaps(pos, length, to, 0)) || overlaps(pos, length, to, 0)) {
m_error = true; m_error = true;
}
EditOp cmd(EditOp::Copy); EditOp cmd(EditOp::Copy);
cmd.pos1 = pos; cmd.pos1 = pos;
@@ -243,27 +246,27 @@ bool ChangeSet::copy_helper(int pos, int length, int to)
return !m_error; return !m_error;
} }
void ChangeSet::doReplace(const EditOp &replace_helper, QList<EditOp> *replaceList) void ChangeSet::doReplace(const EditOp &op, QList<EditOp> *replaceList)
{ {
Q_ASSERT(replace_helper.type == EditOp::Replace); Q_ASSERT(op.type == EditOp::Replace);
{ {
QMutableListIterator<EditOp> i(*replaceList); QMutableListIterator<EditOp> i(*replaceList);
while (i.hasNext()) { while (i.hasNext()) {
EditOp &c = i.next(); EditOp &c = i.next();
if (replace_helper.pos1 <= c.pos1) if (op.pos1 <= c.pos1)
c.pos1 += replace_helper.text.size(); c.pos1 += op.text.size();
if (replace_helper.pos1 < c.pos1) if (op.pos1 < c.pos1)
c.pos1 -= replace_helper.length1; c.pos1 -= op.length1;
} }
} }
if (m_string) { if (m_string) {
m_string->replace(replace_helper.pos1, replace_helper.length1, replace_helper.text); m_string->replace(op.pos1, op.length1, op.text);
} else if (m_cursor) { } else if (m_cursor) {
m_cursor->setPosition(replace_helper.pos1); m_cursor->setPosition(op.pos1);
m_cursor->setPosition(replace_helper.pos1 + replace_helper.length1, QTextCursor::KeepAnchor); m_cursor->setPosition(op.pos1 + op.length1, QTextCursor::KeepAnchor);
m_cursor->insertText(replace_helper.text); m_cursor->insertText(op.text);
} }
} }
@@ -358,22 +361,16 @@ void ChangeSet::apply_helper()
// convert all ops to replace // convert all ops to replace
QList<EditOp> replaceList; QList<EditOp> replaceList;
{ {
while (!m_operationList.isEmpty()) { while (!m_operationList.isEmpty())
const EditOp cmd(m_operationList.first()); convertToReplace(m_operationList.takeFirst(), &replaceList);
m_operationList.removeFirst();
convertToReplace(cmd, &replaceList);
}
} }
// execute replaces // execute replaces
if (m_cursor) if (m_cursor)
m_cursor->beginEditBlock(); m_cursor->beginEditBlock();
while (!replaceList.isEmpty()) { while (!replaceList.isEmpty())
const EditOp cmd(replaceList.first()); doReplace(replaceList.takeFirst(), &replaceList);
replaceList.removeFirst();
doReplace(cmd, &replaceList);
}
if (m_cursor) if (m_cursor)
m_cursor->endEditBlock(); m_cursor->endEditBlock();

View File

@@ -95,7 +95,7 @@ QString FileInProjectFinder::projectDirectory() const
return m_projectDir; return m_projectDir;
} }
void FileInProjectFinder::setProjectFiles(const QStringList &projectFiles) void FileInProjectFinder::setProjectFiles(const Utils::FileNameList &projectFiles)
{ {
if (m_projectFiles == projectFiles) if (m_projectFiles == projectFiles)
return; return;
@@ -309,9 +309,9 @@ QString FileInProjectFinder::findInSearchPath(const QString &searchPath, const Q
QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName) const QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName) const
{ {
QStringList result; QStringList result;
foreach (const QString &f, m_projectFiles) { foreach (const FileName &f, m_projectFiles) {
if (FileName::fromString(f).fileName() == fileName) if (f.fileName() == fileName)
result << f; result << f.toString();
} }
return result; return result;
} }
@@ -319,14 +319,15 @@ QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName)
QStringList FileInProjectFinder::pathSegmentsWithSameName(const QString &pathSegment) const QStringList FileInProjectFinder::pathSegmentsWithSameName(const QString &pathSegment) const
{ {
QStringList result; QStringList result;
for (const QString &f : m_projectFiles) { for (const FileName &f : m_projectFiles) {
QDir dir = FileName::fromString(f).toFileInfo().absoluteDir(); FileName currentPath = f.parentDir();
do { do {
if (dir.dirName() == pathSegment) { if (currentPath.fileName() == pathSegment) {
if (result.isEmpty() || result.last() != dir.path()) if (result.isEmpty() || result.last() != currentPath.toString())
result.append(dir.path()); result.append(currentPath.toString());
} }
} while (dir.cdUp()); currentPath = currentPath.parentDir();
} while (!currentPath.isEmpty());
} }
result.removeDuplicates(); result.removeDuplicates();
return result; return result;

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include <utils/utils_global.h> #include <utils/utils_global.h>
#include <utils/fileutils.h>
#include <QHash> #include <QHash>
#include <QStringList> #include <QStringList>
@@ -48,7 +49,7 @@ public:
void setProjectDirectory(const QString &absoluteProjectPath); void setProjectDirectory(const QString &absoluteProjectPath);
QString projectDirectory() const; QString projectDirectory() const;
void setProjectFiles(const QStringList &projectFiles); void setProjectFiles(const Utils::FileNameList &projectFiles);
void setSysroot(const QString &sysroot); void setSysroot(const QString &sysroot);
QString findFile(const QUrl &fileUrl, bool *success = nullptr) const; QString findFile(const QUrl &fileUrl, bool *success = nullptr) const;
@@ -73,7 +74,7 @@ private:
QString m_projectDir; QString m_projectDir;
QString m_sysroot; QString m_sysroot;
QStringList m_projectFiles; Utils::FileNameList m_projectFiles;
QStringList m_searchDirectories; QStringList m_searchDirectories;
mutable QHash<QString,QString> m_cache; mutable QHash<QString,QString> m_cache;
}; };

View File

@@ -183,6 +183,9 @@ public:
BasicSmallString &operator=(BasicSmallString &&other) noexcept BasicSmallString &operator=(BasicSmallString &&other) noexcept
{ {
if (this == &other)
return *this;
this->~BasicSmallString(); this->~BasicSmallString();
m_data = other.m_data; m_data = other.m_data;

View File

@@ -29,7 +29,6 @@
#include "androidconfigurations.h" #include "androidconfigurations.h"
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runnables.h>
#include <utils/url.h> #include <utils/url.h>

View File

@@ -532,9 +532,7 @@ void AndroidDeviceDialog::devicesRefreshed()
AndroidDeviceInfoList devices = m_futureWatcherRefreshDevices.result(); AndroidDeviceInfoList devices = m_futureWatcherRefreshDevices.result();
QSet<QString> startedAvds = Utils::transform<QSet>(m_connectedDevices, QSet<QString> startedAvds = Utils::transform<QSet>(m_connectedDevices,
[] (const AndroidDeviceInfo &info) { &AndroidDeviceInfo::avdname);
return info.avdname;
});
for (const AndroidDeviceInfo &dev : devices) for (const AndroidDeviceInfo &dev : devices)
if (!startedAvds.contains(dev.avdname)) if (!startedAvds.contains(dev.avdname))

View File

@@ -62,6 +62,17 @@ using namespace ProjectExplorer::Constants;
namespace Android { namespace Android {
namespace Internal { namespace Internal {
class AndroidRunConfigurationFactory : public RunConfigurationFactory
{
public:
AndroidRunConfigurationFactory()
{
registerRunConfiguration<Android::AndroidRunConfiguration>
("Qt4ProjectManager.AndroidRunConfiguration:");
addSupportedTargetDeviceType(Android::Constants::ANDROID_DEVICE_TYPE);
}
};
class AndroidPluginPrivate class AndroidPluginPrivate
{ {
public: public:
@@ -76,6 +87,7 @@ public:
JavaEditorFactory javaEditorFactory; JavaEditorFactory javaEditorFactory;
AndroidPackageInstallationFactory packackeInstallationFactory; AndroidPackageInstallationFactory packackeInstallationFactory;
AndroidManifestEditorFactory manifestEditorFactory; AndroidManifestEditorFactory manifestEditorFactory;
AndroidRunConfigurationFactory runConfigFactory;
}; };
AndroidPlugin::~AndroidPlugin() AndroidPlugin::~AndroidPlugin()
@@ -97,10 +109,7 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
RunControl::registerWorker(QML_PREVIEW_RUN_MODE, [](RunControl *runControl) -> RunWorker* { RunControl::registerWorker(QML_PREVIEW_RUN_MODE, [](RunControl *runControl) -> RunWorker* {
const Runnable runnable = runControl->runConfiguration()->runnable(); const Runnable runnable = runControl->runConfiguration()->runnable();
QTC_ASSERT(runnable.is<StandardRunnable>(), return nullptr); return new AndroidQmlToolingSupport(runControl, runnable.executable, runnable.commandLineArguments);
const StandardRunnable standardRunnable = runnable.as<StandardRunnable>();
return new AndroidQmlToolingSupport(runControl, standardRunnable.executable,
standardRunnable.commandLineArguments);
}, [](RunConfiguration *runConfig) { }, [](RunConfiguration *runConfig) {
return runConfig->isEnabled() return runConfig->isEnabled()
&& runConfig->id().name().startsWith("QmlProjectManager.QmlRunConfiguration") && runConfig->id().name().startsWith("QmlProjectManager.QmlRunConfiguration")

View File

@@ -313,9 +313,7 @@ SdkPlatformList AndroidSdkManager::installedSdkPlatforms()
{ {
AndroidSdkPackageList list = m_d->filteredPackages(AndroidSdkPackage::Installed, AndroidSdkPackageList list = m_d->filteredPackages(AndroidSdkPackage::Installed,
AndroidSdkPackage::SdkPlatformPackage); AndroidSdkPackage::SdkPlatformPackage);
return Utils::transform(list, [](AndroidSdkPackage *p) { return Utils::qobject_container_cast<SdkPlatform *>(list);
return static_cast<SdkPlatform *>(p);
});
} }
const AndroidSdkPackageList &AndroidSdkManager::allSdkPackages() const AndroidSdkPackageList &AndroidSdkManager::allSdkPackages()

View File

@@ -185,7 +185,8 @@ bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorStri
void AutotestPlugin::extensionsInitialized() void AutotestPlugin::extensionsInitialized()
{ {
ActionContainer *contextMenu = ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT); ActionContainer *contextMenu = ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT);
QTC_ASSERT(contextMenu, return); if (!contextMenu) // if QC is started without CppEditor plugin
return;
QAction *action = new QAction(tr("&Run Test Under Cursor"), this); QAction *action = new QAction(tr("&Run Test Under Cursor"), this);
action->setEnabled(false); action->setEnabled(false);

View File

@@ -35,7 +35,6 @@
#include <projectexplorer/deploymentdata.h> #include <projectexplorer/deploymentdata.h>
#include <projectexplorer/environmentaspect.h> #include <projectexplorer/environmentaspect.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
@@ -93,10 +92,7 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio
return; return;
} }
Runnable runnable = rc->runnable(); m_runnable = rc->runnable();
if (!runnable.is<StandardRunnable>())
return;
m_runnable = runnable.as<StandardRunnable>();
m_displayName = rc->displayName(); m_displayName = rc->displayName();
m_project = rc->project(); m_project = rc->project();
@@ -193,15 +189,10 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
continue; continue;
} }
Runnable runnable = runConfig->runnable(); const Runnable runnable = runConfig->runnable();
if (!runnable.is<StandardRunnable>()) {
qCDebug(LOG) << " Skipped as not being a StandardRunnable";
continue;
}
StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
// not the best approach - but depending on the build system and whether the executables // not the best approach - but depending on the build system and whether the executables
// are going to get installed or not we have to soften the condition... // are going to get installed or not we have to soften the condition...
const QString &currentExecutable = ensureExeEnding(stdRunnable.executable); const QString currentExecutable = ensureExeEnding(runnable.executable);
const QString currentBST = runConfig->buildKey() + '|'; const QString currentBST = runConfig->buildKey() + '|';
qCDebug(LOG) << " CurrentExecutable" << currentExecutable; qCDebug(LOG) << " CurrentExecutable" << currentExecutable;
qCDebug(LOG) << " BST of RunConfig" << currentBST; qCDebug(LOG) << " BST of RunConfig" << currentBST;
@@ -213,7 +204,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
}))) { }))) {
qCDebug(LOG) << " Using this RunConfig."; qCDebug(LOG) << " Using this RunConfig.";
m_origRunConfig = runConfig; m_origRunConfig = runConfig;
m_runnable = stdRunnable; m_runnable = runnable;
m_runnable.executable = currentExecutable; m_runnable.executable = currentExecutable;
m_displayName = runConfig->displayName(); m_displayName = runConfig->displayName();
m_project = project; m_project = project;
@@ -234,16 +225,13 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
// we failed to find a valid runconfiguration - but we've got the executable already // we failed to find a valid runconfiguration - but we've got the executable already
if (auto rc = target->activeRunConfiguration()) { if (auto rc = target->activeRunConfiguration()) {
if (isLocal(rc)) { // FIXME for now only Desktop support if (isLocal(rc)) { // FIXME for now only Desktop support
Runnable runnable = rc->runnable(); const Runnable runnable = rc->runnable();
if (runnable.is<StandardRunnable>()) { m_runnable.environment = runnable.environment;
StandardRunnable stdRunnable = runnable.as<StandardRunnable>(); m_project = project;
m_runnable.environment = stdRunnable.environment; m_guessedConfiguration = true;
m_project = project; m_guessedFrom = rc->displayName();
m_guessedConfiguration = true; if (runMode == TestRunMode::Debug)
m_guessedFrom = rc->displayName(); m_runConfig = new TestRunConfiguration(rc->target(), this);
if (runMode == TestRunMode::Debug)
m_runConfig = new TestRunConfiguration(rc->target(), this);
}
} else { } else {
qCDebug(LOG) << "not using the fallback as the current active run configuration " qCDebug(LOG) << "not using the fallback as the current active run configuration "
"appears to be non-Desktop"; "appears to be non-Desktop";

View File

@@ -28,7 +28,7 @@
#include "autotestconstants.h" #include "autotestconstants.h"
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/runnables.h> #include <projectexplorer/runconfiguration.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <QFutureInterface> #include <QFutureInterface>
@@ -88,7 +88,7 @@ public:
QString runConfigDisplayName() const { return m_guessedConfiguration ? m_guessedFrom QString runConfigDisplayName() const { return m_guessedConfiguration ? m_guessedFrom
: m_displayName; } : m_displayName; }
ProjectExplorer::StandardRunnable runnable() const { return m_runnable; } ProjectExplorer::Runnable runnable() const { return m_runnable; }
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi, virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const = 0; QProcess *app) const = 0;
virtual QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const = 0; virtual QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const = 0;
@@ -105,7 +105,7 @@ private:
TestRunConfiguration *m_runConfig = nullptr; TestRunConfiguration *m_runConfig = nullptr;
QSet<QString> m_buildTargets; QSet<QString> m_buildTargets;
ProjectExplorer::RunConfiguration *m_origRunConfig = nullptr; ProjectExplorer::RunConfiguration *m_origRunConfig = nullptr;
ProjectExplorer::StandardRunnable m_runnable; ProjectExplorer::Runnable m_runnable;
}; };
class DebuggableTestConfiguration : public TestConfiguration class DebuggableTestConfiguration : public TestConfiguration

View File

@@ -32,7 +32,6 @@
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/devicesupport/devicemanager.h> #include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runnables.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <debugger/debuggerrunconfigurationaspect.h> #include <debugger/debuggerrunconfigurationaspect.h>
@@ -62,7 +61,7 @@ public:
ProjectExplorer::Runnable runnable() const override ProjectExplorer::Runnable runnable() const override
{ {
ProjectExplorer::StandardRunnable r; ProjectExplorer::Runnable r;
QTC_ASSERT(m_testConfig, return r); QTC_ASSERT(m_testConfig, return r);
r.executable = m_testConfig->executableFilePath(); r.executable = m_testConfig->executableFilePath();
r.commandLineArguments = m_testConfig->argumentsForTestRunner().join(' '); r.commandLineArguments = m_testConfig->argumentsForTestRunner().join(' ');

View File

@@ -336,9 +336,7 @@ static ProjectExplorer::RunConfiguration *getRunConfiguration(const QString &dia
RunConfiguration *runConfig = nullptr; RunConfiguration *runConfig = nullptr;
const QList<RunConfiguration *> runConfigurations const QList<RunConfiguration *> runConfigurations
= Utils::filtered(target->runConfigurations(), [] (const RunConfiguration *rc) { = Utils::filtered(target->runConfigurations(), [] (const RunConfiguration *rc) {
if (!rc->runnable().is<StandardRunnable>()) return !rc->runnable().executable.isEmpty();
return false;
return !rc->runnable().as<StandardRunnable>().executable.isEmpty();
}); });
if (runConfigurations.size() == 1) if (runConfigurations.size() == 1)
return runConfigurations.first(); return runConfigurations.first();
@@ -353,7 +351,7 @@ static ProjectExplorer::RunConfiguration *getRunConfiguration(const QString &dia
runConfig = Utils::findOr(runConfigurations, nullptr, [&dName, &exe] (const RunConfiguration *rc) { runConfig = Utils::findOr(runConfigurations, nullptr, [&dName, &exe] (const RunConfiguration *rc) {
if (rc->displayName() != dName) if (rc->displayName() != dName)
return false; return false;
return rc->runnable().as<StandardRunnable>().executable == exe; return rc->runnable().executable == exe;
}); });
} }
return runConfig; return runConfig;
@@ -489,7 +487,7 @@ void TestRunner::debugTests()
} }
QStringList omitted; QStringList omitted;
ProjectExplorer::StandardRunnable inferior = config->runnable(); ProjectExplorer::Runnable inferior = config->runnable();
inferior.executable = commandFilePath; inferior.executable = commandFilePath;
const QStringList args = config->argumentsForTestRunner(&omitted); const QStringList args = config->argumentsForTestRunner(&omitted);
@@ -515,8 +513,7 @@ void TestRunner::debugTests()
// We need a fake QFuture for the results. TODO: replace with QtConcurrent::run // We need a fake QFuture for the results. TODO: replace with QtConcurrent::run
QFutureInterface<TestResultPtr> *futureInterface QFutureInterface<TestResultPtr> *futureInterface
= new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running); = new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running);
QFuture<TestResultPtr> future(futureInterface); m_futureWatcher.setFuture(futureInterface->future());
m_futureWatcher.setFuture(future);
if (useOutputProcessor) { if (useOutputProcessor) {
TestOutputReader *outputreader = config->outputReader(*futureInterface, 0); TestOutputReader *outputreader = config->outputReader(*futureInterface, 0);
@@ -660,13 +657,11 @@ void RunConfigurationSelectionDialog::populate()
if (auto project = ProjectExplorer::SessionManager::startupProject()) { if (auto project = ProjectExplorer::SessionManager::startupProject()) {
if (auto target = project->activeTarget()) { if (auto target = project->activeTarget()) {
for (ProjectExplorer::RunConfiguration *rc : target->runConfigurations()) { for (ProjectExplorer::RunConfiguration *rc : target->runConfigurations()) {
if (rc->runnable().is<ProjectExplorer::StandardRunnable>()) { auto runnable = rc->runnable();
auto runnable = rc->runnable().as<ProjectExplorer::StandardRunnable>(); const QStringList rcDetails = { runnable.executable,
const QStringList rcDetails = { runnable.executable, runnable.commandLineArguments,
runnable.commandLineArguments, runnable.workingDirectory };
runnable.workingDirectory }; m_rcCombo->addItem(rc->displayName(), rcDetails);
m_rcCombo->addItem(rc->displayName(), rcDetails);
}
} }
} }
} }

View File

@@ -37,7 +37,6 @@
#include <projectexplorer/buildsteplist.h> #include <projectexplorer/buildsteplist.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runconfigurationaspects.h> #include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
@@ -70,7 +69,7 @@ BareMetalDebugSupport::BareMetalDebugSupport(RunControl *runControl)
} }
if (p->startupMode() == GdbServerProvider::StartupOnNetwork) { if (p->startupMode() == GdbServerProvider::StartupOnNetwork) {
StandardRunnable r; Runnable r;
r.executable = p->executable(); r.executable = p->executable();
// We need to wrap the command arguments depending on a host OS, // We need to wrap the command arguments depending on a host OS,
// as the bare metal's GDB servers are launched on a host, // as the bare metal's GDB servers are launched on a host,
@@ -123,7 +122,7 @@ void BareMetalDebugSupport::start()
setCommandsAfterConnect(commands); setCommandsAfterConnect(commands);
#endif #endif
StandardRunnable inferior; Runnable inferior;
inferior.executable = bin; inferior.executable = bin;
if (auto aspect = rc->extraAspect<ArgumentsAspect>()) if (auto aspect = rc->extraAspect<ArgumentsAspect>())
inferior.commandLineArguments = aspect->arguments(); inferior.commandLineArguments = aspect->arguments();

View File

@@ -26,14 +26,11 @@
#include "gdbserverproviderprocess.h" #include "gdbserverproviderprocess.h"
#include <projectexplorer/devicesupport/idevice.h> #include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/runnables.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QStringList>
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace BareMetal { namespace BareMetal {
@@ -62,10 +59,8 @@ GdbServerProviderProcess::GdbServerProviderProcess(
void GdbServerProviderProcess::start(const ProjectExplorer::Runnable &runnable) void GdbServerProviderProcess::start(const ProjectExplorer::Runnable &runnable)
{ {
QTC_ASSERT(runnable.is<StandardRunnable>(), return);
QTC_ASSERT(m_process->state() == QProcess::NotRunning, return); QTC_ASSERT(m_process->state() == QProcess::NotRunning, return);
auto r = runnable.as<StandardRunnable>(); m_process->setCommand(runnable.executable, runnable.commandLineArguments);
m_process->setCommand(r.executable, r.commandLineArguments);
m_process->start(); m_process->start();
} }

View File

@@ -27,7 +27,6 @@
#include <projectexplorer/devicesupport/deviceprocess.h> #include <projectexplorer/devicesupport/deviceprocess.h>
namespace ProjectExplorer { class Runnable; }
namespace Utils { class QtcProcess; } namespace Utils { class QtcProcess; }
namespace BareMetal { namespace BareMetal {

View File

@@ -32,16 +32,31 @@
#include <utils/tooltip/tooltip.h> #include <utils/tooltip/tooltip.h>
#include <QApplication> #include <QApplication>
#include <QDesktopServices>
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QFileInfo> #include <QFileInfo>
#include <QHash> #include <QHash>
#include <QLabel> #include <QLabel>
#include <QUrl>
using namespace ClangCodeModel; using namespace ClangCodeModel;
using Internal::ClangDiagnosticWidget; using Internal::ClangDiagnosticWidget;
namespace { namespace {
// CLANG-UPGRADE-CHECK: Checks/update URLs.
//
// For tidy, upgrade the version in the URL. Note that we cannot use the macro
// CLANG_VERSION here because it might denote a version that was not yet
// released (e.g. 6.0.1, but only 6.0.0 was released).
//
// For clazy, once it gets dedicated documentation pages for released versions,
// use them instead of pointing to master, as checks might vanish.
const char TIDY_DOCUMENTATION_URL_TEMPLATE[]
= "https://releases.llvm.org/6.0.0/tools/clang/tools/extra/docs/clang-tidy/checks/%1.html";
const char CLAZY_DOCUMENTATION_URL_TEMPLATE[]
= "https://github.com/KDE/clazy/blob/master/docs/checks/README-%1.md";
const char LINK_ACTION_GOTO_LOCATION[] = "#gotoLocation"; const char LINK_ACTION_GOTO_LOCATION[] = "#gotoLocation";
const char LINK_ACTION_APPLY_FIX[] = "#applyFix"; const char LINK_ACTION_APPLY_FIX[] = "#applyFix";
@@ -130,12 +145,15 @@ private:
QObject::connect(label, &QLabel::linkActivated, [table, hideToolTipAfterLinkActivation] QObject::connect(label, &QLabel::linkActivated, [table, hideToolTipAfterLinkActivation]
(const QString &action) { (const QString &action) {
const ClangBackEnd::DiagnosticContainer diagnostic = table.value(action); const ClangBackEnd::DiagnosticContainer diagnostic = table.value(action);
QTC_ASSERT(diagnostic != ClangBackEnd::DiagnosticContainer(), return);
if (action.startsWith(LINK_ACTION_APPLY_FIX)) if (diagnostic == ClangBackEnd::DiagnosticContainer())
QDesktopServices::openUrl(QUrl(action));
else if (action.startsWith(LINK_ACTION_GOTO_LOCATION))
openEditorAt(diagnostic);
else if (action.startsWith(LINK_ACTION_APPLY_FIX))
applyFixit(diagnostic); applyFixit(diagnostic);
else else
openEditorAt(diagnostic); QTC_CHECK(!"Link target cannot be handled.");
if (hideToolTipAfterLinkActivation) if (hideToolTipAfterLinkActivation)
Utils::ToolTip::hideImmediately(); Utils::ToolTip::hideImmediately();
@@ -157,6 +175,8 @@ private:
return text; return text;
} }
static bool isClazyOption(const QString &option) { return option.startsWith("-Wclazy"); }
class DiagnosticTextInfo class DiagnosticTextInfo
{ {
public: public:
@@ -188,7 +208,7 @@ private:
return QString(); return QString();
const int index = m_squareBracketStartIndex + 1; const int index = m_squareBracketStartIndex + 1;
if (m_text.midRef(index).startsWith("-Wclazy")) if (isClazyOption(m_text.mid(index)))
return QCoreApplication::translate("ClangDiagnosticWidget", "Clazy Issue"); return QCoreApplication::translate("ClangDiagnosticWidget", "Clazy Issue");
else else
return QCoreApplication::translate("ClangDiagnosticWidget", "Clang-Tidy Issue"); return QCoreApplication::translate("ClangDiagnosticWidget", "Clang-Tidy Issue");
@@ -212,8 +232,8 @@ private:
static ClangBackEnd::DiagnosticContainer supplementedDiagnostic( static ClangBackEnd::DiagnosticContainer supplementedDiagnostic(
const ClangBackEnd::DiagnosticContainer &diagnostic) const ClangBackEnd::DiagnosticContainer &diagnostic)
{ {
if (!diagnostic.category.isEmpty() && !diagnostic.enableOption.isEmpty()) if (!diagnostic.category.isEmpty())
return diagnostic; // OK, diagnostics from clang have this set. return diagnostic; // OK, diagnostics from clang itself have this set.
ClangBackEnd::DiagnosticContainer supplementedDiagnostic = diagnostic; ClangBackEnd::DiagnosticContainer supplementedDiagnostic = diagnostic;
@@ -245,6 +265,39 @@ private:
return text; return text;
} }
static QString documentationUrlForOption(const Utf8String &optionAsUtf8String)
{
if (optionAsUtf8String.isEmpty())
return QString();
QString option = optionAsUtf8String.toString();
// Clazy
if (isClazyOption(option)) {
option = optionAsUtf8String.mid(8); // Remove "-Wclazy-" prefix.
return QString::fromUtf8(CLAZY_DOCUMENTATION_URL_TEMPLATE).arg(option);
}
// Clang itself
if (option.startsWith("-W"))
return QString();
// Clang-Tidy
return QString::fromUtf8(TIDY_DOCUMENTATION_URL_TEMPLATE).arg(option);
}
static QString maybeClickableOption(const Utf8String &option)
{
if (option.isEmpty())
return option;
const QString link = documentationUrlForOption(option);
if (link.isEmpty())
return QString();
return wrapInLink(option.toString(), link);
}
static QString diagnosticCategoryAndEnableOptionRow( static QString diagnosticCategoryAndEnableOptionRow(
const ClangBackEnd::DiagnosticContainer &diagnostic) const ClangBackEnd::DiagnosticContainer &diagnostic)
{ {
@@ -253,7 +306,7 @@ private:
" <td align='left'><b>%1</b></td>" " <td align='left'><b>%1</b></td>"
" <td align='right'>&nbsp;<font color='gray'>%2</font></td>" " <td align='right'>&nbsp;<font color='gray'>%2</font></td>"
" </tr>") " </tr>")
.arg(diagnostic.category, diagnostic.enableOption); .arg(diagnostic.category, maybeClickableOption(diagnostic.enableOption));
return text; return text;
} }

View File

@@ -556,11 +556,7 @@ private:
void addGlobalDiagnosticOptions() void addGlobalDiagnosticOptions()
{ {
m_options.append({ m_options += CppTools::ClangDiagnosticConfigsModel::globalDiagnosticOptions();
// Avoid undesired warnings from e.g. Q_OBJECT
QStringLiteral("-Wno-unknown-pragmas"),
QStringLiteral("-Wno-unknown-warning-option")
});
} }
void addGlobalOptions() void addGlobalOptions()

View File

@@ -0,0 +1,148 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "clangfixitsrefactoringchanges.h"
#include <coreplugin/editormanager/editormanager.h>
#include <QDebug>
#include <QFileInfo>
#include <QLoggingCategory>
#include <QTextBlock>
#include <QTextCursor>
#include <utils/qtcassert.h>
Q_LOGGING_CATEGORY(fixitsLog, "qtc.clangtools.fixits");
using namespace Utils;
namespace ClangTools {
namespace Internal {
int FixitsRefactoringFile::position(unsigned line, unsigned column) const
{
QTC_ASSERT(line != 0, return -1);
QTC_ASSERT(column != 0, return -1);
return document()->findBlockByNumber(line - 1).position() + column - 1;
}
static QDebug operator<<(QDebug debug, const ReplacementOperation &op)
{
debug.nospace() << "ReplacementOperation("
<< op.pos << ", "
<< op.length << ", "
<< op.text << ", "
<< op.apply
<< ")"
;
return debug;
}
bool FixitsRefactoringFile::apply()
{
qCDebug(fixitsLog) << "Applying fixits for" << m_filePath;
if (m_replacementOperations.isEmpty())
return false; // Error nothing to apply TODO: Is this correct to return?
QTC_ASSERT(!m_filePath.isEmpty(), return false);
// Check for permissions
if (!QFileInfo(m_filePath).isWritable())
return false; // Error file not writable
// Apply changes
QTextDocument *doc = document();
QTextCursor cursor(doc);
for (int i=0; i < m_replacementOperations.size(); ++i) {
ReplacementOperation &op = *m_replacementOperations[i];
if (op.apply) {
qCDebug(fixitsLog) << " " << i << "Applying" << op;
// Shift subsequent operations that are affected
shiftAffectedReplacements(op, i + 1);
// Apply
cursor.setPosition(op.pos);
cursor.setPosition(op.pos + op.length, QTextCursor::KeepAnchor);
cursor.insertText(op.text);
}
}
// Write file
if (!m_textFileFormat.codec)
return false; // Error reading file
QString error;
if (!m_textFileFormat.writeFile(m_filePath, doc->toPlainText(), &error)) {
qCDebug(fixitsLog) << "ERROR: Could not write file" << m_filePath << ":" << error;
return false; // Error writing file
}
return true;
}
QTextDocument *FixitsRefactoringFile::document() const
{
if (!m_document) {
QString fileContents;
if (!m_filePath.isEmpty()) {
QString error;
QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec();
TextFileFormat::ReadResult result = TextFileFormat::readFile(
m_filePath, defaultCodec,
&fileContents, &m_textFileFormat,
&error);
if (result != TextFileFormat::ReadSuccess) {
qCDebug(fixitsLog) << "ERROR: Could not read " << m_filePath << ":" << error;
m_textFileFormat.codec = nullptr;
}
}
// always make a QTextDocument to avoid excessive null checks
m_document = new QTextDocument(fileContents);
}
return m_document;
}
void FixitsRefactoringFile::shiftAffectedReplacements(const ReplacementOperation &op, int startIndex)
{
for (int i = startIndex; i < m_replacementOperations.size(); ++i) {
ReplacementOperation &current = *m_replacementOperations[i];
ReplacementOperation before = current;
if (op.pos <= current.pos)
current.pos += op.text.size();
if (op.pos < current.pos)
current.pos -= op.length;
qCDebug(fixitsLog) << " shift:" << i << before << " ====> " << current;
}
}
} // namespace Internal
} // namespace ClangTools

View File

@@ -0,0 +1,73 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <utils/changeset.h>
#include <utils/textfileformat.h>
#include <QString>
#include <QTextDocument>
#include <QVector>
namespace ClangTools {
namespace Internal {
class ReplacementOperation
{
public:
int pos = -1;
int length = -1;
QString text;
bool apply = false;
};
using ReplacementOperations = QVector<ReplacementOperation *>;
/// Simplified version of TextEditor::RefactoringFile that allows
/// to operate on not owned ReplamentOperations
class FixitsRefactoringFile
{
public:
FixitsRefactoringFile() = default;
FixitsRefactoringFile(const QString &filePath) : m_filePath(filePath) {}
bool isValid() const { return !m_filePath.isEmpty(); }
int position(unsigned line, unsigned column) const;
void setReplacements(const ReplacementOperations &ops) { m_replacementOperations = ops; }
bool apply();
private:
QTextDocument *document() const;
void shiftAffectedReplacements(const ReplacementOperation &op, int startIndex);
QString m_filePath;
mutable Utils::TextFileFormat m_textFileFormat;
mutable QTextDocument *m_document = nullptr;
ReplacementOperations m_replacementOperations; // Not owned.
};
} // namespace Internal
} // namespace ClangTools

View File

@@ -78,7 +78,8 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis
arguments << QString("-fsyntax-only") arguments << QString("-fsyntax-only")
<< QString("-serialize-diagnostics") << QString("-serialize-diagnostics")
<< QString(m_logFile); << QString(m_logFile)
<< ClangDiagnosticConfigsModel::globalDiagnosticOptions();
const ClangDiagnosticConfig::TidyMode tidyMode = m_diagnosticConfig.clangTidyMode(); const ClangDiagnosticConfig::TidyMode tidyMode = m_diagnosticConfig.clangTidyMode();
if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) { if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) {

View File

@@ -25,6 +25,7 @@
#include "clangtidyclazytool.h" #include "clangtidyclazytool.h"
#include "clangfixitsrefactoringchanges.h"
#include "clangselectablefilesdialog.h" #include "clangselectablefilesdialog.h"
#include "clangtoolsconstants.h" #include "clangtoolsconstants.h"
#include "clangtoolsdiagnosticmodel.h" #include "clangtoolsdiagnosticmodel.h"
@@ -50,8 +51,6 @@
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <texteditor/refactoringchanges.h>
#include <utils/fancylineedit.h> #include <utils/fancylineedit.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
@@ -69,42 +68,130 @@ namespace Internal {
static ClangTidyClazyTool *s_instance; static ClangTidyClazyTool *s_instance;
static void applyFixits(const QVector<Diagnostic> &diagnostics) class ApplyFixIts
{ {
TextEditor::RefactoringChanges changes; public:
QMap<QString, TextEditor::RefactoringFilePtr> refactoringFiles; class RefactoringFileInfo
{
public:
bool isValid() const { return file.isValid(); }
// Create refactoring files and changes FixitsRefactoringFile file;
for (const Diagnostic &diagnostic : diagnostics) { QVector<DiagnosticItem *> diagnosticItems;
const auto filePath = diagnostic.location.filePath; bool hasScheduledFixits = false;
QTC_ASSERT(!filePath.isEmpty(), continue); };
// Get or create refactoring file ApplyFixIts(const QVector<DiagnosticItem *> &diagnosticItems)
TextEditor::RefactoringFilePtr refactoringFile = refactoringFiles.value(filePath); {
if (!refactoringFile) { for (DiagnosticItem *diagnosticItem : diagnosticItems) {
refactoringFile = changes.file(filePath); const QString &filePath = diagnosticItem->diagnostic().location.filePath;
refactoringFiles.insert(filePath, refactoringFile); QTC_ASSERT(!filePath.isEmpty(), continue);
// Get or create refactoring file
RefactoringFileInfo &fileInfo = m_refactoringFileInfos[filePath];
if (!fileInfo.isValid())
fileInfo.file = FixitsRefactoringFile(filePath);
// Append item
fileInfo.diagnosticItems += diagnosticItem;
if (diagnosticItem->fixItStatus() == FixitStatus::Scheduled)
fileInfo.hasScheduledFixits = true;
} }
// Append changes
ChangeSet cs = refactoringFile->changeSet();
for (const ExplainingStep &step : diagnostic.explainingSteps) {
if (step.isFixIt) {
const Debugger::DiagnosticLocation start = step.ranges.first();
const Debugger::DiagnosticLocation end = step.ranges.last();
cs.replace(refactoringFile->position(start.line, start.column),
refactoringFile->position(end.line, end.column), step.message);
}
}
refactoringFile->setChangeSet(cs);
} }
// Apply refactoring file changes static void addFixitOperations(DiagnosticItem *diagnosticItem,
for (TextEditor::RefactoringFilePtr refactoringFile : refactoringFiles.values()) const FixitsRefactoringFile &file, bool apply)
refactoringFile->apply(); {
} // Did we already created the fixit operations?
ReplacementOperations currentOps = diagnosticItem->fixitOperations();
if (!currentOps.isEmpty()) {
for (ReplacementOperation *op : currentOps)
op->apply = apply;
return;
}
// Collect/construct the fixit operations
ReplacementOperations replacements;
for (const ExplainingStep &step : diagnosticItem->diagnostic().explainingSteps) {
if (!step.isFixIt)
continue;
const Debugger::DiagnosticLocation start = step.ranges.first();
const Debugger::DiagnosticLocation end = step.ranges.last();
const int startPos = file.position(start.line, start.column);
const int endPos = file.position(end.line, end.column);
auto op = new ReplacementOperation;
op->pos = startPos;
op->length = endPos - startPos;
op->text = step.message;
op->apply = apply;
replacements += op;
}
diagnosticItem->setFixitOperations(replacements);
}
void apply()
{
for (auto it = m_refactoringFileInfos.begin(); it != m_refactoringFileInfos.end(); ++it) {
RefactoringFileInfo &fileInfo = it.value();
QVector<DiagnosticItem *> itemsScheduledOrSchedulable;
QVector<DiagnosticItem *> itemsScheduled;
QVector<DiagnosticItem *> itemsSchedulable;
// Construct refactoring operations
for (DiagnosticItem *diagnosticItem : fileInfo.diagnosticItems) {
const FixitStatus fixItStatus = diagnosticItem->fixItStatus();
const bool isScheduled = fixItStatus == FixitStatus::Scheduled;
const bool isSchedulable = fileInfo.hasScheduledFixits
&& fixItStatus == FixitStatus::NotScheduled;
if (isScheduled || isSchedulable) {
addFixitOperations(diagnosticItem, fileInfo.file, isScheduled);
itemsScheduledOrSchedulable += diagnosticItem;
if (isScheduled)
itemsScheduled += diagnosticItem;
else
itemsSchedulable += diagnosticItem;
}
}
// Collect replacements
ReplacementOperations ops;
for (DiagnosticItem *item : itemsScheduledOrSchedulable)
ops += item->fixitOperations();
// Apply file
QVector<DiagnosticItem *> itemsApplied;
QVector<DiagnosticItem *> itemsFailedToApply;
QVector<DiagnosticItem *> itemsInvalidated;
fileInfo.file.setReplacements(ops);
if (fileInfo.file.apply()) {
itemsApplied = itemsScheduled;
} else {
itemsFailedToApply = itemsScheduled;
itemsInvalidated = itemsSchedulable;
}
// Update DiagnosticItem state
for (DiagnosticItem *diagnosticItem : itemsScheduled)
diagnosticItem->setFixItStatus(FixitStatus::Applied);
for (DiagnosticItem *diagnosticItem : itemsFailedToApply)
diagnosticItem->setFixItStatus(FixitStatus::FailedToApply);
for (DiagnosticItem *diagnosticItem : itemsInvalidated)
diagnosticItem->setFixItStatus(FixitStatus::Invalidated);
}
}
private:
QMap<QString, RefactoringFileInfo> m_refactoringFileInfos;
};
ClangTidyClazyTool::ClangTidyClazyTool() ClangTidyClazyTool::ClangTidyClazyTool()
: ClangTool("Clang-Tidy and Clazy") : ClangTool("Clang-Tidy and Clazy")
@@ -166,16 +253,12 @@ ClangTidyClazyTool::ClangTidyClazyTool()
&ClangToolsDiagnosticModel::fixItsToApplyCountChanged, &ClangToolsDiagnosticModel::fixItsToApplyCountChanged,
[this](int c) { m_applyFixitsButton->setEnabled(c); }); [this](int c) { m_applyFixitsButton->setEnabled(c); });
connect(m_applyFixitsButton, &QToolButton::clicked, [this]() { connect(m_applyFixitsButton, &QToolButton::clicked, [this]() {
QVector<Diagnostic> diagnosticsWithFixits; QVector<DiagnosticItem *> diagnosticItems;
m_diagnosticModel->rootItem()->forChildrenAtLevel(1, [&](TreeItem *item){
diagnosticItems += static_cast<DiagnosticItem *>(item);
});
const int count = m_diagnosticModel->rootItem()->childCount(); ApplyFixIts(diagnosticItems).apply();
for (int i = 0; i < count; ++i) {
auto *item = static_cast<DiagnosticItem *>(m_diagnosticModel->rootItem()->childAt(i));
if (item->applyFixits())
diagnosticsWithFixits += item->diagnostic();
}
applyFixits(diagnosticsWithFixits);
}); });
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER); ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);

View File

@@ -9,6 +9,7 @@ LIBS += $$LIBCLANG_LIBS
INCLUDEPATH += $$LLVM_INCLUDEPATH INCLUDEPATH += $$LLVM_INCLUDEPATH
SOURCES += \ SOURCES += \
clangfixitsrefactoringchanges.cpp \
clangselectablefilesdialog.cpp \ clangselectablefilesdialog.cpp \
clangtoolsdiagnosticview.cpp \ clangtoolsdiagnosticview.cpp \
clangtoolsprojectsettingswidget.cpp \ clangtoolsprojectsettingswidget.cpp \
@@ -29,6 +30,7 @@ SOURCES += \
HEADERS += \ HEADERS += \
clangfileinfo.h \ clangfileinfo.h \
clangfixitsrefactoringchanges.h \
clangselectablefilesdialog.h \ clangselectablefilesdialog.h \
clangtoolsdiagnosticview.h \ clangtoolsdiagnosticview.h \
clangtoolsprojectsettingswidget.h \ clangtoolsprojectsettingswidget.h \

View File

@@ -43,6 +43,8 @@ QtcPlugin {
files: [ files: [
"clangfileinfo.h", "clangfileinfo.h",
"clangfixitsrefactoringchanges.cpp",
"clangfixitsrefactoringchanges.h",
"clangselectablefilesdialog.cpp", "clangselectablefilesdialog.cpp",
"clangselectablefilesdialog.h", "clangselectablefilesdialog.h",
"clangselectablefilesdialog.ui", "clangselectablefilesdialog.ui",

View File

@@ -55,18 +55,21 @@ private:
ClangToolsDiagnosticModel::ClangToolsDiagnosticModel(QObject *parent) ClangToolsDiagnosticModel::ClangToolsDiagnosticModel(QObject *parent)
: Utils::TreeModel<>(parent) : Utils::TreeModel<>(parent)
{ {
setHeader({tr("Issue"), tr("Location"), tr("Fixits")}); setHeader({tr("Issue"), tr("Location"), tr("Fixit Status")});
} }
void ClangToolsDiagnosticModel::addDiagnostics(const QList<Diagnostic> &diagnostics) void ClangToolsDiagnosticModel::addDiagnostics(const QList<Diagnostic> &diagnostics)
{ {
const auto onFixItChanged = [this](bool checked){ const auto onFixitStatusChanged = [this](FixitStatus newStatus) {
m_fixItsToApplyCount += checked ? +1 : -1; if (newStatus == FixitStatus::Scheduled)
++m_fixItsToApplyCount;
else
--m_fixItsToApplyCount;
emit fixItsToApplyCountChanged(m_fixItsToApplyCount); emit fixItsToApplyCountChanged(m_fixItsToApplyCount);
}; };
for (const Diagnostic &d : diagnostics) for (const Diagnostic &d : diagnostics)
rootItem()->appendChild(new DiagnosticItem(d, onFixItChanged)); rootItem()->appendChild(new DiagnosticItem(d, onFixitStatusChanged));
} }
QList<Diagnostic> ClangToolsDiagnosticModel::diagnostics() const QList<Diagnostic> ClangToolsDiagnosticModel::diagnostics() const
@@ -94,6 +97,12 @@ static QString createDiagnosticToolTipString(const Diagnostic &diagnostic)
diagnostic.type.toHtmlEscaped()); diagnostic.type.toHtmlEscaped());
} }
if (!diagnostic.description.isEmpty()) {
lines << qMakePair(
QCoreApplication::translate("ClangTools::Diagnostic", "Description:"),
diagnostic.description.toHtmlEscaped());
}
if (!diagnostic.issueContext.isEmpty() && !diagnostic.issueContextKind.isEmpty()) { if (!diagnostic.issueContext.isEmpty() && !diagnostic.issueContextKind.isEmpty()) {
lines << qMakePair( lines << qMakePair(
QCoreApplication::translate("ClangTools::Diagnostic", "Context:"), QCoreApplication::translate("ClangTools::Diagnostic", "Context:"),
@@ -203,10 +212,13 @@ static QString fullText(const Diagnostic &diagnostic)
} }
DiagnosticItem::DiagnosticItem(const Diagnostic &diag, const OnCheckedFixit &onCheckedFixit) DiagnosticItem::DiagnosticItem(const Diagnostic &diag, const OnFixitStatusChanged &onFixitStatusChanged)
: m_diagnostic(diag) : m_diagnostic(diag)
, m_onCheckedFixit(onCheckedFixit) , m_onFixitStatusChanged(onFixitStatusChanged)
{ {
if (diag.hasFixits)
m_fixitStatus = FixitStatus::NotScheduled;
// Don't show explaining steps if they add no information. // Don't show explaining steps if they add no information.
if (diag.explainingSteps.count() == 1) { if (diag.explainingSteps.count() == 1) {
const ExplainingStep &step = diag.explainingSteps.first(); const ExplainingStep &step = diag.explainingSteps.first();
@@ -218,14 +230,25 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag, const OnCheckedFixit &onC
appendChild(new ExplainingStepItem(s)); appendChild(new ExplainingStepItem(s));
} }
DiagnosticItem::~DiagnosticItem()
{
setFixitOperations(ReplacementOperations());
}
Qt::ItemFlags DiagnosticItem::flags(int column) const Qt::ItemFlags DiagnosticItem::flags(int column) const
{ {
const Qt::ItemFlags itemFlags = TreeItem::flags(column); const Qt::ItemFlags itemFlags = TreeItem::flags(column);
if (column == DiagnosticView::FixItColumn) { if (column == DiagnosticView::FixItColumn) {
if (m_diagnostic.hasFixits) switch (m_fixitStatus) {
return itemFlags | Qt::ItemIsUserCheckable; case FixitStatus::NotAvailable:
else case FixitStatus::Applied:
case FixitStatus::FailedToApply:
case FixitStatus::Invalidated:
return itemFlags & ~Qt::ItemIsEnabled; return itemFlags & ~Qt::ItemIsEnabled;
case FixitStatus::Scheduled:
case FixitStatus::NotScheduled:
return itemFlags | Qt::ItemIsUserCheckable;
}
} }
return itemFlags; return itemFlags;
@@ -250,8 +273,33 @@ QVariant DiagnosticItem::data(int column, int role) const
return Debugger::DetailedErrorView::locationData(role, m_diagnostic.location); return Debugger::DetailedErrorView::locationData(role, m_diagnostic.location);
if (column == DiagnosticView::FixItColumn) { if (column == DiagnosticView::FixItColumn) {
if (role == Qt::CheckStateRole) if (role == Qt::CheckStateRole) {
return m_applyFixits ? Qt::Checked : Qt::Unchecked; switch (m_fixitStatus) {
case FixitStatus::NotAvailable:
case FixitStatus::NotScheduled:
case FixitStatus::Invalidated:
case FixitStatus::Applied:
case FixitStatus::FailedToApply:
return Qt::Unchecked;
case FixitStatus::Scheduled:
return Qt::Checked;
}
} else if (role == Qt::DisplayRole) {
switch (m_fixitStatus) {
case FixitStatus::NotAvailable:
return ClangToolsDiagnosticModel::tr("No Fixits");
case FixitStatus::NotScheduled:
return ClangToolsDiagnosticModel::tr("Not Scheduled");
case FixitStatus::Invalidated:
return ClangToolsDiagnosticModel::tr("Invalidated");
case FixitStatus::Scheduled:
return ClangToolsDiagnosticModel::tr("Scheduled");
case FixitStatus::FailedToApply:
return ClangToolsDiagnosticModel::tr("Failed to Apply");
case FixitStatus::Applied:
return ClangToolsDiagnosticModel::tr("Applied");
}
}
return QVariant(); return QVariant();
} }
@@ -275,16 +323,32 @@ QVariant DiagnosticItem::data(int column, int role) const
bool DiagnosticItem::setData(int column, const QVariant &data, int role) bool DiagnosticItem::setData(int column, const QVariant &data, int role)
{ {
if (column == DiagnosticView::FixItColumn && role == Qt::CheckStateRole) { if (column == DiagnosticView::FixItColumn && role == Qt::CheckStateRole) {
m_applyFixits = data.value<Qt::CheckState>() == Qt::Checked ? true : false; const FixitStatus newStatus = data.value<Qt::CheckState>() == Qt::Checked
update(); ? FixitStatus::Scheduled
if (m_onCheckedFixit) : FixitStatus::NotScheduled;
m_onCheckedFixit(m_applyFixits);
setFixItStatus(newStatus);
return true; return true;
} }
return Utils::TreeItem::setData(column, data, role); return Utils::TreeItem::setData(column, data, role);
} }
void DiagnosticItem::setFixItStatus(const FixitStatus &status)
{
const FixitStatus oldStatus = m_fixitStatus;
m_fixitStatus = status;
update();
if (m_onFixitStatusChanged && status != oldStatus)
m_onFixitStatusChanged(status);
}
void DiagnosticItem::setFixitOperations(const ReplacementOperations &replacements)
{
qDeleteAll(m_fixitOperations);
m_fixitOperations = replacements;
}
ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step) : m_step(step) ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step) : m_step(step)
{ {
} }

View File

@@ -25,6 +25,7 @@
#pragma once #pragma once
#include "clangfixitsrefactoringchanges.h"
#include "clangtoolsdiagnostic.h" #include "clangtoolsdiagnostic.h"
#include "clangtoolsprojectsettings.h" #include "clangtoolsprojectsettings.h"
@@ -42,14 +43,29 @@ namespace ProjectExplorer { class Project; }
namespace ClangTools { namespace ClangTools {
namespace Internal { namespace Internal {
enum class FixitStatus {
NotAvailable,
NotScheduled,
Scheduled,
Applied,
FailedToApply,
Invalidated,
};
class DiagnosticItem : public Utils::TreeItem class DiagnosticItem : public Utils::TreeItem
{ {
public: public:
using OnCheckedFixit = std::function<void(bool)>; using OnFixitStatusChanged = std::function<void(FixitStatus newStatus)>;
DiagnosticItem(const Diagnostic &diag, const OnCheckedFixit &onCheckedFixit); DiagnosticItem(const Diagnostic &diag, const OnFixitStatusChanged &onFixitStatusChanged);
~DiagnosticItem() override;
Diagnostic diagnostic() const { return m_diagnostic; } Diagnostic diagnostic() const { return m_diagnostic; }
bool applyFixits() const { return m_applyFixits; }
FixitStatus fixItStatus() const { return m_fixitStatus; }
void setFixItStatus(const FixitStatus &status);
ReplacementOperations &fixitOperations() { return m_fixitOperations; }
void setFixitOperations(const ReplacementOperations &replacements);
private: private:
Qt::ItemFlags flags(int column) const override; Qt::ItemFlags flags(int column) const override;
@@ -58,8 +74,10 @@ private:
private: private:
const Diagnostic m_diagnostic; const Diagnostic m_diagnostic;
bool m_applyFixits = false; OnFixitStatusChanged m_onFixitStatusChanged;
OnCheckedFixit m_onCheckedFixit;
ReplacementOperations m_fixitOperations;
FixitStatus m_fixitStatus = FixitStatus::NotAvailable;
}; };
class ClangToolsDiagnosticModel : public Utils::TreeModel<> class ClangToolsDiagnosticModel : public Utils::TreeModel<>

View File

@@ -34,6 +34,7 @@
#include <QAction> #include <QAction>
#include <QDebug> #include <QDebug>
#include <QHeaderView>
using namespace Debugger; using namespace Debugger;
@@ -103,5 +104,12 @@ bool DiagnosticView::eventFilter(QObject *watched, QEvent *event)
} }
} }
void DiagnosticView::setModel(QAbstractItemModel *model)
{
Debugger::DetailedErrorView::setModel(model);
header()->setStretchLastSection(false);
header()->setSectionResizeMode(0, QHeaderView::Stretch);
}
} // namespace Internal } // namespace Internal
} // namespace ClangTools } // namespace ClangTools

View File

@@ -46,6 +46,7 @@ private:
QList<QAction *> customActions() const; QList<QAction *> customActions() const;
bool eventFilter(QObject *watched, QEvent *event) override; bool eventFilter(QObject *watched, QEvent *event) override;
void setModel(QAbstractItemModel *model) override;
QAction *m_suppressAction; QAction *m_suppressAction;
}; };

View File

@@ -81,8 +81,8 @@ static CppTools::ClangDiagnosticConfig createTidyClazyConfig()
config.setDisplayName("Test"); config.setDisplayName("Test");
config.setIsReadOnly(true); config.setIsReadOnly(true);
config.setClangOptions(QStringList{QStringLiteral("-Wno-everything")}); config.setClangOptions(QStringList{QStringLiteral("-Wno-everything")});
config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksString); config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksPrefixList);
config.setClangTidyChecksString("-*,modernize-*, misc-*"); config.setClangTidyChecks("modernize-*, misc-*");
config.setClazyChecks("level2"); config.setClazyChecks("level2");
return config; return config;
} }

View File

@@ -356,8 +356,6 @@ QList<CMakeBuildTarget> BuildDirManager::takeBuildTargets() const
CMakeConfig BuildDirManager::takeCMakeConfiguration() const CMakeConfig BuildDirManager::takeCMakeConfiguration() const
{ {
QTC_ASSERT(!m_isHandlingError, return {});
if (!m_reader) if (!m_reader)
return CMakeConfig(); return CMakeConfig();

View File

@@ -494,7 +494,7 @@ CMakeConfig CMakeConfigurationKitInformation::configuration(const Kit *k)
if (!k) if (!k)
return CMakeConfig(); return CMakeConfig();
const QStringList tmp = k->value(CONFIGURATION_ID).toStringList(); const QStringList tmp = k->value(CONFIGURATION_ID).toStringList();
return Utils::transform(tmp, [](const QString &s) { return CMakeConfigItem::fromString(s); }); return Utils::transform(tmp, &CMakeConfigItem::fromString);
} }
void CMakeConfigurationKitInformation::setConfiguration(Kit *k, const CMakeConfig &config) void CMakeConfigurationKitInformation::setConfiguration(Kit *k, const CMakeConfig &config)

View File

@@ -106,6 +106,7 @@ CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEM
CMakeBuildConfiguration *bc = activeBc(this); CMakeBuildConfiguration *bc = activeBc(this);
if (bc && bc == m_buildDirManager.buildConfiguration()) { if (bc && bc == m_buildDirManager.buildConfiguration()) {
bc->setError(msg); bc->setError(msg);
bc->setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration());
handleParsingError(bc); handleParsingError(bc);
} }
}); });
@@ -475,7 +476,7 @@ void CMakeProject::startParsing(int reparseParameters)
QStringList CMakeProject::buildTargetTitles() const QStringList CMakeProject::buildTargetTitles() const
{ {
return transform(buildTargets(), [](const CMakeBuildTarget &ct) { return ct.title; }); return transform(buildTargets(), &CMakeBuildTarget::title);
} }
Project::RestoreResult CMakeProject::fromMap(const QVariantMap &map, QString *errorMessage) Project::RestoreResult CMakeProject::fromMap(const QVariantMap &map, QString *errorMessage)
@@ -670,7 +671,7 @@ void CMakeProject::createGeneratedCodeModelSupport()
ExtraCompilerFactory::extraCompilerFactories(); ExtraCompilerFactory::extraCompilerFactories();
const QSet<QString> fileExtensions const QSet<QString> fileExtensions
= Utils::transform<QSet>(factories, [](const ExtraCompilerFactory *f) { return f->sourceTag(); }); = Utils::transform<QSet>(factories, &ExtraCompilerFactory::sourceTag);
// Find all files generated by any of the extra compilers, in a rather crude way. // Find all files generated by any of the extra compilers, in a rather crude way.
const FileNameList fileList = files([&fileExtensions](const Node *n) { const FileNameList fileList = files([&fileExtensions](const Node *n) {

View File

@@ -25,7 +25,7 @@
#pragma once #pragma once
#include <projectexplorer/runnables.h> #include <projectexplorer/runconfiguration.h>
namespace CMakeProjectManager { namespace CMakeProjectManager {
namespace Internal { namespace Internal {

View File

@@ -427,7 +427,7 @@ void CMakeTool::fetchVersionFromVersionOutput() const
if (response.result != Utils::SynchronousProcessResponse::Finished) if (response.result != Utils::SynchronousProcessResponse::Finished)
return; return;
QRegularExpression versionLine("^cmake version ((\\d+).(\\d+).(\\d+).*)$"); QRegularExpression versionLine("^cmake.* version ((\\d+).(\\d+).(\\d+).*)$");
const QString responseText = response.stdOut(); const QString responseText = response.stdOut();
for (const QStringRef &line : responseText.splitRef(QLatin1Char('\n'))) { for (const QStringRef &line : responseText.splitRef(QLatin1Char('\n'))) {
QRegularExpressionMatch match = versionLine.match(line); QRegularExpressionMatch match = versionLine.match(line);

View File

@@ -199,6 +199,7 @@ void ServerModeReader::parse(bool forceConfiguration)
tr("Configuring \"%1\"").arg(m_parameters.projectName), tr("Configuring \"%1\"").arg(m_parameters.projectName),
"CMake.Configure"); "CMake.Configure");
m_delayedErrorMessage.clear();
m_cmakeServer->sendRequest(CONFIGURE_TYPE, extra); m_cmakeServer->sendRequest(CONFIGURE_TYPE, extra);
} }
@@ -389,42 +390,49 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps)
void ServerModeReader::handleReply(const QVariantMap &data, const QString &inReplyTo) void ServerModeReader::handleReply(const QVariantMap &data, const QString &inReplyTo)
{ {
Q_UNUSED(data); if (!m_delayedErrorMessage.isEmpty()) {
if (inReplyTo == CONFIGURE_TYPE) { // Handle reply to cache after error:
m_cmakeServer->sendRequest(COMPUTE_TYPE); if (inReplyTo == CACHE_TYPE)
if (m_future) extractCacheData(data);
m_future->setProgressValue(1000); reportError();
m_progressStepMinimum = m_progressStepMaximum; } else {
m_progressStepMaximum = 1100; // No error yet:
} else if (inReplyTo == COMPUTE_TYPE) { if (inReplyTo == CONFIGURE_TYPE) {
m_cmakeServer->sendRequest(CODEMODEL_TYPE); m_cmakeServer->sendRequest(COMPUTE_TYPE);
if (m_future) if (m_future)
m_future->setProgressValue(1100); m_future->setProgressValue(1000);
m_progressStepMinimum = m_progressStepMaximum; m_progressStepMinimum = m_progressStepMaximum;
m_progressStepMaximum = 1200; m_progressStepMaximum = 1100;
} else if (inReplyTo == CODEMODEL_TYPE) { } else if (inReplyTo == COMPUTE_TYPE) {
extractCodeModelData(data); m_cmakeServer->sendRequest(CODEMODEL_TYPE);
m_cmakeServer->sendRequest(CMAKE_INPUTS_TYPE); if (m_future)
if (m_future) m_future->setProgressValue(1100);
m_future->setProgressValue(1200); m_progressStepMinimum = m_progressStepMaximum;
m_progressStepMinimum = m_progressStepMaximum; m_progressStepMaximum = 1200;
m_progressStepMaximum = 1300; } else if (inReplyTo == CODEMODEL_TYPE) {
} else if (inReplyTo == CMAKE_INPUTS_TYPE) { extractCodeModelData(data);
extractCMakeInputsData(data); m_cmakeServer->sendRequest(CMAKE_INPUTS_TYPE);
m_cmakeServer->sendRequest(CACHE_TYPE); if (m_future)
if (m_future) m_future->setProgressValue(1200);
m_future->setProgressValue(1300); m_progressStepMinimum = m_progressStepMaximum;
m_progressStepMinimum = m_progressStepMaximum; m_progressStepMaximum = 1300;
m_progressStepMaximum = 1400; } else if (inReplyTo == CMAKE_INPUTS_TYPE) {
} else if (inReplyTo == CACHE_TYPE) { extractCMakeInputsData(data);
extractCacheData(data); m_cmakeServer->sendRequest(CACHE_TYPE);
if (m_future) { if (m_future)
m_future->setProgressValue(MAX_PROGRESS); m_future->setProgressValue(1300);
m_future->reportFinished(); m_progressStepMinimum = m_progressStepMaximum;
m_future.reset(); m_progressStepMaximum = 1400;
} else if (inReplyTo == CACHE_TYPE) {
extractCacheData(data);
if (m_future) {
m_future->setProgressValue(MAX_PROGRESS);
m_future->reportFinished();
m_future.reset();
}
Core::MessageManager::write(tr("CMake Project was parsed successfully."));
emit dataAvailable();
} }
Core::MessageManager::write(tr("CMake Project was parsed successfully."));
emit dataAvailable();
} }
} }
@@ -432,9 +440,17 @@ void ServerModeReader::handleError(const QString &message)
{ {
TaskHub::addTask(Task::Error, message, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM, TaskHub::addTask(Task::Error, message, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM,
Utils::FileName(), -1); Utils::FileName(), -1);
stop(); if (!m_delayedErrorMessage.isEmpty()) {
Core::MessageManager::write(tr("CMake Project parsing failed.")); reportError();
emit errorOccured(message); return;
}
m_delayedErrorMessage = message;
// Always try to read CMakeCache, even after an error!
m_cmakeServer->sendRequest(CACHE_TYPE);
if (m_future)
m_future->setProgressValue(1300);
} }
void ServerModeReader::handleProgress(int min, int cur, int max, const QString &inReplyTo) void ServerModeReader::handleProgress(int min, int cur, int max, const QString &inReplyTo)
@@ -455,6 +471,18 @@ void ServerModeReader::handleSignal(const QString &signal, const QVariantMap &da
emit dirty(); emit dirty();
} }
void ServerModeReader::reportError()
{
stop();
Core::MessageManager::write(tr("CMake Project parsing failed."));
emit errorOccured(m_delayedErrorMessage);
if (m_future)
m_future->reportCanceled();
m_delayedErrorMessage.clear();
}
int ServerModeReader::calculateProgress(const int minRange, const int min, const int cur, const int max, const int maxRange) int ServerModeReader::calculateProgress(const int minRange, const int min, const int cur, const int max, const int maxRange)
{ {
if (minRange == maxRange || min == max) if (minRange == maxRange || min == max)

View File

@@ -68,6 +68,8 @@ private:
void handleProgress(int min, int cur, int max, const QString &inReplyTo); void handleProgress(int min, int cur, int max, const QString &inReplyTo);
void handleSignal(const QString &signal, const QVariantMap &data); void handleSignal(const QString &signal, const QVariantMap &data);
void reportError();
int calculateProgress(const int minRange, const int min, int calculateProgress(const int minRange, const int min,
const int cur, const int cur,
const int max, const int maxRange); const int max, const int maxRange);
@@ -166,6 +168,8 @@ private:
int m_progressStepMinimum = 0; int m_progressStepMinimum = 0;
int m_progressStepMaximum = 1000; int m_progressStepMaximum = 1000;
QString m_delayedErrorMessage;
CMakeConfig m_cmakeConfiguration; CMakeConfig m_cmakeConfiguration;
QSet<Utils::FileName> m_cmakeFiles; QSet<Utils::FileName> m_cmakeFiles;

View File

@@ -271,7 +271,7 @@ void TeaLeafReader::generateProjectTree(CMakeProjectNode *root, const QList<cons
// Delete no longer necessary file watcher based on m_cmakeFiles: // Delete no longer necessary file watcher based on m_cmakeFiles:
const QSet<FileName> currentWatched const QSet<FileName> currentWatched
= transform(m_watchedFiles, [](CMakeFile *cmf) { return cmf->filePath(); }); = transform(m_watchedFiles, &CMakeFile::filePath);
const QSet<FileName> toWatch = m_cmakeFiles; const QSet<FileName> toWatch = m_cmakeFiles;
QSet<FileName> toDelete = currentWatched; QSet<FileName> toDelete = currentWatched;
toDelete.subtract(toWatch); toDelete.subtract(toWatch);
@@ -383,7 +383,7 @@ void TeaLeafReader::updateCodeModel(CppTools::RawProjectParts &rpps)
rpp.setMacros(cbt.macros); rpp.setMacros(cbt.macros);
rpp.setDisplayName(cbt.title); rpp.setDisplayName(cbt.title);
rpp.setFiles(transform(cbt.files, [](const FileName &fn) { return fn.toString(); })); rpp.setFiles(transform(cbt.files, &FileName::toString));
const bool isExecutable = cbt.targetType == ExecutableType; const bool isExecutable = cbt.targetType == ExecutableType;
rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable

View File

@@ -1537,7 +1537,7 @@ void EditorManagerPrivate::closeView(EditorView *view)
if (!view) if (!view)
return; return;
emptyView(view); const QList<IEditor *> editorsToDelete = emptyView(view);
SplitterOrView *splitterOrView = view->parentSplitterOrView(); SplitterOrView *splitterOrView = view->parentSplitterOrView();
Q_ASSERT(splitterOrView); Q_ASSERT(splitterOrView);
@@ -1552,15 +1552,23 @@ void EditorManagerPrivate::closeView(EditorView *view)
EditorView *newCurrent = splitter->findFirstView(); EditorView *newCurrent = splitter->findFirstView();
if (newCurrent) if (newCurrent)
EditorManagerPrivate::activateView(newCurrent); EditorManagerPrivate::activateView(newCurrent);
deleteEditors(editorsToDelete);
} }
void EditorManagerPrivate::emptyView(EditorView *view) /*!
Removes all editors from the view and from the document model, taking care of
the handling of editors that are the last ones for the document.
Returns the list of editors that were actually removed from the document model and
need to be deleted with EditorManagerPrivate::deleteEditors.
\internal
*/
const QList<IEditor *> EditorManagerPrivate::emptyView(EditorView *view)
{ {
if (!view) if (!view)
return; return {};
const QList<IEditor *> editors = view->editors();
QList<IEditor *> editors = view->editors(); QList<IEditor *> removedEditors;
foreach (IEditor *editor, editors) { for (IEditor *editor : editors) {
if (DocumentModel::editorsForDocument(editor->document()).size() == 1) { if (DocumentModel::editorsForDocument(editor->document()).size() == 1) {
// it's the only editor for that file // it's the only editor for that file
// so we need to keep it around (--> in the editor model) // so we need to keep it around (--> in the editor model)
@@ -1569,19 +1577,26 @@ void EditorManagerPrivate::emptyView(EditorView *view)
setCurrentView(view); setCurrentView(view);
setCurrentEditor(nullptr); setCurrentEditor(nullptr);
} }
editors.removeAll(editor);
view->removeEditor(editor); view->removeEditor(editor);
continue; // don't close the editor } else {
emit m_instance->editorAboutToClose(editor);
removeEditor(editor, true /*=removeSuspendedEntry, but doesn't matter since it's not the last editor anyhow*/);
view->removeEditor(editor);
removedEditors.append(editor);
} }
emit m_instance->editorAboutToClose(editor);
removeEditor(editor, true /*=removeSuspendedEntry, but doesn't matter since it's not the last editor anyhow*/);
view->removeEditor(editor);
} }
return removedEditors;
}
/*!
Signals editorsClosed and deletes the editors.
\internal
*/
void EditorManagerPrivate::deleteEditors(const QList<IEditor *> &editors)
{
if (!editors.isEmpty()) { if (!editors.isEmpty()) {
emit m_instance->editorsClosed(editors); emit m_instance->editorsClosed(editors);
foreach (IEditor *editor, editors) { qDeleteAll(editors);
delete editor;
}
} }
} }
@@ -2195,7 +2210,7 @@ void EditorManagerPrivate::autoSuspendDocuments()
return; return;
auto visibleDocuments = Utils::transform<QSet>(EditorManager::visibleEditors(), auto visibleDocuments = Utils::transform<QSet>(EditorManager::visibleEditors(),
[](IEditor *editor) { return editor->document(); }); &IEditor::document);
int keptEditorCount = 0; int keptEditorCount = 0;
QList<IDocument *> documentsToSuspend; QList<IDocument *> documentsToSuspend;
foreach (const EditLocation &editLocation, d->m_globalHistory) { foreach (const EditLocation &editLocation, d->m_globalHistory) {

View File

@@ -126,7 +126,8 @@ public:
static EditorWindow *createEditorWindow(); static EditorWindow *createEditorWindow();
static void splitNewWindow(Internal::EditorView *view); static void splitNewWindow(Internal::EditorView *view);
static void closeView(Internal::EditorView *view); static void closeView(Internal::EditorView *view);
static void emptyView(Internal::EditorView *view); static const QList<IEditor *> emptyView(Internal::EditorView *view);
static void deleteEditors(const QList<IEditor *> &editors);
static void updateActions(); static void updateActions();

View File

@@ -641,7 +641,7 @@ SplitterOrView::~SplitterOrView()
delete m_layout; delete m_layout;
m_layout = nullptr; m_layout = nullptr;
if (m_view) if (m_view)
EditorManagerPrivate::emptyView(m_view); EditorManagerPrivate::deleteEditors(EditorManagerPrivate::emptyView(m_view));
delete m_view; delete m_view;
m_view = nullptr; m_view = nullptr;
delete m_splitter; delete m_splitter;
@@ -772,7 +772,7 @@ void SplitterOrView::unsplitAll()
} }
m_splitter->hide(); m_splitter->hide();
m_layout->removeWidget(m_splitter); // workaround Qt bug m_layout->removeWidget(m_splitter); // workaround Qt bug
unsplitAll_helper(); const QList<IEditor *> editorsToDelete = unsplitAll_helper();
m_view = currentView; m_view = currentView;
m_layout->addWidget(m_view); m_layout->addWidget(m_view);
delete m_splitter; delete m_splitter;
@@ -785,19 +785,27 @@ void SplitterOrView::unsplitAll()
else else
m_view->setFocus(); m_view->setFocus();
} }
EditorManagerPrivate::deleteEditors(editorsToDelete);
emit splitStateChanged(); emit splitStateChanged();
} }
void SplitterOrView::unsplitAll_helper() /*!
Recursively empties all views.
Returns the editors to delete with EditorManagerPrivate::deleteEditors.
\internal
*/
const QList<IEditor *> SplitterOrView::unsplitAll_helper()
{ {
if (m_view) if (m_view)
EditorManagerPrivate::emptyView(m_view); return EditorManagerPrivate::emptyView(m_view);
QList<IEditor *> editorsToDelete;
if (m_splitter) { if (m_splitter) {
for (int i = 0; i < m_splitter->count(); ++i) { for (int i = 0; i < m_splitter->count(); ++i) {
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i))) if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i)))
splitterOrView->unsplitAll_helper(); editorsToDelete.append(splitterOrView->unsplitAll_helper());
} }
} }
return editorsToDelete;
} }
void SplitterOrView::unsplit() void SplitterOrView::unsplit()
@@ -809,7 +817,7 @@ void SplitterOrView::unsplit()
SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(0)); SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(0));
QSplitter *oldSplitter = m_splitter; QSplitter *oldSplitter = m_splitter;
m_splitter = nullptr; m_splitter = nullptr;
QList<IEditor *> editorsToDelete;
if (childSplitterOrView->isSplitter()) { if (childSplitterOrView->isSplitter()) {
Q_ASSERT(childSplitterOrView->view() == nullptr); Q_ASSERT(childSplitterOrView->view() == nullptr);
m_splitter = childSplitterOrView->takeSplitter(); m_splitter = childSplitterOrView->takeSplitter();
@@ -825,7 +833,7 @@ void SplitterOrView::unsplit()
m_view->addEditor(e); m_view->addEditor(e);
m_view->setCurrentEditor(e); m_view->setCurrentEditor(e);
} }
EditorManagerPrivate::emptyView(childView); editorsToDelete = EditorManagerPrivate::emptyView(childView);
} else { } else {
m_view = childSplitterOrView->takeView(); m_view = childSplitterOrView->takeView();
m_view->setParentSplitterOrView(this); m_view->setParentSplitterOrView(this);
@@ -849,6 +857,7 @@ void SplitterOrView::unsplit()
EditorManagerPrivate::activateView(newCurrent); EditorManagerPrivate::activateView(newCurrent);
else else
EditorManagerPrivate::setCurrentView(nullptr); EditorManagerPrivate::setCurrentView(nullptr);
EditorManagerPrivate::deleteEditors(editorsToDelete);
emit splitStateChanged(); emit splitStateChanged();
} }

View File

@@ -202,7 +202,7 @@ signals:
void splitStateChanged(); void splitStateChanged();
private: private:
void unsplitAll_helper(); const QList<IEditor *> unsplitAll_helper();
QStackedLayout *m_layout; QStackedLayout *m_layout;
EditorView *m_view; EditorView *m_view;
QSplitter *m_splitter; QSplitter *m_splitter;

View File

@@ -243,14 +243,14 @@ Id Id::versionedId(const QByteArray &prefix, int major, int minor)
QSet<Id> Id::fromStringList(const QStringList &list) QSet<Id> Id::fromStringList(const QStringList &list)
{ {
return QSet<Id>::fromList(Utils::transform(list, [](const QString &s) { return Id::fromString(s); })); return QSet<Id>::fromList(Utils::transform(list, &Id::fromString));
} }
QStringList Id::toStringList(const QSet<Id> &ids) QStringList Id::toStringList(const QSet<Id> &ids)
{ {
QList<Id> idList = ids.toList(); QList<Id> idList = ids.toList();
Utils::sort(idList); Utils::sort(idList);
return Utils::transform(idList, [](Id i) { return i.toString(); }); return Utils::transform(idList, &Id::toString);
} }
/*! /*!

View File

@@ -353,10 +353,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
void MainWindow::openDroppedFiles(const QList<DropSupport::FileSpec> &files) void MainWindow::openDroppedFiles(const QList<DropSupport::FileSpec> &files)
{ {
raiseWindow(); raiseWindow();
QStringList filePaths = Utils::transform(files, QStringList filePaths = Utils::transform(files, &DropSupport::FileSpec::filePath);
[](const DropSupport::FileSpec &spec) -> QString {
return spec.filePath;
});
openFiles(filePaths, ICore::SwitchMode); openFiles(filePaths, ICore::SwitchMode);
} }

View File

@@ -73,8 +73,7 @@ bool ClangDiagnosticConfig::operator==(const ClangDiagnosticConfig &other) const
&& m_displayName == other.m_displayName && m_displayName == other.m_displayName
&& m_clangOptions == other.m_clangOptions && m_clangOptions == other.m_clangOptions
&& m_clangTidyMode == other.m_clangTidyMode && m_clangTidyMode == other.m_clangTidyMode
&& m_clangTidyChecksPrefixes == other.m_clangTidyChecksPrefixes && m_clangTidyChecks == other.m_clangTidyChecks
&& m_clangTidyChecksString == other.m_clangTidyChecksString
&& m_clazyChecks == other.m_clazyChecks && m_clazyChecks == other.m_clazyChecks
&& m_isReadOnly == other.m_isReadOnly; && m_isReadOnly == other.m_isReadOnly;
} }
@@ -96,35 +95,12 @@ void ClangDiagnosticConfig::setClangTidyMode(TidyMode mode)
QString ClangDiagnosticConfig::clangTidyChecks() const QString ClangDiagnosticConfig::clangTidyChecks() const
{ {
QString checks; return m_clangTidyChecks;
if (m_clangTidyMode == TidyMode::ChecksPrefixList) {
checks = QStringLiteral("-*") + clangTidyChecksPrefixes();
} else if (m_clangTidyMode == TidyMode::ChecksString) {
checks = clangTidyChecksString();
checks = checks.simplified();
checks.replace(" ", "");
}
return checks;
} }
QString ClangDiagnosticConfig::clangTidyChecksPrefixes() const void ClangDiagnosticConfig::setClangTidyChecks(const QString &checks)
{ {
return m_clangTidyChecksPrefixes; m_clangTidyChecks = checks;
}
void ClangDiagnosticConfig::setClangTidyChecksPrefixes(const QString &checks)
{
m_clangTidyChecksPrefixes = checks;
}
QString ClangDiagnosticConfig::clangTidyChecksString() const
{
return m_clangTidyChecksString;
}
void ClangDiagnosticConfig::setClangTidyChecksString(const QString &checks)
{
m_clangTidyChecksString = checks;
} }
QString ClangDiagnosticConfig::clazyChecks() const QString ClangDiagnosticConfig::clazyChecks() const

View File

@@ -41,7 +41,6 @@ public:
{ {
Disabled = 0, Disabled = 0,
ChecksPrefixList, ChecksPrefixList,
ChecksString,
File File
}; };
@@ -55,12 +54,7 @@ public:
void setClangOptions(const QStringList &options); void setClangOptions(const QStringList &options);
QString clangTidyChecks() const; QString clangTidyChecks() const;
void setClangTidyChecks(const QString &checks);
QString clangTidyChecksPrefixes() const;
void setClangTidyChecksPrefixes(const QString &checks);
QString clangTidyChecksString() const;
void setClangTidyChecksString(const QString &checks);
TidyMode clangTidyMode() const; TidyMode clangTidyMode() const;
void setClangTidyMode(TidyMode mode); void setClangTidyMode(TidyMode mode);
@@ -79,8 +73,7 @@ private:
QString m_displayName; QString m_displayName;
QStringList m_clangOptions; QStringList m_clangOptions;
TidyMode m_clangTidyMode = TidyMode::Disabled; TidyMode m_clangTidyMode = TidyMode::Disabled;
QString m_clangTidyChecksPrefixes; QString m_clangTidyChecks;
QString m_clangTidyChecksString;
QString m_clazyChecks; QString m_clazyChecks;
bool m_isReadOnly = false; bool m_isReadOnly = false;
}; };

View File

@@ -165,6 +165,15 @@ QVector<Core::Id> ClangDiagnosticConfigsModel::changedOrRemovedConfigs(
return changedConfigs; return changedConfigs;
} }
QStringList ClangDiagnosticConfigsModel::globalDiagnosticOptions()
{
return {
// Avoid undesired warnings from e.g. Q_OBJECT
QStringLiteral("-Wno-unknown-pragmas"),
QStringLiteral("-Wno-unknown-warning-option")
};
}
int ClangDiagnosticConfigsModel::indexOfConfig(const Core::Id &id) const int ClangDiagnosticConfigsModel::indexOfConfig(const Core::Id &id) const
{ {
return Utils::indexOf(m_diagnosticConfigs, [&](const ClangDiagnosticConfig &config) { return Utils::indexOf(m_diagnosticConfigs, [&](const ClangDiagnosticConfig &config) {

View File

@@ -53,6 +53,7 @@ public:
static QString displayNameWithBuiltinIndication(const ClangDiagnosticConfig &config); static QString displayNameWithBuiltinIndication(const ClangDiagnosticConfig &config);
static QVector<Core::Id> changedOrRemovedConfigs(const ClangDiagnosticConfigs &oldConfigs, static QVector<Core::Id> changedOrRemovedConfigs(const ClangDiagnosticConfigs &oldConfigs,
const ClangDiagnosticConfigs &newConfigs); const ClangDiagnosticConfigs &newConfigs);
static QStringList globalDiagnosticOptions();
private: private:
ClangDiagnosticConfigs m_diagnosticConfigs; ClangDiagnosticConfigs m_diagnosticConfigs;

View File

@@ -39,34 +39,6 @@
namespace CppTools { namespace CppTools {
static void connectToClangDiagnosticConfigsDialog(QPushButton *button)
{
QObject::connect(button, &QPushButton::clicked, []() {
ClangDiagnosticConfigsWidget *widget = new ClangDiagnosticConfigsWidget;
widget->layout()->setMargin(0);
QDialog dialog;
dialog.setWindowTitle(widget->tr("Diagnostic Configurations"));
dialog.setLayout(new QVBoxLayout);
dialog.layout()->addWidget(widget);
auto *buttonsBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog.layout()->addWidget(buttonsBox);
QObject::connect(buttonsBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
QObject::connect(buttonsBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
QObject::connect(&dialog, &QDialog::accepted, [widget]() {
QSharedPointer<CppCodeModelSettings> settings = codeModelSettings();
const ClangDiagnosticConfigs oldDiagnosticConfigs
= settings->clangCustomDiagnosticConfigs();
const ClangDiagnosticConfigs currentDiagnosticConfigs = widget->customConfigs();
if (oldDiagnosticConfigs != currentDiagnosticConfigs) {
settings->setClangCustomDiagnosticConfigs(currentDiagnosticConfigs);
settings->toSettings(Core::ICore::settings());
}
});
dialog.exec();
});
}
ClangDiagnosticConfigsSelectionWidget::ClangDiagnosticConfigsSelectionWidget(QWidget *parent) ClangDiagnosticConfigsSelectionWidget::ClangDiagnosticConfigsSelectionWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_label(new QLabel(tr("Diagnostic Configuration:"), this)) , m_label(new QLabel(tr("Diagnostic Configuration:"), this))
@@ -139,4 +111,32 @@ void ClangDiagnosticConfigsSelectionWidget::showLabel(bool show)
m_label->setVisible(show); m_label->setVisible(show);
} }
void ClangDiagnosticConfigsSelectionWidget::connectToClangDiagnosticConfigsDialog(QPushButton *button)
{
connect(button, &QPushButton::clicked, [this]() {
ClangDiagnosticConfigsWidget *widget = new ClangDiagnosticConfigsWidget(currentConfigId());
widget->layout()->setMargin(0);
QDialog dialog;
dialog.setWindowTitle(widget->tr("Diagnostic Configurations"));
dialog.setLayout(new QVBoxLayout);
dialog.layout()->addWidget(widget);
auto *buttonsBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog.layout()->addWidget(buttonsBox);
connect(buttonsBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
connect(buttonsBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
connect(&dialog, &QDialog::accepted, [widget]() {
QSharedPointer<CppCodeModelSettings> settings = codeModelSettings();
const ClangDiagnosticConfigs oldDiagnosticConfigs
= settings->clangCustomDiagnosticConfigs();
const ClangDiagnosticConfigs currentDiagnosticConfigs = widget->customConfigs();
if (oldDiagnosticConfigs != currentDiagnosticConfigs) {
settings->setClangCustomDiagnosticConfigs(currentDiagnosticConfigs);
settings->toSettings(Core::ICore::settings());
}
});
dialog.exec();
});
}
} // CppTools namespace } // CppTools namespace

View File

@@ -34,6 +34,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QComboBox; class QComboBox;
class QLabel; class QLabel;
class QPushButton;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace CppTools { namespace CppTools {
@@ -55,6 +56,7 @@ signals:
void currentConfigChanged(const Core::Id &currentConfigId); void currentConfigChanged(const Core::Id &currentConfigId);
private: private:
void connectToClangDiagnosticConfigsDialog(QPushButton *button);
void connectToCurrentIndexChanged(); void connectToCurrentIndexChanged();
void disconnectFromCurrentIndexChanged(); void disconnectFromCurrentIndexChanged();

View File

@@ -26,27 +26,169 @@
#include "clangdiagnosticconfigswidget.h" #include "clangdiagnosticconfigswidget.h"
#include "cppcodemodelsettings.h" #include "cppcodemodelsettings.h"
#include "cpptools_clangtidychecks.h"
#include "cpptoolsreuse.h" #include "cpptoolsreuse.h"
#include "ui_clangdiagnosticconfigswidget.h" #include "ui_clangdiagnosticconfigswidget.h"
#include "ui_clangbasechecks.h" #include "ui_clangbasechecks.h"
#include "ui_clazychecks.h" #include "ui_clazychecks.h"
#include "ui_tidychecks.h" #include "ui_tidychecks.h"
#include <projectexplorer/selectablefilesmodel.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <QDebug> #include <QDebug>
#include <QDialogButtonBox>
#include <QInputDialog> #include <QInputDialog>
#include <QPushButton> #include <QPushButton>
#include <QUuid> #include <QUuid>
namespace CppTools { namespace CppTools {
ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(QWidget *parent) static void buildTree(ProjectExplorer::Tree *parent,
ProjectExplorer::Tree *current,
const Constants::TidyNode &node)
{
current->name = QString::fromUtf8(node.name);
current->isDir = node.children.size();
if (parent) {
current->fullPath = parent->fullPath + current->name;
parent->childDirectories.push_back(current);
} else {
current->fullPath = Utils::FileName::fromString(current->name);
}
current->parent = parent;
for (const Constants::TidyNode &nodeChild : node.children)
buildTree(current, new ProjectExplorer::Tree, nodeChild);
}
class TidyChecksTreeModel final : public ProjectExplorer::SelectableFilesModel
{
Q_OBJECT
public:
TidyChecksTreeModel()
: ProjectExplorer::SelectableFilesModel(nullptr)
{
buildTree(nullptr, m_root, Constants::CLANG_TIDY_CHECKS_ROOT);
}
QString selectedChecks() const
{
QString checks;
collectChecks(m_root, checks);
return "-*" + checks;
}
void selectChecks(const QString &checks)
{
m_root->checked = Qt::Unchecked;
propagateDown(index(0, 0, QModelIndex()));
QStringList checksList = checks.simplified().remove(" ")
.split(",", QString::SkipEmptyParts);
for (QString &check : checksList) {
Qt::CheckState state;
if (check.startsWith("-")) {
check = check.right(check.length() - 1);
state = Qt::Unchecked;
} else {
state = Qt::Checked;
}
const QModelIndex index = indexForCheck(check);
if (!index.isValid())
continue;
auto node = static_cast<ProjectExplorer::Tree *>(index.internalPointer());
node->checked = state;
propagateUp(index);
propagateDown(index);
}
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const final
{
if (!index.isValid() || role == Qt::DecorationRole)
return QVariant();
if (role == Qt::DisplayRole) {
auto *node = static_cast<ProjectExplorer::Tree *>(index.internalPointer());
return node->isDir ? (node->name + "*") : node->name;
}
return ProjectExplorer::SelectableFilesModel::data(index, role);
}
private:
// TODO: Remove/replace this method after base class refactoring is done.
void traverse(const QModelIndex &index,
const std::function<bool(const QModelIndex &)> &visit) const
{
if (!index.isValid())
return;
if (!visit(index))
return;
if (!hasChildren(index))
return;
const int rows = rowCount(index);
const int cols = columnCount(index);
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j)
traverse(this->index(i, j, index), visit);
}
}
QModelIndex indexForCheck(const QString &check) const {
if (check == "*")
return index(0, 0, QModelIndex());
QModelIndex result;
traverse(index(0, 0, QModelIndex()), [&](const QModelIndex &index){
using ProjectExplorer::Tree;
if (result.isValid())
return false;
auto *node = static_cast<Tree *>(index.internalPointer());
const QString nodeName = node->fullPath.toString();
if ((check.endsWith("*") && nodeName.startsWith(check.left(check.length() - 1)))
|| (!node->isDir && nodeName == check)) {
result = index;
return false;
}
if (!check.startsWith(nodeName))
return false;
return true;
});
return result;
}
static void collectChecks(const ProjectExplorer::Tree *root, QString &checks)
{
if (root->checked == Qt::Unchecked)
return;
if (root->checked == Qt::Checked) {
checks += "," + root->fullPath.toString();
if (root->isDir)
checks += "*";
return;
}
for (const ProjectExplorer::Tree *t : root->childDirectories)
collectChecks(t, checks);
}
};
ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(const Core::Id &configToSelect,
QWidget *parent)
: QWidget(parent) : QWidget(parent)
, m_ui(new Ui::ClangDiagnosticConfigsWidget) , m_ui(new Ui::ClangDiagnosticConfigsWidget)
, m_diagnosticConfigsModel(codeModelSettings()->clangCustomDiagnosticConfigs()) , m_diagnosticConfigsModel(codeModelSettings()->clangCustomDiagnosticConfigs())
, m_tidyTreeModel(new TidyChecksTreeModel())
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
setupTabs(); setupTabs();
@@ -61,7 +203,7 @@ ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(QWidget *parent)
this, &ClangDiagnosticConfigsWidget::onRemoveButtonClicked); this, &ClangDiagnosticConfigsWidget::onRemoveButtonClicked);
connectDiagnosticOptionsChanged(); connectDiagnosticOptionsChanged();
syncWidgetsToModel(); syncWidgetsToModel(configToSelect);
} }
ClangDiagnosticConfigsWidget::~ClangDiagnosticConfigsWidget() ClangDiagnosticConfigsWidget::~ClangDiagnosticConfigsWidget()
@@ -133,22 +275,10 @@ void ClangDiagnosticConfigsWidget::onClangTidyModeChanged(int index)
syncClangTidyWidgets(config); syncClangTidyWidgets(config);
} }
void ClangDiagnosticConfigsWidget::onClangTidyItemChanged(QListWidgetItem *item) void ClangDiagnosticConfigsWidget::onClangTidyTreeChanged()
{
const QString prefix = item->text();
ClangDiagnosticConfig config = selectedConfig();
QString checks = config.clangTidyChecksPrefixes();
item->checkState() == Qt::Checked
? checks.append(',' + prefix)
: checks.remove(',' + prefix);
config.setClangTidyChecksPrefixes(checks);
updateConfig(config);
}
void ClangDiagnosticConfigsWidget::onClangTidyLineEdited(const QString &text)
{ {
ClangDiagnosticConfig config = selectedConfig(); ClangDiagnosticConfig config = selectedConfig();
config.setClangTidyChecksString(text); config.setClangTidyChecks(m_tidyTreeModel->selectedChecks());
updateConfig(config); updateConfig(config);
} }
@@ -301,18 +431,13 @@ void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticCon
switch (tidyMode) { switch (tidyMode) {
case ClangDiagnosticConfig::TidyMode::Disabled: case ClangDiagnosticConfig::TidyMode::Disabled:
case ClangDiagnosticConfig::TidyMode::File: case ClangDiagnosticConfig::TidyMode::File:
m_tidyChecks->checksString->setVisible(false); m_tidyChecks->plainTextEditButton->setVisible(false);
m_tidyChecks->checksListWrapper->setCurrentIndex(1); m_tidyChecks->checksListWrapper->setCurrentIndex(1);
break; break;
case ClangDiagnosticConfig::TidyMode::ChecksString:
m_tidyChecks->checksString->setVisible(true);
m_tidyChecks->checksListWrapper->setCurrentIndex(1);
m_tidyChecks->checksString->setText(config.clangTidyChecksString());
break;
case ClangDiagnosticConfig::TidyMode::ChecksPrefixList: case ClangDiagnosticConfig::TidyMode::ChecksPrefixList:
m_tidyChecks->checksString->setVisible(false); m_tidyChecks->plainTextEditButton->setVisible(true);
m_tidyChecks->checksListWrapper->setCurrentIndex(0); m_tidyChecks->checksListWrapper->setCurrentIndex(0);
syncTidyChecksList(config); syncTidyChecksToTree(config);
break; break;
} }
@@ -320,25 +445,9 @@ void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticCon
connectClangTidyItemChanged(); connectClangTidyItemChanged();
} }
void ClangDiagnosticConfigsWidget::syncTidyChecksList(const ClangDiagnosticConfig &config) void ClangDiagnosticConfigsWidget::syncTidyChecksToTree(const ClangDiagnosticConfig &config)
{ {
const QString tidyChecks = config.clangTidyChecksPrefixes(); m_tidyTreeModel->selectChecks(config.clangTidyChecks());
for (int row = 0; row < m_tidyChecks->checksPrefixesList->count(); ++row) {
QListWidgetItem *item = m_tidyChecks->checksPrefixesList->item(row);
Qt::ItemFlags flags = item->flags();
flags |= Qt::ItemIsUserCheckable;
if (config.isReadOnly())
flags &= ~Qt::ItemIsEnabled;
else
flags |= Qt::ItemIsEnabled;
item->setFlags(flags);
if (tidyChecks.indexOf(item->text()) != -1)
item->setCheckState(Qt::Checked);
else
item->setCheckState(Qt::Unchecked);
}
} }
void ClangDiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &config) void ClangDiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &config)
@@ -410,10 +519,8 @@ void ClangDiagnosticConfigsWidget::connectClangTidyItemChanged()
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, this,
&ClangDiagnosticConfigsWidget::onClangTidyModeChanged); &ClangDiagnosticConfigsWidget::onClangTidyModeChanged);
connect(m_tidyChecks->checksPrefixesList, &QListWidget::itemChanged, connect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged,
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged); this, &ClangDiagnosticConfigsWidget::onClangTidyTreeChanged);
connect(m_tidyChecks->checksString, &QLineEdit::textEdited,
this, &ClangDiagnosticConfigsWidget::onClangTidyLineEdited);
} }
void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged() void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged()
@@ -422,10 +529,8 @@ void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged()
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, this,
&ClangDiagnosticConfigsWidget::onClangTidyModeChanged); &ClangDiagnosticConfigsWidget::onClangTidyModeChanged);
disconnect(m_tidyChecks->checksPrefixesList, &QListWidget::itemChanged, disconnect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged,
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged); this, &ClangDiagnosticConfigsWidget::onClangTidyTreeChanged);
disconnect(m_tidyChecks->checksString, &QLineEdit::textEdited,
this, &ClangDiagnosticConfigsWidget::onClangTidyLineEdited);
} }
void ClangDiagnosticConfigsWidget::connectClazyRadioButtonClicked(QRadioButton *button) void ClangDiagnosticConfigsWidget::connectClazyRadioButtonClicked(QRadioButton *button)
@@ -492,6 +597,37 @@ void ClangDiagnosticConfigsWidget::setupTabs()
m_tidyChecks.reset(new CppTools::Ui::TidyChecks); m_tidyChecks.reset(new CppTools::Ui::TidyChecks);
m_tidyChecksWidget = new QWidget(); m_tidyChecksWidget = new QWidget();
m_tidyChecks->setupUi(m_tidyChecksWidget); m_tidyChecks->setupUi(m_tidyChecksWidget);
m_tidyChecks->checksPrefixesTree->setModel(m_tidyTreeModel.get());
m_tidyChecks->checksPrefixesTree->expandToDepth(0);
connect(m_tidyChecks->plainTextEditButton, &QPushButton::clicked, this, [this]() {
QDialog dialog;
dialog.setWindowTitle(tr("Checks"));
dialog.setLayout(new QVBoxLayout);
auto *textEdit = new QTextEdit(&dialog);
dialog.layout()->addWidget(textEdit);
auto *buttonsBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog.layout()->addWidget(buttonsBox);
QObject::connect(buttonsBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
QObject::connect(buttonsBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
const QString initialChecks = m_tidyTreeModel->selectedChecks();
textEdit->setPlainText(initialChecks);
QObject::connect(&dialog, &QDialog::accepted, [=, &initialChecks]() {
const QString updatedChecks = textEdit->toPlainText();
if (updatedChecks == initialChecks)
return;
disconnectClangTidyItemChanged();
// Also throws away invalid options.
m_tidyTreeModel->selectChecks(updatedChecks);
onClangTidyTreeChanged();
connectClangTidyItemChanged();
});
dialog.exec();
});
connectClangTidyItemChanged(); connectClangTidyItemChanged();
m_ui->tabWidget->addTab(m_clangBaseChecksWidget, tr("Clang")); m_ui->tabWidget->addTab(m_clangBaseChecksWidget, tr("Clang"));
@@ -501,3 +637,5 @@ void ClangDiagnosticConfigsWidget::setupTabs()
} }
} // CppTools namespace } // CppTools namespace
#include "clangdiagnosticconfigswidget.moc"

View File

@@ -50,12 +50,14 @@ class ClazyChecks;
class TidyChecks; class TidyChecks;
} }
class TidyChecksTreeModel;
class CPPTOOLS_EXPORT ClangDiagnosticConfigsWidget : public QWidget class CPPTOOLS_EXPORT ClangDiagnosticConfigsWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ClangDiagnosticConfigsWidget(QWidget *parent = nullptr); explicit ClangDiagnosticConfigsWidget(const Core::Id &configToSelect, QWidget *parent = nullptr);
~ClangDiagnosticConfigsWidget() override; ~ClangDiagnosticConfigsWidget() override;
ClangDiagnosticConfigs customConfigs() const; ClangDiagnosticConfigs customConfigs() const;
@@ -70,8 +72,7 @@ private:
void onCopyButtonClicked(); void onCopyButtonClicked();
void onRemoveButtonClicked(); void onRemoveButtonClicked();
void onClangTidyModeChanged(int index); void onClangTidyModeChanged(int index);
void onClangTidyItemChanged(QListWidgetItem *item); void onClangTidyTreeChanged();
void onClangTidyLineEdited(const QString &text);
void onClazyRadioButtonChanged(bool checked); void onClazyRadioButtonChanged(bool checked);
void onDiagnosticOptionsEdited(); void onDiagnosticOptionsEdited();
@@ -81,7 +82,7 @@ private:
void syncOtherWidgetsToComboBox(); void syncOtherWidgetsToComboBox();
void syncClangTidyWidgets(const ClangDiagnosticConfig &config); void syncClangTidyWidgets(const ClangDiagnosticConfig &config);
void syncClazyWidgets(const ClangDiagnosticConfig &config); void syncClazyWidgets(const ClangDiagnosticConfig &config);
void syncTidyChecksList(const ClangDiagnosticConfig &config); void syncTidyChecksToTree(const ClangDiagnosticConfig &config);
void updateConfig(const CppTools::ClangDiagnosticConfig &config); void updateConfig(const CppTools::ClangDiagnosticConfig &config);
@@ -115,6 +116,7 @@ private:
std::unique_ptr<CppTools::Ui::TidyChecks> m_tidyChecks; std::unique_ptr<CppTools::Ui::TidyChecks> m_tidyChecks;
QWidget *m_tidyChecksWidget = nullptr; QWidget *m_tidyChecksWidget = nullptr;
std::unique_ptr<TidyChecksTreeModel> m_tidyTreeModel;
int m_selectedConfigIndex = 0; int m_selectedConfigIndex = 0;
}; };

View File

@@ -17,7 +17,20 @@
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QListWidget" name="configChooserList"/> <widget class="QListWidget" name="configChooserList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>156</height>
</size>
</property>
</widget>
</item> </item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
@@ -40,10 +53,13 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>40</height> <height>100</height>
</size> </size>
</property> </property>
</spacer> </spacer>

View File

@@ -565,10 +565,10 @@ QString clangIncludeDirectory(const QString &clangVersion, const QString &clangR
QString clangExecutable(const QString &clangBinDirectory) QString clangExecutable(const QString &clangBinDirectory)
{ {
const QString hostExeSuffix(QTC_HOST_EXE_SUFFIX); const QString hostExeSuffix(QTC_HOST_EXE_SUFFIX);
QDir executable(creatorLibexecPath() + "/clang/bin/clang" + hostExeSuffix); QFileInfo executable(creatorLibexecPath() + "/clang/bin/clang" + hostExeSuffix);
if (!executable.exists()) if (!executable.exists())
executable = QDir(clangBinDirectory + "/clang" + hostExeSuffix); executable = QFileInfo(clangBinDirectory + "/clang" + hostExeSuffix);
return QDir::toNativeSeparators(executable.canonicalPath()); return QDir::toNativeSeparators(executable.canonicalFilePath());
} }
void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc() void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()

View File

@@ -55,12 +55,9 @@ static QString clangDiagnosticConfigsArrayDisplayNameKey()
static QString clangDiagnosticConfigsArrayWarningsKey() static QString clangDiagnosticConfigsArrayWarningsKey()
{ return QLatin1String("diagnosticOptions"); } { return QLatin1String("diagnosticOptions"); }
static QString clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey() static QString clangDiagnosticConfigsArrayClangTidyChecksKey()
{ return QLatin1String("clangTidyChecks"); } { return QLatin1String("clangTidyChecks"); }
static QString clangDiagnosticConfigsArrayClangTidyChecksStringKey()
{ return QLatin1String("clangTidyChecksString"); }
static QString clangDiagnosticConfigsArrayClangTidyModeKey() static QString clangDiagnosticConfigsArrayClangTidyModeKey()
{ return QLatin1String("clangTidyMode"); } { return QLatin1String("clangTidyMode"); }
@@ -96,10 +93,8 @@ static ClangDiagnosticConfigs customDiagnosticConfigsFromSettings(QSettings *s)
config.setClangOptions(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList()); config.setClangOptions(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList());
config.setClangTidyMode(static_cast<ClangDiagnosticConfig::TidyMode>( config.setClangTidyMode(static_cast<ClangDiagnosticConfig::TidyMode>(
s->value(clangDiagnosticConfigsArrayClangTidyModeKey()).toInt())); s->value(clangDiagnosticConfigsArrayClangTidyModeKey()).toInt()));
config.setClangTidyChecksPrefixes( config.setClangTidyChecks(
s->value(clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey()).toString()); s->value(clangDiagnosticConfigsArrayClangTidyChecksKey()).toString());
config.setClangTidyChecksString(
s->value(clangDiagnosticConfigsArrayClangTidyChecksStringKey()).toString());
config.setClazyChecks(s->value(clangDiagnosticConfigsArrayClazyChecksKey()).toString()); config.setClazyChecks(s->value(clangDiagnosticConfigsArrayClazyChecksKey()).toString());
configs.append(config); configs.append(config);
} }
@@ -157,10 +152,8 @@ void CppCodeModelSettings::toSettings(QSettings *s)
s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.clangOptions()); s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.clangOptions());
s->setValue(clangDiagnosticConfigsArrayClangTidyModeKey(), s->setValue(clangDiagnosticConfigsArrayClangTidyModeKey(),
static_cast<int>(config.clangTidyMode())); static_cast<int>(config.clangTidyMode()));
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey(), s->setValue(clangDiagnosticConfigsArrayClangTidyChecksKey(),
config.clangTidyChecksPrefixes()); config.clangTidyChecks());
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksStringKey(),
config.clangTidyChecksString());
s->setValue(clangDiagnosticConfigsArrayClazyChecksKey(), config.clazyChecks()); s->setValue(clangDiagnosticConfigsArrayClazyChecksKey(), config.clazyChecks());
} }
s->endArray(); s->endArray();

View File

@@ -100,7 +100,8 @@ HEADERS += \
cppsymbolinfo.h \ cppsymbolinfo.h \
cursorineditor.h \ cursorineditor.h \
wrappablelineedit.h \ wrappablelineedit.h \
usages.h usages.h \
cpptools_clangtidychecks.h
SOURCES += \ SOURCES += \
abstracteditorsupport.cpp \ abstracteditorsupport.cpp \

View File

@@ -155,6 +155,7 @@ Project {
"cppsourceprocessor.cpp", "cppsourceprocessor.cpp",
"cppsourceprocessor.h", "cppsourceprocessor.h",
"cpptools.qrc", "cpptools.qrc",
"cpptools_clangtidychecks.h",
"cpptools_global.h", "cpptools_global.h",
"cpptools_utils.h", "cpptools_utils.h",
"cpptoolsbridge.cpp", "cpptoolsbridge.cpp",

View File

@@ -0,0 +1,664 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <vector>
namespace CppTools {
namespace Constants {
struct TidyNode
{
const std::vector<TidyNode> children;
const char *name = nullptr;
TidyNode(const char *name, std::vector<TidyNode> &&children)
: children(std::move(children))
, name(name)
{}
TidyNode(const char *name) : name(name) {}
};
// CLANG-UPGRADE-CHECK: Run 'scripts/generateClangTidyChecks.py' after Clang upgrade to
// update this header.
static const TidyNode CLANG_TIDY_CHECKS_ROOT
{
"",
{
{
"android-",
{
{
"cloexec-",
{
"accept",
"accept4",
"creat",
"dup",
{
"epoll-",
{
"create",
"create1"
}
},
"fopen",
{
"inotify-",
{
"init",
"init1"
}
},
"memfd-create",
"open",
"socket"
}
}
}
},
{
"boost-",
{
"use-to-string"
}
},
{
"bugprone-",
{
"argument-comment",
"assert-side-effect",
"bool-pointer-implicit-conversion",
"copy-constructor-init",
"dangling-handle",
"fold-init-type",
"forward-declaration-namespace",
"inaccurate-erase",
"integer-division",
"misplaced-operator-in-strlen-in-alloc",
"move-forwarding-reference",
"multiple-statement-macro",
"string-constructor",
"suspicious-memset-usage",
"undefined-memory-manipulation",
"use-after-move",
"virtual-near-miss"
}
},
{
"cert-",
{
"dcl03-c",
"dcl21-cpp",
"dcl50-cpp",
"dcl54-cpp",
"dcl58-cpp",
"dcl59-cpp",
"env33-c",
"err09-cpp",
"err34-c",
"err52-cpp",
"err58-cpp",
"err60-cpp",
"err61-cpp",
"fio38-c",
"flp30-c",
"msc30-c",
"msc50-cpp",
"oop11-cpp"
}
},
{
"clang-analyzer-",
{
"apiModeling.google.GTest",
{
"core.",
{
"CallAndMessage",
"DivideZero",
"DynamicTypePropagation",
"NonNullParamChecker",
"NonnilStringConstants",
"NullDereference",
"StackAddressEscape",
"UndefinedBinaryOperatorResult",
"VLASize",
{
"builtin.",
{
"BuiltinFunctions",
"NoReturnFunctions"
}
},
{
"uninitialized.",
{
"ArraySubscript",
"Assign",
"Branch",
"CapturedBlockVariable",
"UndefReturn"
}
}
}
},
{
"cplusplus.",
{
"NewDelete",
"NewDeleteLeaks",
"SelfAssignment"
}
},
"deadcode.DeadStores",
"llvm.Conventions",
{
"nullability.",
{
"NullPassedToNonnull",
"NullReturnedFromNonnull",
"NullableDereferenced",
"NullablePassedToNonnull",
"NullableReturnedFromNonnull"
}
},
{
"optin.",
{
"cplusplus.VirtualCall",
"mpi.MPI-Checker",
{
"osx.",
{
{
"cocoa.",
{
{
"localizability.",
{
"EmptyLocalizationContextChecker",
"NonLocalizedStringChecker"
}
}
}
}
}
},
"performance.Padding",
"portability.UnixAPI"
}
},
{
"osx.",
{
"API",
"NumberObjectConversion",
"ObjCProperty",
"SecKeychainAPI",
{
"cocoa.",
{
"AtSync",
"ClassRelease",
"Dealloc",
"IncompatibleMethodTypes",
"Loops",
"MissingSuperCall",
"NSAutoreleasePool",
"NSError",
"NilArg",
"NonNilReturnValue",
"ObjCGenerics",
"RetainCount",
"SelfInit",
"SuperDealloc",
"UnusedIvars",
"VariadicMethodTypes"
}
},
{
"coreFoundation.",
{
"CFError",
"CFNumber",
"CFRetainRelease",
{
"containers.",
{
"OutOfBounds",
"PointerSizedValues"
}
}
}
}
}
},
{
"security.",
{
"FloatLoopCounter",
{
"insecureAPI.",
{
"UncheckedReturn",
"getpw",
"gets",
"mkstemp",
"mktemp",
"rand",
"strcpy",
"vfork"
}
}
}
},
{
"unix.",
{
"API",
"Malloc",
"MallocSizeof",
"MismatchedDeallocator",
"StdCLibraryFunctions",
"Vfork",
{
"cstring.",
{
"BadSizeArg",
"NullArg"
}
}
}
},
{
"valist.",
{
"CopyToSelf",
"Uninitialized",
"Unterminated"
}
}
}
},
{
"cppcoreguidelines-",
{
"c-copy-assignment-signature",
"interfaces-global-init",
"no-malloc",
"owning-memory",
{
"pro-",
{
{
"bounds-",
{
"array-to-pointer-decay",
"constant-array-index",
"pointer-arithmetic"
}
},
{
"type-",
{
"const-cast",
"cstyle-cast",
"member-init",
"reinterpret-cast",
"static-cast-downcast",
"union-access",
"vararg"
}
}
}
},
"slicing",
"special-member-functions"
}
},
{
"fuchsia-",
{
"default-arguments",
"overloaded-operator",
"virtual-inheritance"
}
},
{
"google-",
{
{
"build-",
{
"explicit-make-pair",
"namespaces",
"using-namespace"
}
},
"default-arguments",
"explicit-constructor",
"global-names-in-headers",
{
"objc-",
{
"avoid-throwing-exception",
"global-variable-declaration"
}
},
{
"readability-",
{
"braces-around-statements",
"casting",
"function-size",
"namespace-comments",
"redundant-smartptr-get",
"todo"
}
},
{
"runtime-",
{
"int",
"member-string-references",
"operator",
"references"
}
}
}
},
{
"hicpp-",
{
"braces-around-statements",
"deprecated-headers",
"exception-baseclass",
"explicit-conversions",
"function-size",
"invalid-access-moved",
"member-init",
"move-const-arg",
"named-parameter",
"new-delete-operators",
{
"no-",
{
"array-decay",
"assembler",
"malloc"
}
},
"noexcept-move",
"signed-bitwise",
"special-member-functions",
"static-assert",
"undelegated-constructor",
{
"use-",
{
"auto",
"emplace",
{
"equals-",
{
"default",
"delete"
}
},
"noexcept",
"nullptr",
"override"
}
},
"vararg"
}
},
{
"llvm-",
{
"header-guard",
"include-order",
"namespace-comment",
"twine-local"
}
},
{
"misc-",
{
"definitions-in-headers",
"forwarding-reference-overload",
"incorrect-roundings",
"lambda-function-name",
{
"macro-",
{
"parentheses",
"repeated-side-effects"
}
},
{
"misplaced-",
{
"const",
"widening-cast"
}
},
"new-delete-overloads",
"non-copyable-objects",
"redundant-expression",
{
"sizeof-",
{
"container",
"expression"
}
},
"static-assert",
{
"string-",
{
"compare",
"integer-assignment",
"literal-with-embedded-nul"
}
},
{
"suspicious-",
{
"enum-usage",
"missing-comma",
"semicolon",
"string-compare"
}
},
"swapped-arguments",
"throw-by-value-catch-by-reference",
"unconventional-assign-operator",
"undelegated-constructor",
"uniqueptr-reset-release",
{
"unused-",
{
"alias-decls",
"parameters",
"raii",
"using-decls"
}
}
}
},
{
"modernize-",
{
"avoid-bind",
"deprecated-headers",
"loop-convert",
{
"make-",
{
"shared",
"unique"
}
},
"pass-by-value",
"raw-string-literal",
"redundant-void-arg",
{
"replace-",
{
"auto-ptr",
"random-shuffle"
}
},
"return-braced-init-list",
"shrink-to-fit",
"unary-static-assert",
{
"use-",
{
"auto",
"bool-literals",
"default-member-init",
"emplace",
{
"equals-",
{
"default",
"delete"
}
},
"noexcept",
"nullptr",
"override",
"transparent-functors",
"using"
}
}
}
},
{
"mpi-",
{
"buffer-deref",
"type-mismatch"
}
},
{
"objc-",
{
{
"avoid-",
{
"nserror-init",
"spinlock"
}
},
"forbidden-subclassing",
"property-declaration"
}
},
{
"performance-",
{
"faster-string-find",
"for-range-copy",
"implicit-conversion-in-loop",
{
"inefficient-",
{
"algorithm",
"string-concatenation",
"vector-operation"
}
},
{
"move-",
{
"const-arg",
"constructor-init"
}
},
"noexcept-move-constructor",
"type-promotion-in-math-fn",
{
"unnecessary-",
{
"copy-initialization",
"value-param"
}
}
}
},
{
"readability-",
{
"avoid-const-params-in-decls",
"braces-around-statements",
"container-size-empty",
"delete-null-pointer",
"deleted-default",
"else-after-return",
"function-size",
"identifier-naming",
"implicit-bool-conversion",
"inconsistent-declaration-parameter-name",
"misleading-indentation",
"misplaced-array-index",
"named-parameter",
"non-const-parameter",
{
"redundant-",
{
"control-flow",
"declaration",
"function-ptr-dereference",
"member-init",
"smartptr-get",
{
"string-",
{
"cstr",
"init"
}
}
}
},
"simplify-boolean-expr",
{
"static-",
{
"accessed-through-instance",
"definition-in-anonymous-namespace"
}
},
"uniqueptr-delete-release"
}
}
}
};
} // namespace Constants
} // namespace CppTools

View File

@@ -93,6 +93,5 @@ const char LOCATOR_FILTER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("CppTools", "C++ Cl
const char SYMBOLS_FIND_FILTER_ID[] = "Symbols"; const char SYMBOLS_FIND_FILTER_ID[] = "Symbols";
const char SYMBOLS_FIND_FILTER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("CppTools", "C++ Symbols"); const char SYMBOLS_FIND_FILTER_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("CppTools", "C++ Symbols");
} // namespace Constants } // namespace Constants
} // namespace CppTools } // namespace CppTools

View File

@@ -37,12 +37,7 @@
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Select Clang-Tidy prefixes</string> <string>Select Checks</string>
</property>
</item>
<item>
<property name="text">
<string>Provide Clang-Tidy checks string</string>
</property> </property>
</item> </item>
<item> <item>
@@ -52,6 +47,13 @@
</item> </item>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="plainTextEditButton">
<property name="text">
<string>Edit Checks as String...</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
@@ -67,9 +69,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QLineEdit" name="checksString"/>
</item>
<item> <item>
<widget class="QStackedWidget" name="checksListWrapper"> <widget class="QStackedWidget" name="checksListWrapper">
<widget class="QWidget" name="checksPage"> <widget class="QWidget" name="checksPage">
@@ -87,87 +86,16 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QListWidget" name="checksPrefixesList"> <widget class="QTreeView" name="checksPrefixesTree">
<item> <property name="minimumSize">
<property name="text"> <size>
<string>android-*</string> <width>0</width>
</property> <height>300</height>
</item> </size>
<item> </property>
<property name="text"> <attribute name="headerVisible">
<string>boost-*</string> <bool>false</bool>
</property> </attribute>
</item>
<item>
<property name="text">
<string>bugprone-*</string>
</property>
</item>
<item>
<property name="text">
<string>cert-*</string>
</property>
</item>
<item>
<property name="text">
<string>cppcoreguidelines-*</string>
</property>
</item>
<item>
<property name="text">
<string>clang-analyzer-*</string>
</property>
</item>
<item>
<property name="text">
<string>clang-diagnostic-*</string>
</property>
</item>
<item>
<property name="text">
<string>google-*</string>
</property>
</item>
<item>
<property name="text">
<string>hicpp-*</string>
</property>
</item>
<item>
<property name="text">
<string>llvm-*</string>
</property>
</item>
<item>
<property name="text">
<string>misc-*</string>
</property>
</item>
<item>
<property name="text">
<string>modernize-*</string>
</property>
</item>
<item>
<property name="text">
<string>mpi-*</string>
</property>
</item>
<item>
<property name="text">
<string>objc-*</string>
</property>
</item>
<item>
<property name="text">
<string>performance-*</string>
</property>
</item>
<item>
<property name="text">
<string>readability-*</string>
</property>
</item>
</widget> </widget>
</item> </item>
</layout> </layout>
@@ -186,19 +114,6 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>237</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>

View File

@@ -28,7 +28,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <projectexplorer/kitchooser.h> #include <projectexplorer/kitchooser.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h> #include <projectexplorer/runconfiguration.h>
#include <ssh/sshconnection.h> #include <ssh/sshconnection.h>
#include <QDialogButtonBox> #include <QDialogButtonBox>
@@ -128,10 +128,10 @@ void StartRemoteDialog::validate()
d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid); d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
} }
StandardRunnable StartRemoteDialog::runnable() const Runnable StartRemoteDialog::runnable() const
{ {
Kit *kit = d->kitChooser->currentKit(); Kit *kit = d->kitChooser->currentKit();
StandardRunnable r; Runnable r;
r.device = DeviceKitInformation::device(kit); r.device = DeviceKitInformation::device(kit);
r.executable = d->executable->text(); r.executable = d->executable->text();
r.commandLineArguments = d->arguments->text(); r.commandLineArguments = d->arguments->text();

View File

@@ -29,7 +29,7 @@
#include <QDialog> #include <QDialog>
namespace ProjectExplorer { class StandardRunnable; } namespace ProjectExplorer { class Runnable; }
namespace Debugger { namespace Debugger {
@@ -43,7 +43,7 @@ public:
explicit StartRemoteDialog(QWidget *parent = nullptr); explicit StartRemoteDialog(QWidget *parent = nullptr);
~StartRemoteDialog() override; ~StartRemoteDialog() override;
ProjectExplorer::StandardRunnable runnable() const; ProjectExplorer::Runnable runnable() const;
private: private:
void validate(); void validate();

View File

@@ -31,7 +31,6 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <app/app_version.h> #include <app/app_version.h>
@@ -147,7 +146,7 @@ public:
Id kitId; Id kitId;
uint serverPort; uint serverPort;
QString serverAddress; QString serverAddress;
StandardRunnable runnable; Runnable runnable;
bool breakAtMain = false; bool breakAtMain = false;
QString serverStartScript; QString serverStartScript;
QString debugInfoLocation; QString debugInfoLocation;
@@ -424,7 +423,7 @@ void StartApplicationDialog::run(bool attachRemote)
settings->endGroup(); settings->endGroup();
} }
StandardRunnable inferior = newParameters.runnable; Runnable inferior = newParameters.runnable;
const QString inputAddress = dialog.d->channelOverrideEdit->text(); const QString inputAddress = dialog.d->channelOverrideEdit->text();
if (!inputAddress.isEmpty()) if (!inputAddress.isEmpty())
debugger->setRemoteChannel(inputAddress); debugger->setRemoteChannel(inputAddress);

View File

@@ -31,8 +31,9 @@
#include "debuggerprotocol.h" #include "debuggerprotocol.h"
#include <projectexplorer/devicesupport/idevice.h> #include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/runnables.h> #include <projectexplorer/runconfiguration.h>
#include <texteditor/textmark.h> #include <texteditor/textmark.h>
#include <utils/fileutils.h>
#include <QObject> #include <QObject>
#include <QProcess> #include <QProcess>
@@ -82,7 +83,7 @@ public:
DebuggerStartMode startMode = NoStartMode; DebuggerStartMode startMode = NoStartMode;
DebuggerCloseMode closeMode = KillAtClose; DebuggerCloseMode closeMode = KillAtClose;
ProjectExplorer::StandardRunnable inferior; ProjectExplorer::Runnable inferior;
QString displayName; // Used in the Snapshots view. QString displayName; // Used in the Snapshots view.
Utils::ProcessHandle attachPID; Utils::ProcessHandle attachPID;
QStringList solibSearchPath; QStringList solibSearchPath;
@@ -133,7 +134,7 @@ public:
bool breakOnMain = false; bool breakOnMain = false;
bool multiProcess = false; // Whether to set detach-on-fork off. bool multiProcess = false; // Whether to set detach-on-fork off.
ProjectExplorer::StandardRunnable debugger; ProjectExplorer::Runnable debugger;
QString overrideStartScript; // Used in attach to core and remote debugging QString overrideStartScript; // Used in attach to core and remote debugging
QString startMessage; // First status message shown. QString startMessage; // First status message shown.
QString debugInfoLocation; // Gdb "set-debug-file-directory". QString debugInfoLocation; // Gdb "set-debug-file-directory".
@@ -143,7 +144,7 @@ public:
ProjectExplorer::Abi toolChainAbi; ProjectExplorer::Abi toolChainAbi;
QString projectSourceDirectory; QString projectSourceDirectory;
QStringList projectSourceFiles; Utils::FileNameList projectSourceFiles;
// Used by Script debugging // Used by Script debugging
QString interpreter; QString interpreter;

View File

@@ -254,9 +254,9 @@ const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit)
return DebuggerItemManager::findById(id); return DebuggerItemManager::findById(id);
} }
StandardRunnable DebuggerKitInformation::runnable(const Kit *kit) Runnable DebuggerKitInformation::runnable(const Kit *kit)
{ {
StandardRunnable runnable; Runnable runnable;
if (const DebuggerItem *item = debugger(kit)) { if (const DebuggerItem *item = debugger(kit)) {
runnable.executable = item->command().toString(); runnable.executable = item->command().toString();
runnable.workingDirectory = item->workingDirectory().toString(); runnable.workingDirectory = item->workingDirectory().toString();

View File

@@ -29,7 +29,7 @@
#include "debuggerconstants.h" #include "debuggerconstants.h"
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/runnables.h> #include <projectexplorer/runconfiguration.h>
namespace Debugger { namespace Debugger {
class DebuggerItem; class DebuggerItem;
@@ -50,7 +50,7 @@ public:
void fix(ProjectExplorer::Kit *k) override; void fix(ProjectExplorer::Kit *k) override;
static const DebuggerItem *debugger(const ProjectExplorer::Kit *kit); static const DebuggerItem *debugger(const ProjectExplorer::Kit *kit);
static ProjectExplorer::StandardRunnable runnable(const ProjectExplorer::Kit *kit); static ProjectExplorer::Runnable runnable(const ProjectExplorer::Kit *kit);
enum ConfigurationError enum ConfigurationError
{ {

View File

@@ -100,7 +100,6 @@
#include <projectexplorer/projectexplorersettings.h> #include <projectexplorer/projectexplorersettings.h>
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h> #include <projectexplorer/taskhub.h>
@@ -3000,11 +2999,8 @@ void DebuggerPluginPrivate::extensionsInitialized()
auto constraint = [](RunConfiguration *runConfig) { auto constraint = [](RunConfiguration *runConfig) {
Runnable runnable = runConfig->runnable(); Runnable runnable = runConfig->runnable();
if (runnable.is<StandardRunnable>()) { if (runnable.device && runnable.device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
IDevice::ConstPtr device = runnable.as<StandardRunnable>().device; return true;
if (device && device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
return true;
}
if (DeviceTypeKitInformation::deviceTypeId(runConfig->target()->kit()) if (DeviceTypeKitInformation::deviceTypeId(runConfig->target()->kit())
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
@@ -3639,7 +3635,7 @@ void DebuggerUnitTests::testStateMachine()
auto runControl = new RunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE); auto runControl = new RunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE);
auto debugger = new DebuggerRunTool(runControl); auto debugger = new DebuggerRunTool(runControl);
debugger->setInferior(rc->runnable().as<StandardRunnable>()); debugger->setInferior(rc->runnable());
debugger->setTestCase(TestNoBoundsOfCurrentFunction); debugger->setTestCase(TestNoBoundsOfCurrentFunction);
connect(debugger, &DebuggerRunTool::stopped, connect(debugger, &DebuggerRunTool::stopped,

View File

@@ -44,7 +44,6 @@
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorericons.h> #include <projectexplorer/projectexplorericons.h>
#include <projectexplorer/runnables.h>
#include <projectexplorer/runconfigurationaspects.h> #include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
@@ -93,7 +92,7 @@ class LocalProcessRunner : public RunWorker
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::LocalProcessRunner) Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::LocalProcessRunner)
public: public:
LocalProcessRunner(RunControl *runControl, const StandardRunnable &runnable) LocalProcessRunner(RunControl *runControl, const Runnable &runnable)
: RunWorker(runControl), m_runnable(runnable) : RunWorker(runControl), m_runnable(runnable)
{ {
connect(&m_proc, &QProcess::errorOccurred, connect(&m_proc, &QProcess::errorOccurred,
@@ -177,7 +176,7 @@ public:
Core::AsynchronousMessageBox::critical(tr("Error"), msg); Core::AsynchronousMessageBox::critical(tr("Error"), msg);
} }
StandardRunnable m_runnable; Runnable m_runnable;
Utils::QtcProcess m_proc; Utils::QtcProcess m_proc;
}; };
@@ -278,7 +277,7 @@ void DebuggerRunTool::setStartMode(DebuggerStartMode startMode)
projects.insert(0, startupProject); projects.insert(0, startupProject);
} }
foreach (Project *project, projects) foreach (Project *project, projects)
m_runParameters.projectSourceFiles.append(transform(project->files(Project::SourceFiles), &FileName::toString)); m_runParameters.projectSourceFiles.append(project->files(Project::SourceFiles));
if (!projects.isEmpty()) if (!projects.isEmpty())
m_runParameters.projectSourceDirectory = projects.first()->projectDirectory().toString(); m_runParameters.projectSourceDirectory = projects.first()->projectDirectory().toString();
@@ -395,7 +394,7 @@ void DebuggerRunTool::setServerStartScript(const QString &serverStartScript)
{ {
if (!serverStartScript.isEmpty()) { if (!serverStartScript.isEmpty()) {
// Provide script information about the environment // Provide script information about the environment
StandardRunnable serverStarter; Runnable serverStarter;
serverStarter.executable = serverStartScript; serverStarter.executable = serverStartScript;
QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.inferior.executable); QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.inferior.executable);
QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.remoteChannel); QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.remoteChannel);
@@ -435,8 +434,7 @@ void DebuggerRunTool::setOverrideStartScript(const QString &script)
void DebuggerRunTool::setInferior(const Runnable &runnable) void DebuggerRunTool::setInferior(const Runnable &runnable)
{ {
QTC_ASSERT(runnable.is<StandardRunnable>(), reportFailure(); return); m_runParameters.inferior = runnable;
m_runParameters.inferior = runnable.as<StandardRunnable>();
setUseTerminal(m_runParameters.inferior.runMode == ApplicationLauncher::Console); setUseTerminal(m_runParameters.inferior.runMode == ApplicationLauncher::Console);
} }
@@ -852,14 +850,11 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
if (m_runParameters.isCppDebugging) if (m_runParameters.isCppDebugging)
m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit); m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit);
Runnable r = runnable(); m_runParameters.inferior = runnable();
if (r.is<StandardRunnable>()) { // Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...)
m_runParameters.inferior = r.as<StandardRunnable>(); m_runParameters.inferior.workingDirectory =
// Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...) FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory);
m_runParameters.inferior.workingDirectory = setUseTerminal(allowTerminal && m_runParameters.inferior.runMode == ApplicationLauncher::Console);
FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory);
setUseTerminal(allowTerminal && m_runParameters.inferior.runMode == ApplicationLauncher::Console);
}
const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH"); const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH");
if (!envBinary.isEmpty()) if (!envBinary.isEmpty())
@@ -868,7 +863,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
Project *project = runConfig ? runConfig->target()->project() : nullptr; Project *project = runConfig ? runConfig->target()->project() : nullptr;
if (project) { if (project) {
m_runParameters.projectSourceDirectory = project->projectDirectory().toString(); m_runParameters.projectSourceDirectory = project->projectDirectory().toString();
m_runParameters.projectSourceFiles = transform(project->files(Project::SourceFiles), &FileName::toString); m_runParameters.projectSourceFiles = project->files(Project::SourceFiles);
} }
m_runParameters.toolChainAbi = ToolChainKitInformation::targetAbi(kit); m_runParameters.toolChainAbi = ToolChainKitInformation::targetAbi(kit);
@@ -1005,8 +1000,7 @@ GdbServerRunner::GdbServerRunner(RunControl *runControl, GdbServerPortsGatherer
: SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer) : SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
{ {
setDisplayName("GdbServerRunner"); setDisplayName("GdbServerRunner");
if (runControl->runnable().is<StandardRunnable>()) m_runnable = runControl->runnable();
m_runnable = runControl->runnable().as<StandardRunnable>();
addStartDependency(m_portsGatherer); addStartDependency(m_portsGatherer);
} }
@@ -1014,7 +1008,7 @@ GdbServerRunner::~GdbServerRunner()
{ {
} }
void GdbServerRunner::setRunnable(const StandardRunnable &runnable) void GdbServerRunner::setRunnable(const Runnable &runnable)
{ {
m_runnable = runnable; m_runnable = runnable;
} }
@@ -1033,7 +1027,7 @@ void GdbServerRunner::start()
{ {
QTC_ASSERT(m_portsGatherer, reportFailure(); return); QTC_ASSERT(m_portsGatherer, reportFailure(); return);
StandardRunnable gdbserver; Runnable gdbserver;
gdbserver.environment = m_runnable.environment; gdbserver.environment = m_runnable.environment;
gdbserver.workingDirectory = m_runnable.workingDirectory; gdbserver.workingDirectory = m_runnable.workingDirectory;

View File

@@ -181,7 +181,7 @@ public:
~GdbServerRunner() override; ~GdbServerRunner() override;
void setRunnable(const ProjectExplorer::StandardRunnable &runnable); void setRunnable(const ProjectExplorer::Runnable &runnable);
void setUseMulti(bool on); void setUseMulti(bool on);
void setAttachPid(Utils::ProcessHandle pid); void setAttachPid(Utils::ProcessHandle pid);
@@ -189,7 +189,7 @@ private:
void start() override; void start() override;
GdbServerPortsGatherer *m_portsGatherer; GdbServerPortsGatherer *m_portsGatherer;
ProjectExplorer::StandardRunnable m_runnable; ProjectExplorer::Runnable m_runnable;
Utils::ProcessHandle m_pid; Utils::ProcessHandle m_pid;
bool m_useMulti = true; bool m_useMulti = true;
}; };

View File

@@ -696,7 +696,6 @@ void GdbEngine::interruptInferior()
showStatusMessage(tr("Stop requested..."), 5000); showStatusMessage(tr("Stop requested..."), 5000);
showMessage("TRYING TO INTERRUPT INFERIOR"); showMessage("TRYING TO INTERRUPT INFERIOR");
if (HostOsInfo::isWindowsHost() && !m_isQnxGdb) { if (HostOsInfo::isWindowsHost() && !m_isQnxGdb) {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); notifyInferiorStopFailed());
IDevice::ConstPtr device = runTool()->device(); IDevice::ConstPtr device = runTool()->device();
if (!device) if (!device)
device = runParameters().inferior.device; device = runParameters().inferior.device;
@@ -4832,7 +4831,7 @@ static QString findExecutableFromName(const QString &fileNameFromCore, const QSt
return QString(); return QString();
} }
CoreInfo CoreInfo::readExecutableNameFromCore(const StandardRunnable &debugger, const QString &coreFile) CoreInfo CoreInfo::readExecutableNameFromCore(const Runnable &debugger, const QString &coreFile)
{ {
CoreInfo cinfo; CoreInfo cinfo;
#if 0 #if 0

View File

@@ -61,7 +61,7 @@ struct CoreInfo
QString foundExecutableName; // empty if no corresponding exec could be found QString foundExecutableName; // empty if no corresponding exec could be found
bool isCore = false; bool isCore = false;
static CoreInfo readExecutableNameFromCore(const ProjectExplorer::StandardRunnable &debugger, static CoreInfo readExecutableNameFromCore(const ProjectExplorer::Runnable &debugger,
const QString &coreFile); const QString &coreFile);
}; };

View File

@@ -363,7 +363,7 @@ void AttachCoreDialog::coreFileChanged(const QString &core)
if (!HostOsInfo::isWindowsHost() && QFile::exists(core)) { if (!HostOsInfo::isWindowsHost() && QFile::exists(core)) {
Kit *k = d->kitChooser->currentKit(); Kit *k = d->kitChooser->currentKit();
QTC_ASSERT(k, return); QTC_ASSERT(k, return);
StandardRunnable debugger = DebuggerKitInformation::runnable(k); Runnable debugger = DebuggerKitInformation::runnable(k);
CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(debugger, core); CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(debugger, core);
if (!cinfo.foundExecutableName.isEmpty()) if (!cinfo.foundExecutableName.isEmpty())
d->localExecFileName->setFileName(FileName::fromString(cinfo.foundExecutableName)); d->localExecFileName->setFileName(FileName::fromString(cinfo.foundExecutableName));

View File

@@ -437,7 +437,8 @@ LogWindow::LogWindow(QWidget *parent)
"environment variables, in-memory data of the processes you are debugging, and more. " "environment variables, in-memory data of the processes you are debugging, and more. "
"It is never transferred over the internet by %1, and only stored " "It is never transferred over the internet by %1, and only stored "
"to disk if you manually use the respective option from the context menu, or through " "to disk if you manually use the respective option from the context menu, or through "
"mechanisms that are not under the control of %1, for instance in swap files.\n" "mechanisms that are not under the control of %1's Debugger plugin, "
"for instance in swap files, or other plugins you might use.\n"
"You may be asked to share the contents of this log when reporting bugs related " "You may be asked to share the contents of this log when reporting bugs related "
"to debugger operation. In this case, make sure your submission does not " "to debugger operation. In this case, make sure your submission does not "
"contain data you do not want to or you are not allowed to share.\n\n") "contain data you do not want to or you are not allowed to share.\n\n")

View File

@@ -337,6 +337,7 @@ void QmlCppEngine::continueInferior()
void QmlCppEngine::interruptInferior() void QmlCppEngine::interruptInferior()
{ {
EDEBUG("\nMASTER INTERRUPT INFERIOR"); EDEBUG("\nMASTER INTERRUPT INFERIOR");
m_activeEngine->setState(InferiorStopRequested);
m_activeEngine->interruptInferior(); m_activeEngine->interruptInferior();
} }

View File

@@ -48,7 +48,6 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <projectexplorer/applicationlauncher.h> #include <projectexplorer/applicationlauncher.h>
#include <projectexplorer/runnables.h>
#include <qmljseditor/qmljseditorconstants.h> #include <qmljseditor/qmljseditorconstants.h>
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
@@ -526,7 +525,7 @@ void QmlEngine::runEngine()
void QmlEngine::startApplicationLauncher() void QmlEngine::startApplicationLauncher()
{ {
if (!d->applicationLauncher.isRunning()) { if (!d->applicationLauncher.isRunning()) {
StandardRunnable runnable = runParameters().inferior; const Runnable runnable = runParameters().inferior;
runTool()->appendMessage(tr("Starting %1 %2").arg( runTool()->appendMessage(tr("Starting %1 %2").arg(
QDir::toNativeSeparators(runnable.executable), QDir::toNativeSeparators(runnable.executable),
runnable.commandLineArguments), runnable.commandLineArguments),

View File

@@ -29,7 +29,6 @@
#include <QSocketNotifier> #include <QSocketNotifier>
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runnables.h>
#include <utils/consoleprocess.h> #include <utils/consoleprocess.h>
@@ -85,7 +84,7 @@ private:
void stubError(const QString &msg); void stubError(const QString &msg);
Utils::ConsoleProcess m_stubProc; Utils::ConsoleProcess m_stubProc;
ProjectExplorer::StandardRunnable m_stubRunnable; ProjectExplorer::Runnable m_stubRunnable;
qint64 m_applicationPid = 0; qint64 m_applicationPid = 0;
qint64 m_applicationMainThreadId = 0; qint64 m_applicationMainThreadId = 0;
}; };

View File

@@ -38,7 +38,6 @@
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
#include <projectexplorer/runconfiguration.h> #include <projectexplorer/runconfiguration.h>
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/runnables.h>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QHBoxLayout> #include <QHBoxLayout>
@@ -116,11 +115,10 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent)
if (activeTarget) { if (activeTarget) {
if (RunConfiguration *runConfig = activeTarget->activeRunConfiguration()) { if (RunConfiguration *runConfig = activeTarget->activeRunConfiguration()) {
const Runnable runnable = runConfig->runnable(); const Runnable runnable = runConfig->runnable();
if (runnable.is<StandardRunnable>() && isLocal(runConfig)) { if (isLocal(runConfig)) {
resetExecutable->setEnabled(true); resetExecutable->setEnabled(true);
connect(resetExecutable, &QPushButton::clicked, connect(resetExecutable, &QPushButton::clicked, this, [this, runnable] {
this, [this, runnable]() { m_pathChooser->setPath(runnable.executable);
m_pathChooser->setPath(runnable.as<StandardRunnable>().executable);
}); });
} }
} }
@@ -198,8 +196,8 @@ void UnstartedAppWatcherDialog::selectExecutable()
if (activeTarget) { if (activeTarget) {
if (RunConfiguration *runConfig = activeTarget->activeRunConfiguration()) { if (RunConfiguration *runConfig = activeTarget->activeRunConfiguration()) {
const Runnable runnable = runConfig->runnable(); const Runnable runnable = runConfig->runnable();
if (runnable.is<StandardRunnable>() && isLocal(runConfig)) if (isLocal(runConfig))
path = QFileInfo(runnable.as<StandardRunnable>().executable).path(); path = QFileInfo(runnable.executable).path();
} }
} }

View File

@@ -38,7 +38,7 @@ RemoteModel::RemoteModel(QObject *parent) : QAbstractTableModel(parent)
QStringList RemoteModel::allRemoteNames() const QStringList RemoteModel::allRemoteNames() const
{ {
return Utils::transform(m_remotes, std::mem_fn(&Remote::name)); return Utils::transform(m_remotes, &Remote::name);
} }
QString RemoteModel::remoteName(int row) const QString RemoteModel::remoteName(int row) const

View File

@@ -70,9 +70,7 @@ void HelpIndexFilter::prepareSearch(const QString &entry)
{ {
Q_UNUSED(entry) Q_UNUSED(entry)
QStringList namespaces = HelpManager::registeredNamespaces(); QStringList namespaces = HelpManager::registeredNamespaces();
m_helpDatabases = Utils::transform(namespaces, [](const QString &ns) { m_helpDatabases = Utils::transform(namespaces, &HelpManager::fileFromNamespace);
return HelpManager::fileFromNamespace(ns);
});
} }
QList<LocatorFilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &entry) QList<LocatorFilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &entry)

Some files were not shown because too many files have changed in this diff Show More