Merge remote-tracking branch 'origin/4.7'
Conflicts: src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h Change-Id: I192b9e88f967182f3275b4b98abed1220c26daac
51
dist/changes-4.6.2.md
vendored
Normal 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
@@ -9,27 +9,77 @@ you can check out from the public Git repository. For example:
|
||||
|
||||
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
|
||||
|
||||
* 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
|
||||
|
||||
* Improved performance impact on start up
|
||||
|
||||
All Projects
|
||||
|
||||
* 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
|
||||
(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
|
||||
|
||||
* Improved resize behavior of editor tool bar
|
||||
(QTCREATORBUG-15218, QTCREATORBUG-19386)
|
||||
* Fixed auto-insertion of closing brace and semicolon after classes
|
||||
(QTCREATORBUG-19726)
|
||||
* Fixed location information of macros (QTCREATORBUG-19905)
|
||||
* Clang Code Model
|
||||
* Enabled by default
|
||||
* Switched to Clang 6.0
|
||||
* Implemented outline pane, outline dropdown and
|
||||
`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
|
||||
* 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
|
||||
* 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
|
||||
|
||||
* Improved performance of timeline
|
||||
|
||||
Qt Quick Designer
|
||||
* Added zooming into flame graph items
|
||||
|
||||
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
|
||||
|
||||
@@ -56,16 +119,66 @@ Image Viewer
|
||||
|
||||
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
|
||||
|
||||
Windows
|
||||
|
||||
* Improved parsing of MSVC error messages (QTCREATORBUG-20297)
|
||||
* 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
|
||||
|
||||
Remote Linux
|
||||
* Improved behavior when emulator cannot be started (QTCREATORBUG-20160)
|
||||
|
||||
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
|
||||
|
||||
@@ -65,7 +65,7 @@ qhp.QtCreator.indexRoot =
|
||||
|
||||
qhp.QtCreator.subprojects = 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
|
||||
|
||||
# Doxygen compatibility commands
|
||||
|
||||
BIN
doc/images/qtcreator-bookmarks-view.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
doc/images/qtcreator-new-search-icon.png
Normal file
|
After Width: | Height: | Size: 668 B |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 36 KiB |
@@ -85,8 +85,8 @@
|
||||
include several files, processing a single file and all the included files
|
||||
can take a while.
|
||||
|
||||
The following services are currently implemented in the Clang
|
||||
code model plugin:
|
||||
The Clang code model plugin replaces services of the old C/C++ code model.
|
||||
Currently the following services are implemented:
|
||||
|
||||
\list
|
||||
|
||||
@@ -100,8 +100,6 @@
|
||||
|
||||
\endlist
|
||||
|
||||
To use the plugin, you must activate it and configure it in \QC.
|
||||
|
||||
\section1 Code Model Warnings
|
||||
|
||||
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}
|
||||
{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
|
||||
|
||||
To specify settings for the Clang code model:
|
||||
|
||||
@@ -159,9 +159,19 @@
|
||||
\uicontrol {Edit Bookmark}. To view the note, move the mouse pointer over
|
||||
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
|
||||
|
||||
|
||||
@@ -1848,6 +1848,12 @@
|
||||
The search results are stored in the search history from which you can
|
||||
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
|
||||
more information, see \l{Finding Symbols}.
|
||||
|
||||
@@ -1999,6 +2005,9 @@
|
||||
\inlineimage clean_pane_small.png
|
||||
(\uicontrol Clear) button.
|
||||
|
||||
\li To start a new search, click the
|
||||
\inlineimage qtcreator-new-search-icon.png
|
||||
(\uicontrol {New Search}) button.
|
||||
\endlist
|
||||
|
||||
\section1 Renaming Symbols
|
||||
|
||||
@@ -49,7 +49,8 @@
|
||||
is not available, the tooltip displays type information for the
|
||||
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
|
||||
pane next to the code editor, or, if there is not enough vertical
|
||||
space, in the fullscreen \uicontrol Help mode.
|
||||
|
||||
@@ -74,7 +74,9 @@
|
||||
{corresponding keyboard shortcut}.
|
||||
|
||||
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)
|
||||
and \uicontrol Design mode (2).
|
||||
@@ -263,7 +265,9 @@
|
||||
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
|
||||
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
|
||||
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
|
||||
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,
|
||||
deselect \uicontrol {Synchronize with Editor}.
|
||||
|
||||
To also show hidden files, select \uicontrol {Filter Files} >
|
||||
\uicontrol {Show Hidden Files}.
|
||||
|
||||
Use the context menu functions to:
|
||||
|
||||
\list
|
||||
@@ -292,16 +300,22 @@
|
||||
|
||||
\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
|
||||
\l{Adding Files to Projects}.
|
||||
|
||||
\li Rename or remove existing files.
|
||||
|
||||
\li Create new folders.
|
||||
|
||||
\li Compare the selected file with the currently open file in the diff
|
||||
editor. For more information, see \l{Comparing Files}.
|
||||
|
||||
\li Display the contents of a particular directory in the view.
|
||||
|
||||
\li Collapse all open folders.
|
||||
|
||||
\endlist
|
||||
|
||||
\section2 Viewing the Class Hierarchy
|
||||
@@ -452,7 +466,7 @@
|
||||
The figure below shows an example search result for all
|
||||
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
|
||||
\l {Finding and Replacing}.
|
||||
@@ -601,6 +615,11 @@
|
||||
|
||||
\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
|
||||
\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
|
||||
@@ -623,4 +642,70 @@
|
||||
\uicontrol Keyboard
|
||||
\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.
|
||||
*/
|
||||
|
||||
@@ -108,37 +108,10 @@
|
||||
|
||||
\b {How do I reset all \QC settings?}
|
||||
|
||||
\QC creates the following files and directories:
|
||||
Remove the settings files created by \QC.
|
||||
|
||||
\list
|
||||
|
||||
\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}.
|
||||
For more information about where the files are located on each supported
|
||||
platform, see \l {Location of Settings Files}.
|
||||
|
||||
\b {\QC comes with MinGW, should I use this version with Qt?}
|
||||
|
||||
|
||||
@@ -28,10 +28,7 @@
|
||||
\contentspage {Qt Creator}
|
||||
\page qtcreator-toc.html
|
||||
|
||||
\title Qt Creator TOC
|
||||
|
||||
This file is used only for generating the TOC for the help file to be
|
||||
displayed in the Qt Creator Help mode Contents view.
|
||||
\title All Topics
|
||||
|
||||
\list
|
||||
\li \l{Getting Started}
|
||||
|
||||
@@ -121,6 +121,8 @@
|
||||
\li \l{Known Issues}
|
||||
\li \l{Glossary}
|
||||
\endlist
|
||||
\row
|
||||
\li {4,1} \l{All Topics}
|
||||
\row
|
||||
\li {4,1} \note To report bugs and suggestions to the Qt Bug
|
||||
Tracker, select \uicontrol {Help > Report Bug}.
|
||||
|
||||
179
scripts/generateClangTidyChecks.py
Normal 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()
|
||||
@@ -492,7 +492,7 @@ def qdump__QFile(d, value):
|
||||
if qtVersion >= 0x050700:
|
||||
if d.isWindowsTarget():
|
||||
if d.isMsvcTarget():
|
||||
offset = 184 if is32bit else 248
|
||||
offset = 176 if is32bit else 248
|
||||
else:
|
||||
offset = 172 if is32bit else 248
|
||||
else:
|
||||
|
||||
@@ -36,6 +36,7 @@ Module {
|
||||
Property { name: "additionalProductTypes"; type: "string"; isList: true }
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "name"; type: "string" }
|
||||
Property { name: "prefixMapping"; type: "QVariant" }
|
||||
Property { name: "present"; type: "bool" }
|
||||
Property { name: "setupBuildEnvironment"; type: "QVariant" }
|
||||
Property { name: "setupRunEnvironment"; type: "QVariant" }
|
||||
@@ -114,7 +115,6 @@ Module {
|
||||
Property { name: "multiplexed"; type: "bool" }
|
||||
Property { name: "multiplexedType"; type: "string"; isList: true }
|
||||
Property { name: "name"; type: "string" }
|
||||
Property { name: "profile"; type: "string" }
|
||||
Property { name: "profiles"; type: "string"; isList: true }
|
||||
Property { name: "qbsSearchPaths"; type: "string"; isList: true }
|
||||
Property { name: "targetName"; type: "string" }
|
||||
@@ -146,6 +146,7 @@ Module {
|
||||
name: "Properties"
|
||||
exports: [ "qbs/Properties 1.0" ]
|
||||
prototype: "QQuickItem"
|
||||
Property { name: "condition"; type: "bool" }
|
||||
}
|
||||
Component {
|
||||
name: "PropertyOptions"
|
||||
@@ -164,7 +165,9 @@ Module {
|
||||
Property { name: "auxiliaryInputs"; type: "string"; isList: true }
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "excludedAuxiliaryInputs"; type: "string"; isList: true }
|
||||
Property { name: "excludedInputs"; 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: "inputsFromDependencies"; type: "string"; isList: true }
|
||||
Property { name: "multiplex"; type: "bool" }
|
||||
|
||||
@@ -107,6 +107,11 @@ int TimelineTraceManager::numEventTypes() const
|
||||
return d->typeStorage->size();
|
||||
}
|
||||
|
||||
void TimelineTraceManager::swapEventStorage(std::unique_ptr<TraceEventStorage> &other)
|
||||
{
|
||||
d->eventStorage.swap(other);
|
||||
}
|
||||
|
||||
const TraceEventStorage *TimelineTraceManager::eventStorage() const
|
||||
{
|
||||
return d->eventStorage.get();
|
||||
|
||||
@@ -125,6 +125,7 @@ signals:
|
||||
void recordedFeaturesChanged(quint64 features);
|
||||
|
||||
protected:
|
||||
void swapEventStorage(std::unique_ptr<TraceEventStorage> &other);
|
||||
virtual void clearEventStorage();
|
||||
virtual void clearTypeStorage();
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <QFile>
|
||||
#include <QDataStream>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Timeline {
|
||||
|
||||
template<typename Event>
|
||||
@@ -59,21 +61,90 @@ public:
|
||||
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>
|
||||
ReplayResult replay(const Loader &loader) const
|
||||
{
|
||||
QFile readFile(file.fileName());
|
||||
if (!readFile.open(QIODevice::ReadOnly))
|
||||
Iterator replayIterator(file.fileName());
|
||||
if (!replayIterator.open())
|
||||
return ReplayOpenFailed;
|
||||
|
||||
QDataStream readStream(&readFile);
|
||||
while (!readStream.atEnd()) {
|
||||
Event event;
|
||||
readStream >> event;
|
||||
if (readStream.status() == QDataStream::ReadPastEnd)
|
||||
return ReplayReadPastEnd;
|
||||
if (!loader(std::move(event)))
|
||||
while (replayIterator.hasNext()) {
|
||||
if (!loader(replayIterator.next()))
|
||||
return ReplayLoadFailed;
|
||||
if (replayIterator.readPastEnd())
|
||||
return ReplayReadPastEnd;
|
||||
}
|
||||
|
||||
return ReplaySuccess;
|
||||
|
||||
@@ -140,8 +140,9 @@ bool ChangeSet::move_helper(int pos, int length, int to)
|
||||
{
|
||||
if (hasOverlap(pos, length)
|
||||
|| hasOverlap(to, 0)
|
||||
|| overlaps(pos, length, to, 0))
|
||||
|| overlaps(pos, length, to, 0)) {
|
||||
m_error = true;
|
||||
}
|
||||
|
||||
EditOp cmd(EditOp::Move);
|
||||
cmd.pos1 = pos;
|
||||
@@ -214,8 +215,9 @@ bool ChangeSet::flip_helper(int pos1, int length1, int pos2, int length2)
|
||||
{
|
||||
if (hasOverlap(pos1, length1)
|
||||
|| hasOverlap(pos2, length2)
|
||||
|| overlaps(pos1, length1, pos2, length2))
|
||||
|| overlaps(pos1, length1, pos2, length2)) {
|
||||
m_error = true;
|
||||
}
|
||||
|
||||
EditOp cmd(EditOp::Flip);
|
||||
cmd.pos1 = pos1;
|
||||
@@ -231,8 +233,9 @@ bool ChangeSet::copy_helper(int pos, int length, int to)
|
||||
{
|
||||
if (hasOverlap(pos, length)
|
||||
|| hasOverlap(to, 0)
|
||||
|| overlaps(pos, length, to, 0))
|
||||
|| overlaps(pos, length, to, 0)) {
|
||||
m_error = true;
|
||||
}
|
||||
|
||||
EditOp cmd(EditOp::Copy);
|
||||
cmd.pos1 = pos;
|
||||
@@ -243,27 +246,27 @@ bool ChangeSet::copy_helper(int pos, int length, int to)
|
||||
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);
|
||||
while (i.hasNext()) {
|
||||
EditOp &c = i.next();
|
||||
if (replace_helper.pos1 <= c.pos1)
|
||||
c.pos1 += replace_helper.text.size();
|
||||
if (replace_helper.pos1 < c.pos1)
|
||||
c.pos1 -= replace_helper.length1;
|
||||
if (op.pos1 <= c.pos1)
|
||||
c.pos1 += op.text.size();
|
||||
if (op.pos1 < c.pos1)
|
||||
c.pos1 -= op.length1;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
m_cursor->setPosition(replace_helper.pos1);
|
||||
m_cursor->setPosition(replace_helper.pos1 + replace_helper.length1, QTextCursor::KeepAnchor);
|
||||
m_cursor->insertText(replace_helper.text);
|
||||
m_cursor->setPosition(op.pos1);
|
||||
m_cursor->setPosition(op.pos1 + op.length1, QTextCursor::KeepAnchor);
|
||||
m_cursor->insertText(op.text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,22 +361,16 @@ void ChangeSet::apply_helper()
|
||||
// convert all ops to replace
|
||||
QList<EditOp> replaceList;
|
||||
{
|
||||
while (!m_operationList.isEmpty()) {
|
||||
const EditOp cmd(m_operationList.first());
|
||||
m_operationList.removeFirst();
|
||||
convertToReplace(cmd, &replaceList);
|
||||
}
|
||||
while (!m_operationList.isEmpty())
|
||||
convertToReplace(m_operationList.takeFirst(), &replaceList);
|
||||
}
|
||||
|
||||
// execute replaces
|
||||
if (m_cursor)
|
||||
m_cursor->beginEditBlock();
|
||||
|
||||
while (!replaceList.isEmpty()) {
|
||||
const EditOp cmd(replaceList.first());
|
||||
replaceList.removeFirst();
|
||||
doReplace(cmd, &replaceList);
|
||||
}
|
||||
while (!replaceList.isEmpty())
|
||||
doReplace(replaceList.takeFirst(), &replaceList);
|
||||
|
||||
if (m_cursor)
|
||||
m_cursor->endEditBlock();
|
||||
|
||||
@@ -95,7 +95,7 @@ QString FileInProjectFinder::projectDirectory() const
|
||||
return m_projectDir;
|
||||
}
|
||||
|
||||
void FileInProjectFinder::setProjectFiles(const QStringList &projectFiles)
|
||||
void FileInProjectFinder::setProjectFiles(const Utils::FileNameList &projectFiles)
|
||||
{
|
||||
if (m_projectFiles == projectFiles)
|
||||
return;
|
||||
@@ -309,9 +309,9 @@ QString FileInProjectFinder::findInSearchPath(const QString &searchPath, const Q
|
||||
QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName) const
|
||||
{
|
||||
QStringList result;
|
||||
foreach (const QString &f, m_projectFiles) {
|
||||
if (FileName::fromString(f).fileName() == fileName)
|
||||
result << f;
|
||||
foreach (const FileName &f, m_projectFiles) {
|
||||
if (f.fileName() == fileName)
|
||||
result << f.toString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -319,14 +319,15 @@ QStringList FileInProjectFinder::filesWithSameFileName(const QString &fileName)
|
||||
QStringList FileInProjectFinder::pathSegmentsWithSameName(const QString &pathSegment) const
|
||||
{
|
||||
QStringList result;
|
||||
for (const QString &f : m_projectFiles) {
|
||||
QDir dir = FileName::fromString(f).toFileInfo().absoluteDir();
|
||||
for (const FileName &f : m_projectFiles) {
|
||||
FileName currentPath = f.parentDir();
|
||||
do {
|
||||
if (dir.dirName() == pathSegment) {
|
||||
if (result.isEmpty() || result.last() != dir.path())
|
||||
result.append(dir.path());
|
||||
if (currentPath.fileName() == pathSegment) {
|
||||
if (result.isEmpty() || result.last() != currentPath.toString())
|
||||
result.append(currentPath.toString());
|
||||
}
|
||||
} while (dir.cdUp());
|
||||
currentPath = currentPath.parentDir();
|
||||
} while (!currentPath.isEmpty());
|
||||
}
|
||||
result.removeDuplicates();
|
||||
return result;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <utils/utils_global.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QHash>
|
||||
#include <QStringList>
|
||||
@@ -48,7 +49,7 @@ public:
|
||||
void setProjectDirectory(const QString &absoluteProjectPath);
|
||||
QString projectDirectory() const;
|
||||
|
||||
void setProjectFiles(const QStringList &projectFiles);
|
||||
void setProjectFiles(const Utils::FileNameList &projectFiles);
|
||||
void setSysroot(const QString &sysroot);
|
||||
|
||||
QString findFile(const QUrl &fileUrl, bool *success = nullptr) const;
|
||||
@@ -73,7 +74,7 @@ private:
|
||||
|
||||
QString m_projectDir;
|
||||
QString m_sysroot;
|
||||
QStringList m_projectFiles;
|
||||
Utils::FileNameList m_projectFiles;
|
||||
QStringList m_searchDirectories;
|
||||
mutable QHash<QString,QString> m_cache;
|
||||
};
|
||||
|
||||
@@ -183,6 +183,9 @@ public:
|
||||
|
||||
BasicSmallString &operator=(BasicSmallString &&other) noexcept
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
this->~BasicSmallString();
|
||||
|
||||
m_data = other.m_data;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "androidconfigurations.h"
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
|
||||
#include <utils/url.h>
|
||||
|
||||
|
||||
@@ -532,9 +532,7 @@ void AndroidDeviceDialog::devicesRefreshed()
|
||||
|
||||
AndroidDeviceInfoList devices = m_futureWatcherRefreshDevices.result();
|
||||
QSet<QString> startedAvds = Utils::transform<QSet>(m_connectedDevices,
|
||||
[] (const AndroidDeviceInfo &info) {
|
||||
return info.avdname;
|
||||
});
|
||||
&AndroidDeviceInfo::avdname);
|
||||
|
||||
for (const AndroidDeviceInfo &dev : devices)
|
||||
if (!startedAvds.contains(dev.avdname))
|
||||
|
||||
@@ -62,6 +62,17 @@ using namespace ProjectExplorer::Constants;
|
||||
namespace Android {
|
||||
namespace Internal {
|
||||
|
||||
class AndroidRunConfigurationFactory : public RunConfigurationFactory
|
||||
{
|
||||
public:
|
||||
AndroidRunConfigurationFactory()
|
||||
{
|
||||
registerRunConfiguration<Android::AndroidRunConfiguration>
|
||||
("Qt4ProjectManager.AndroidRunConfiguration:");
|
||||
addSupportedTargetDeviceType(Android::Constants::ANDROID_DEVICE_TYPE);
|
||||
}
|
||||
};
|
||||
|
||||
class AndroidPluginPrivate
|
||||
{
|
||||
public:
|
||||
@@ -76,6 +87,7 @@ public:
|
||||
JavaEditorFactory javaEditorFactory;
|
||||
AndroidPackageInstallationFactory packackeInstallationFactory;
|
||||
AndroidManifestEditorFactory manifestEditorFactory;
|
||||
AndroidRunConfigurationFactory runConfigFactory;
|
||||
};
|
||||
|
||||
AndroidPlugin::~AndroidPlugin()
|
||||
@@ -97,10 +109,7 @@ bool AndroidPlugin::initialize(const QStringList &arguments, QString *errorMessa
|
||||
|
||||
RunControl::registerWorker(QML_PREVIEW_RUN_MODE, [](RunControl *runControl) -> RunWorker* {
|
||||
const Runnable runnable = runControl->runConfiguration()->runnable();
|
||||
QTC_ASSERT(runnable.is<StandardRunnable>(), return nullptr);
|
||||
const StandardRunnable standardRunnable = runnable.as<StandardRunnable>();
|
||||
return new AndroidQmlToolingSupport(runControl, standardRunnable.executable,
|
||||
standardRunnable.commandLineArguments);
|
||||
return new AndroidQmlToolingSupport(runControl, runnable.executable, runnable.commandLineArguments);
|
||||
}, [](RunConfiguration *runConfig) {
|
||||
return runConfig->isEnabled()
|
||||
&& runConfig->id().name().startsWith("QmlProjectManager.QmlRunConfiguration")
|
||||
|
||||
@@ -313,9 +313,7 @@ SdkPlatformList AndroidSdkManager::installedSdkPlatforms()
|
||||
{
|
||||
AndroidSdkPackageList list = m_d->filteredPackages(AndroidSdkPackage::Installed,
|
||||
AndroidSdkPackage::SdkPlatformPackage);
|
||||
return Utils::transform(list, [](AndroidSdkPackage *p) {
|
||||
return static_cast<SdkPlatform *>(p);
|
||||
});
|
||||
return Utils::qobject_container_cast<SdkPlatform *>(list);
|
||||
}
|
||||
|
||||
const AndroidSdkPackageList &AndroidSdkManager::allSdkPackages()
|
||||
|
||||
@@ -185,7 +185,8 @@ bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorStri
|
||||
void AutotestPlugin::extensionsInitialized()
|
||||
{
|
||||
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);
|
||||
action->setEnabled(false);
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <projectexplorer/deploymentdata.h>
|
||||
#include <projectexplorer/environmentaspect.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
@@ -93,10 +92,7 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable runnable = rc->runnable();
|
||||
if (!runnable.is<StandardRunnable>())
|
||||
return;
|
||||
m_runnable = runnable.as<StandardRunnable>();
|
||||
m_runnable = rc->runnable();
|
||||
m_displayName = rc->displayName();
|
||||
m_project = rc->project();
|
||||
|
||||
@@ -193,15 +189,10 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
|
||||
continue;
|
||||
}
|
||||
|
||||
Runnable runnable = runConfig->runnable();
|
||||
if (!runnable.is<StandardRunnable>()) {
|
||||
qCDebug(LOG) << " Skipped as not being a StandardRunnable";
|
||||
continue;
|
||||
}
|
||||
StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
|
||||
const Runnable runnable = runConfig->runnable();
|
||||
// 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...
|
||||
const QString ¤tExecutable = ensureExeEnding(stdRunnable.executable);
|
||||
const QString currentExecutable = ensureExeEnding(runnable.executable);
|
||||
const QString currentBST = runConfig->buildKey() + '|';
|
||||
qCDebug(LOG) << " CurrentExecutable" << currentExecutable;
|
||||
qCDebug(LOG) << " BST of RunConfig" << currentBST;
|
||||
@@ -213,7 +204,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
|
||||
}))) {
|
||||
qCDebug(LOG) << " Using this RunConfig.";
|
||||
m_origRunConfig = runConfig;
|
||||
m_runnable = stdRunnable;
|
||||
m_runnable = runnable;
|
||||
m_runnable.executable = currentExecutable;
|
||||
m_displayName = runConfig->displayName();
|
||||
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
|
||||
if (auto rc = target->activeRunConfiguration()) {
|
||||
if (isLocal(rc)) { // FIXME for now only Desktop support
|
||||
Runnable runnable = rc->runnable();
|
||||
if (runnable.is<StandardRunnable>()) {
|
||||
StandardRunnable stdRunnable = runnable.as<StandardRunnable>();
|
||||
m_runnable.environment = stdRunnable.environment;
|
||||
m_project = project;
|
||||
m_guessedConfiguration = true;
|
||||
m_guessedFrom = rc->displayName();
|
||||
if (runMode == TestRunMode::Debug)
|
||||
m_runConfig = new TestRunConfiguration(rc->target(), this);
|
||||
}
|
||||
const Runnable runnable = rc->runnable();
|
||||
m_runnable.environment = runnable.environment;
|
||||
m_project = project;
|
||||
m_guessedConfiguration = true;
|
||||
m_guessedFrom = rc->displayName();
|
||||
if (runMode == TestRunMode::Debug)
|
||||
m_runConfig = new TestRunConfiguration(rc->target(), this);
|
||||
} else {
|
||||
qCDebug(LOG) << "not using the fallback as the current active run configuration "
|
||||
"appears to be non-Desktop";
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "autotestconstants.h"
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QFutureInterface>
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
QString runConfigDisplayName() const { return m_guessedConfiguration ? m_guessedFrom
|
||||
: m_displayName; }
|
||||
|
||||
ProjectExplorer::StandardRunnable runnable() const { return m_runnable; }
|
||||
ProjectExplorer::Runnable runnable() const { return m_runnable; }
|
||||
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
|
||||
QProcess *app) const = 0;
|
||||
virtual QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const = 0;
|
||||
@@ -105,7 +105,7 @@ private:
|
||||
TestRunConfiguration *m_runConfig = nullptr;
|
||||
QSet<QString> m_buildTargets;
|
||||
ProjectExplorer::RunConfiguration *m_origRunConfig = nullptr;
|
||||
ProjectExplorer::StandardRunnable m_runnable;
|
||||
ProjectExplorer::Runnable m_runnable;
|
||||
};
|
||||
|
||||
class DebuggableTestConfiguration : public TestConfiguration
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <debugger/debuggerrunconfigurationaspect.h>
|
||||
|
||||
@@ -62,7 +61,7 @@ public:
|
||||
|
||||
ProjectExplorer::Runnable runnable() const override
|
||||
{
|
||||
ProjectExplorer::StandardRunnable r;
|
||||
ProjectExplorer::Runnable r;
|
||||
QTC_ASSERT(m_testConfig, return r);
|
||||
r.executable = m_testConfig->executableFilePath();
|
||||
r.commandLineArguments = m_testConfig->argumentsForTestRunner().join(' ');
|
||||
|
||||
@@ -336,9 +336,7 @@ static ProjectExplorer::RunConfiguration *getRunConfiguration(const QString &dia
|
||||
RunConfiguration *runConfig = nullptr;
|
||||
const QList<RunConfiguration *> runConfigurations
|
||||
= Utils::filtered(target->runConfigurations(), [] (const RunConfiguration *rc) {
|
||||
if (!rc->runnable().is<StandardRunnable>())
|
||||
return false;
|
||||
return !rc->runnable().as<StandardRunnable>().executable.isEmpty();
|
||||
return !rc->runnable().executable.isEmpty();
|
||||
});
|
||||
if (runConfigurations.size() == 1)
|
||||
return runConfigurations.first();
|
||||
@@ -353,7 +351,7 @@ static ProjectExplorer::RunConfiguration *getRunConfiguration(const QString &dia
|
||||
runConfig = Utils::findOr(runConfigurations, nullptr, [&dName, &exe] (const RunConfiguration *rc) {
|
||||
if (rc->displayName() != dName)
|
||||
return false;
|
||||
return rc->runnable().as<StandardRunnable>().executable == exe;
|
||||
return rc->runnable().executable == exe;
|
||||
});
|
||||
}
|
||||
return runConfig;
|
||||
@@ -489,7 +487,7 @@ void TestRunner::debugTests()
|
||||
}
|
||||
|
||||
QStringList omitted;
|
||||
ProjectExplorer::StandardRunnable inferior = config->runnable();
|
||||
ProjectExplorer::Runnable inferior = config->runnable();
|
||||
inferior.executable = commandFilePath;
|
||||
|
||||
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
|
||||
QFutureInterface<TestResultPtr> *futureInterface
|
||||
= new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running);
|
||||
QFuture<TestResultPtr> future(futureInterface);
|
||||
m_futureWatcher.setFuture(future);
|
||||
m_futureWatcher.setFuture(futureInterface->future());
|
||||
|
||||
if (useOutputProcessor) {
|
||||
TestOutputReader *outputreader = config->outputReader(*futureInterface, 0);
|
||||
@@ -660,13 +657,11 @@ void RunConfigurationSelectionDialog::populate()
|
||||
if (auto project = ProjectExplorer::SessionManager::startupProject()) {
|
||||
if (auto target = project->activeTarget()) {
|
||||
for (ProjectExplorer::RunConfiguration *rc : target->runConfigurations()) {
|
||||
if (rc->runnable().is<ProjectExplorer::StandardRunnable>()) {
|
||||
auto runnable = rc->runnable().as<ProjectExplorer::StandardRunnable>();
|
||||
const QStringList rcDetails = { runnable.executable,
|
||||
runnable.commandLineArguments,
|
||||
runnable.workingDirectory };
|
||||
m_rcCombo->addItem(rc->displayName(), rcDetails);
|
||||
}
|
||||
auto runnable = rc->runnable();
|
||||
const QStringList rcDetails = { runnable.executable,
|
||||
runnable.commandLineArguments,
|
||||
runnable.workingDirectory };
|
||||
m_rcCombo->addItem(rc->displayName(), rcDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <projectexplorer/buildsteplist.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/runconfigurationaspects.h>
|
||||
#include <projectexplorer/target.h>
|
||||
@@ -70,7 +69,7 @@ BareMetalDebugSupport::BareMetalDebugSupport(RunControl *runControl)
|
||||
}
|
||||
|
||||
if (p->startupMode() == GdbServerProvider::StartupOnNetwork) {
|
||||
StandardRunnable r;
|
||||
Runnable r;
|
||||
r.executable = p->executable();
|
||||
// We need to wrap the command arguments depending on a host OS,
|
||||
// as the bare metal's GDB servers are launched on a host,
|
||||
@@ -123,7 +122,7 @@ void BareMetalDebugSupport::start()
|
||||
setCommandsAfterConnect(commands);
|
||||
#endif
|
||||
|
||||
StandardRunnable inferior;
|
||||
Runnable inferior;
|
||||
inferior.executable = bin;
|
||||
if (auto aspect = rc->extraAspect<ArgumentsAspect>())
|
||||
inferior.commandLineArguments = aspect->arguments();
|
||||
|
||||
@@ -26,14 +26,11 @@
|
||||
#include "gdbserverproviderprocess.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace BareMetal {
|
||||
@@ -62,10 +59,8 @@ GdbServerProviderProcess::GdbServerProviderProcess(
|
||||
|
||||
void GdbServerProviderProcess::start(const ProjectExplorer::Runnable &runnable)
|
||||
{
|
||||
QTC_ASSERT(runnable.is<StandardRunnable>(), return);
|
||||
QTC_ASSERT(m_process->state() == QProcess::NotRunning, return);
|
||||
auto r = runnable.as<StandardRunnable>();
|
||||
m_process->setCommand(r.executable, r.commandLineArguments);
|
||||
m_process->setCommand(runnable.executable, runnable.commandLineArguments);
|
||||
m_process->start();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#include <projectexplorer/devicesupport/deviceprocess.h>
|
||||
|
||||
namespace ProjectExplorer { class Runnable; }
|
||||
namespace Utils { class QtcProcess; }
|
||||
|
||||
namespace BareMetal {
|
||||
|
||||
@@ -32,16 +32,31 @@
|
||||
#include <utils/tooltip/tooltip.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QDesktopWidget>
|
||||
#include <QFileInfo>
|
||||
#include <QHash>
|
||||
#include <QLabel>
|
||||
#include <QUrl>
|
||||
|
||||
using namespace ClangCodeModel;
|
||||
using Internal::ClangDiagnosticWidget;
|
||||
|
||||
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_APPLY_FIX[] = "#applyFix";
|
||||
|
||||
@@ -130,12 +145,15 @@ private:
|
||||
QObject::connect(label, &QLabel::linkActivated, [table, hideToolTipAfterLinkActivation]
|
||||
(const QString &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);
|
||||
else
|
||||
openEditorAt(diagnostic);
|
||||
QTC_CHECK(!"Link target cannot be handled.");
|
||||
|
||||
if (hideToolTipAfterLinkActivation)
|
||||
Utils::ToolTip::hideImmediately();
|
||||
@@ -157,6 +175,8 @@ private:
|
||||
return text;
|
||||
}
|
||||
|
||||
static bool isClazyOption(const QString &option) { return option.startsWith("-Wclazy"); }
|
||||
|
||||
class DiagnosticTextInfo
|
||||
{
|
||||
public:
|
||||
@@ -188,7 +208,7 @@ private:
|
||||
return QString();
|
||||
|
||||
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");
|
||||
else
|
||||
return QCoreApplication::translate("ClangDiagnosticWidget", "Clang-Tidy Issue");
|
||||
@@ -212,8 +232,8 @@ private:
|
||||
static ClangBackEnd::DiagnosticContainer supplementedDiagnostic(
|
||||
const ClangBackEnd::DiagnosticContainer &diagnostic)
|
||||
{
|
||||
if (!diagnostic.category.isEmpty() && !diagnostic.enableOption.isEmpty())
|
||||
return diagnostic; // OK, diagnostics from clang have this set.
|
||||
if (!diagnostic.category.isEmpty())
|
||||
return diagnostic; // OK, diagnostics from clang itself have this set.
|
||||
|
||||
ClangBackEnd::DiagnosticContainer supplementedDiagnostic = diagnostic;
|
||||
|
||||
@@ -245,6 +265,39 @@ private:
|
||||
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(
|
||||
const ClangBackEnd::DiagnosticContainer &diagnostic)
|
||||
{
|
||||
@@ -253,7 +306,7 @@ private:
|
||||
" <td align='left'><b>%1</b></td>"
|
||||
" <td align='right'> <font color='gray'>%2</font></td>"
|
||||
" </tr>")
|
||||
.arg(diagnostic.category, diagnostic.enableOption);
|
||||
.arg(diagnostic.category, maybeClickableOption(diagnostic.enableOption));
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -556,11 +556,7 @@ private:
|
||||
|
||||
void addGlobalDiagnosticOptions()
|
||||
{
|
||||
m_options.append({
|
||||
// Avoid undesired warnings from e.g. Q_OBJECT
|
||||
QStringLiteral("-Wno-unknown-pragmas"),
|
||||
QStringLiteral("-Wno-unknown-warning-option")
|
||||
});
|
||||
m_options += CppTools::ClangDiagnosticConfigsModel::globalDiagnosticOptions();
|
||||
}
|
||||
|
||||
void addGlobalOptions()
|
||||
|
||||
148
src/plugins/clangtools/clangfixitsrefactoringchanges.cpp
Normal 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 ¤t = *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
|
||||
73
src/plugins/clangtools/clangfixitsrefactoringchanges.h
Normal 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
|
||||
@@ -78,7 +78,8 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis
|
||||
|
||||
arguments << QString("-fsyntax-only")
|
||||
<< QString("-serialize-diagnostics")
|
||||
<< QString(m_logFile);
|
||||
<< QString(m_logFile)
|
||||
<< ClangDiagnosticConfigsModel::globalDiagnosticOptions();
|
||||
|
||||
const ClangDiagnosticConfig::TidyMode tidyMode = m_diagnosticConfig.clangTidyMode();
|
||||
if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "clangtidyclazytool.h"
|
||||
|
||||
#include "clangfixitsrefactoringchanges.h"
|
||||
#include "clangselectablefilesdialog.h"
|
||||
#include "clangtoolsconstants.h"
|
||||
#include "clangtoolsdiagnosticmodel.h"
|
||||
@@ -50,8 +51,6 @@
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
#include <texteditor/refactoringchanges.h>
|
||||
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
@@ -69,42 +68,130 @@ namespace Internal {
|
||||
|
||||
static ClangTidyClazyTool *s_instance;
|
||||
|
||||
static void applyFixits(const QVector<Diagnostic> &diagnostics)
|
||||
class ApplyFixIts
|
||||
{
|
||||
TextEditor::RefactoringChanges changes;
|
||||
QMap<QString, TextEditor::RefactoringFilePtr> refactoringFiles;
|
||||
public:
|
||||
class RefactoringFileInfo
|
||||
{
|
||||
public:
|
||||
bool isValid() const { return file.isValid(); }
|
||||
|
||||
// Create refactoring files and changes
|
||||
for (const Diagnostic &diagnostic : diagnostics) {
|
||||
const auto filePath = diagnostic.location.filePath;
|
||||
QTC_ASSERT(!filePath.isEmpty(), continue);
|
||||
FixitsRefactoringFile file;
|
||||
QVector<DiagnosticItem *> diagnosticItems;
|
||||
bool hasScheduledFixits = false;
|
||||
};
|
||||
|
||||
// Get or create refactoring file
|
||||
TextEditor::RefactoringFilePtr refactoringFile = refactoringFiles.value(filePath);
|
||||
if (!refactoringFile) {
|
||||
refactoringFile = changes.file(filePath);
|
||||
refactoringFiles.insert(filePath, refactoringFile);
|
||||
ApplyFixIts(const QVector<DiagnosticItem *> &diagnosticItems)
|
||||
{
|
||||
for (DiagnosticItem *diagnosticItem : diagnosticItems) {
|
||||
const QString &filePath = diagnosticItem->diagnostic().location.filePath;
|
||||
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
|
||||
for (TextEditor::RefactoringFilePtr refactoringFile : refactoringFiles.values())
|
||||
refactoringFile->apply();
|
||||
}
|
||||
static void addFixitOperations(DiagnosticItem *diagnosticItem,
|
||||
const FixitsRefactoringFile &file, bool 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()
|
||||
: ClangTool("Clang-Tidy and Clazy")
|
||||
@@ -166,16 +253,12 @@ ClangTidyClazyTool::ClangTidyClazyTool()
|
||||
&ClangToolsDiagnosticModel::fixItsToApplyCountChanged,
|
||||
[this](int c) { m_applyFixitsButton->setEnabled(c); });
|
||||
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();
|
||||
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);
|
||||
ApplyFixIts(diagnosticItems).apply();
|
||||
});
|
||||
|
||||
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
|
||||
|
||||
@@ -9,6 +9,7 @@ LIBS += $$LIBCLANG_LIBS
|
||||
INCLUDEPATH += $$LLVM_INCLUDEPATH
|
||||
|
||||
SOURCES += \
|
||||
clangfixitsrefactoringchanges.cpp \
|
||||
clangselectablefilesdialog.cpp \
|
||||
clangtoolsdiagnosticview.cpp \
|
||||
clangtoolsprojectsettingswidget.cpp \
|
||||
@@ -29,6 +30,7 @@ SOURCES += \
|
||||
|
||||
HEADERS += \
|
||||
clangfileinfo.h \
|
||||
clangfixitsrefactoringchanges.h \
|
||||
clangselectablefilesdialog.h \
|
||||
clangtoolsdiagnosticview.h \
|
||||
clangtoolsprojectsettingswidget.h \
|
||||
|
||||
@@ -43,6 +43,8 @@ QtcPlugin {
|
||||
|
||||
files: [
|
||||
"clangfileinfo.h",
|
||||
"clangfixitsrefactoringchanges.cpp",
|
||||
"clangfixitsrefactoringchanges.h",
|
||||
"clangselectablefilesdialog.cpp",
|
||||
"clangselectablefilesdialog.h",
|
||||
"clangselectablefilesdialog.ui",
|
||||
|
||||
@@ -55,18 +55,21 @@ private:
|
||||
ClangToolsDiagnosticModel::ClangToolsDiagnosticModel(QObject *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)
|
||||
{
|
||||
const auto onFixItChanged = [this](bool checked){
|
||||
m_fixItsToApplyCount += checked ? +1 : -1;
|
||||
const auto onFixitStatusChanged = [this](FixitStatus newStatus) {
|
||||
if (newStatus == FixitStatus::Scheduled)
|
||||
++m_fixItsToApplyCount;
|
||||
else
|
||||
--m_fixItsToApplyCount;
|
||||
emit fixItsToApplyCountChanged(m_fixItsToApplyCount);
|
||||
};
|
||||
|
||||
for (const Diagnostic &d : diagnostics)
|
||||
rootItem()->appendChild(new DiagnosticItem(d, onFixItChanged));
|
||||
rootItem()->appendChild(new DiagnosticItem(d, onFixitStatusChanged));
|
||||
}
|
||||
|
||||
QList<Diagnostic> ClangToolsDiagnosticModel::diagnostics() const
|
||||
@@ -94,6 +97,12 @@ static QString createDiagnosticToolTipString(const Diagnostic &diagnostic)
|
||||
diagnostic.type.toHtmlEscaped());
|
||||
}
|
||||
|
||||
if (!diagnostic.description.isEmpty()) {
|
||||
lines << qMakePair(
|
||||
QCoreApplication::translate("ClangTools::Diagnostic", "Description:"),
|
||||
diagnostic.description.toHtmlEscaped());
|
||||
}
|
||||
|
||||
if (!diagnostic.issueContext.isEmpty() && !diagnostic.issueContextKind.isEmpty()) {
|
||||
lines << qMakePair(
|
||||
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_onCheckedFixit(onCheckedFixit)
|
||||
, m_onFixitStatusChanged(onFixitStatusChanged)
|
||||
{
|
||||
if (diag.hasFixits)
|
||||
m_fixitStatus = FixitStatus::NotScheduled;
|
||||
|
||||
// Don't show explaining steps if they add no information.
|
||||
if (diag.explainingSteps.count() == 1) {
|
||||
const ExplainingStep &step = diag.explainingSteps.first();
|
||||
@@ -218,14 +230,25 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag, const OnCheckedFixit &onC
|
||||
appendChild(new ExplainingStepItem(s));
|
||||
}
|
||||
|
||||
DiagnosticItem::~DiagnosticItem()
|
||||
{
|
||||
setFixitOperations(ReplacementOperations());
|
||||
}
|
||||
|
||||
Qt::ItemFlags DiagnosticItem::flags(int column) const
|
||||
{
|
||||
const Qt::ItemFlags itemFlags = TreeItem::flags(column);
|
||||
if (column == DiagnosticView::FixItColumn) {
|
||||
if (m_diagnostic.hasFixits)
|
||||
return itemFlags | Qt::ItemIsUserCheckable;
|
||||
else
|
||||
switch (m_fixitStatus) {
|
||||
case FixitStatus::NotAvailable:
|
||||
case FixitStatus::Applied:
|
||||
case FixitStatus::FailedToApply:
|
||||
case FixitStatus::Invalidated:
|
||||
return itemFlags & ~Qt::ItemIsEnabled;
|
||||
case FixitStatus::Scheduled:
|
||||
case FixitStatus::NotScheduled:
|
||||
return itemFlags | Qt::ItemIsUserCheckable;
|
||||
}
|
||||
}
|
||||
|
||||
return itemFlags;
|
||||
@@ -250,8 +273,33 @@ QVariant DiagnosticItem::data(int column, int role) const
|
||||
return Debugger::DetailedErrorView::locationData(role, m_diagnostic.location);
|
||||
|
||||
if (column == DiagnosticView::FixItColumn) {
|
||||
if (role == Qt::CheckStateRole)
|
||||
return m_applyFixits ? Qt::Checked : Qt::Unchecked;
|
||||
if (role == Qt::CheckStateRole) {
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -275,16 +323,32 @@ QVariant DiagnosticItem::data(int column, int role) const
|
||||
bool DiagnosticItem::setData(int column, const QVariant &data, int role)
|
||||
{
|
||||
if (column == DiagnosticView::FixItColumn && role == Qt::CheckStateRole) {
|
||||
m_applyFixits = data.value<Qt::CheckState>() == Qt::Checked ? true : false;
|
||||
update();
|
||||
if (m_onCheckedFixit)
|
||||
m_onCheckedFixit(m_applyFixits);
|
||||
const FixitStatus newStatus = data.value<Qt::CheckState>() == Qt::Checked
|
||||
? FixitStatus::Scheduled
|
||||
: FixitStatus::NotScheduled;
|
||||
|
||||
setFixItStatus(newStatus);
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "clangfixitsrefactoringchanges.h"
|
||||
#include "clangtoolsdiagnostic.h"
|
||||
#include "clangtoolsprojectsettings.h"
|
||||
|
||||
@@ -42,14 +43,29 @@ namespace ProjectExplorer { class Project; }
|
||||
namespace ClangTools {
|
||||
namespace Internal {
|
||||
|
||||
enum class FixitStatus {
|
||||
NotAvailable,
|
||||
NotScheduled,
|
||||
Scheduled,
|
||||
Applied,
|
||||
FailedToApply,
|
||||
Invalidated,
|
||||
};
|
||||
|
||||
class DiagnosticItem : public Utils::TreeItem
|
||||
{
|
||||
public:
|
||||
using OnCheckedFixit = std::function<void(bool)>;
|
||||
DiagnosticItem(const Diagnostic &diag, const OnCheckedFixit &onCheckedFixit);
|
||||
using OnFixitStatusChanged = std::function<void(FixitStatus newStatus)>;
|
||||
DiagnosticItem(const Diagnostic &diag, const OnFixitStatusChanged &onFixitStatusChanged);
|
||||
~DiagnosticItem() override;
|
||||
|
||||
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:
|
||||
Qt::ItemFlags flags(int column) const override;
|
||||
@@ -58,8 +74,10 @@ private:
|
||||
|
||||
private:
|
||||
const Diagnostic m_diagnostic;
|
||||
bool m_applyFixits = false;
|
||||
OnCheckedFixit m_onCheckedFixit;
|
||||
OnFixitStatusChanged m_onFixitStatusChanged;
|
||||
|
||||
ReplacementOperations m_fixitOperations;
|
||||
FixitStatus m_fixitStatus = FixitStatus::NotAvailable;
|
||||
};
|
||||
|
||||
class ClangToolsDiagnosticModel : public Utils::TreeModel<>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
#include <QHeaderView>
|
||||
|
||||
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 ClangTools
|
||||
|
||||
@@ -46,6 +46,7 @@ private:
|
||||
|
||||
QList<QAction *> customActions() const;
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
void setModel(QAbstractItemModel *model) override;
|
||||
|
||||
QAction *m_suppressAction;
|
||||
};
|
||||
|
||||
@@ -81,8 +81,8 @@ static CppTools::ClangDiagnosticConfig createTidyClazyConfig()
|
||||
config.setDisplayName("Test");
|
||||
config.setIsReadOnly(true);
|
||||
config.setClangOptions(QStringList{QStringLiteral("-Wno-everything")});
|
||||
config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksString);
|
||||
config.setClangTidyChecksString("-*,modernize-*, misc-*");
|
||||
config.setClangTidyMode(CppTools::ClangDiagnosticConfig::TidyMode::ChecksPrefixList);
|
||||
config.setClangTidyChecks("modernize-*, misc-*");
|
||||
config.setClazyChecks("level2");
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -356,8 +356,6 @@ QList<CMakeBuildTarget> BuildDirManager::takeBuildTargets() const
|
||||
|
||||
CMakeConfig BuildDirManager::takeCMakeConfiguration() const
|
||||
{
|
||||
QTC_ASSERT(!m_isHandlingError, return {});
|
||||
|
||||
if (!m_reader)
|
||||
return CMakeConfig();
|
||||
|
||||
|
||||
@@ -494,7 +494,7 @@ CMakeConfig CMakeConfigurationKitInformation::configuration(const Kit *k)
|
||||
if (!k)
|
||||
return CMakeConfig();
|
||||
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)
|
||||
|
||||
@@ -106,6 +106,7 @@ CMakeProject::CMakeProject(const FileName &fileName) : Project(Constants::CMAKEM
|
||||
CMakeBuildConfiguration *bc = activeBc(this);
|
||||
if (bc && bc == m_buildDirManager.buildConfiguration()) {
|
||||
bc->setError(msg);
|
||||
bc->setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration());
|
||||
handleParsingError(bc);
|
||||
}
|
||||
});
|
||||
@@ -475,7 +476,7 @@ void CMakeProject::startParsing(int reparseParameters)
|
||||
|
||||
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)
|
||||
@@ -670,7 +671,7 @@ void CMakeProject::createGeneratedCodeModelSupport()
|
||||
ExtraCompilerFactory::extraCompilerFactories();
|
||||
|
||||
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.
|
||||
const FileNameList fileList = files([&fileExtensions](const Node *n) {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
@@ -427,7 +427,7 @@ void CMakeTool::fetchVersionFromVersionOutput() const
|
||||
if (response.result != Utils::SynchronousProcessResponse::Finished)
|
||||
return;
|
||||
|
||||
QRegularExpression versionLine("^cmake version ((\\d+).(\\d+).(\\d+).*)$");
|
||||
QRegularExpression versionLine("^cmake.* version ((\\d+).(\\d+).(\\d+).*)$");
|
||||
const QString responseText = response.stdOut();
|
||||
for (const QStringRef &line : responseText.splitRef(QLatin1Char('\n'))) {
|
||||
QRegularExpressionMatch match = versionLine.match(line);
|
||||
|
||||
@@ -199,6 +199,7 @@ void ServerModeReader::parse(bool forceConfiguration)
|
||||
tr("Configuring \"%1\"").arg(m_parameters.projectName),
|
||||
"CMake.Configure");
|
||||
|
||||
m_delayedErrorMessage.clear();
|
||||
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)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
if (inReplyTo == CONFIGURE_TYPE) {
|
||||
m_cmakeServer->sendRequest(COMPUTE_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1000);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
m_progressStepMaximum = 1100;
|
||||
} else if (inReplyTo == COMPUTE_TYPE) {
|
||||
m_cmakeServer->sendRequest(CODEMODEL_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1100);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
m_progressStepMaximum = 1200;
|
||||
} else if (inReplyTo == CODEMODEL_TYPE) {
|
||||
extractCodeModelData(data);
|
||||
m_cmakeServer->sendRequest(CMAKE_INPUTS_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1200);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
m_progressStepMaximum = 1300;
|
||||
} else if (inReplyTo == CMAKE_INPUTS_TYPE) {
|
||||
extractCMakeInputsData(data);
|
||||
m_cmakeServer->sendRequest(CACHE_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1300);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
m_progressStepMaximum = 1400;
|
||||
} else if (inReplyTo == CACHE_TYPE) {
|
||||
extractCacheData(data);
|
||||
if (m_future) {
|
||||
m_future->setProgressValue(MAX_PROGRESS);
|
||||
m_future->reportFinished();
|
||||
m_future.reset();
|
||||
if (!m_delayedErrorMessage.isEmpty()) {
|
||||
// Handle reply to cache after error:
|
||||
if (inReplyTo == CACHE_TYPE)
|
||||
extractCacheData(data);
|
||||
reportError();
|
||||
} else {
|
||||
// No error yet:
|
||||
if (inReplyTo == CONFIGURE_TYPE) {
|
||||
m_cmakeServer->sendRequest(COMPUTE_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1000);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
m_progressStepMaximum = 1100;
|
||||
} else if (inReplyTo == COMPUTE_TYPE) {
|
||||
m_cmakeServer->sendRequest(CODEMODEL_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1100);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
m_progressStepMaximum = 1200;
|
||||
} else if (inReplyTo == CODEMODEL_TYPE) {
|
||||
extractCodeModelData(data);
|
||||
m_cmakeServer->sendRequest(CMAKE_INPUTS_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1200);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
m_progressStepMaximum = 1300;
|
||||
} else if (inReplyTo == CMAKE_INPUTS_TYPE) {
|
||||
extractCMakeInputsData(data);
|
||||
m_cmakeServer->sendRequest(CACHE_TYPE);
|
||||
if (m_future)
|
||||
m_future->setProgressValue(1300);
|
||||
m_progressStepMinimum = m_progressStepMaximum;
|
||||
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,
|
||||
Utils::FileName(), -1);
|
||||
stop();
|
||||
Core::MessageManager::write(tr("CMake Project parsing failed."));
|
||||
emit errorOccured(message);
|
||||
if (!m_delayedErrorMessage.isEmpty()) {
|
||||
reportError();
|
||||
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)
|
||||
@@ -455,6 +471,18 @@ void ServerModeReader::handleSignal(const QString &signal, const QVariantMap &da
|
||||
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)
|
||||
{
|
||||
if (minRange == maxRange || min == max)
|
||||
|
||||
@@ -68,6 +68,8 @@ private:
|
||||
void handleProgress(int min, int cur, int max, const QString &inReplyTo);
|
||||
void handleSignal(const QString &signal, const QVariantMap &data);
|
||||
|
||||
void reportError();
|
||||
|
||||
int calculateProgress(const int minRange, const int min,
|
||||
const int cur,
|
||||
const int max, const int maxRange);
|
||||
@@ -166,6 +168,8 @@ private:
|
||||
int m_progressStepMinimum = 0;
|
||||
int m_progressStepMaximum = 1000;
|
||||
|
||||
QString m_delayedErrorMessage;
|
||||
|
||||
CMakeConfig m_cmakeConfiguration;
|
||||
|
||||
QSet<Utils::FileName> m_cmakeFiles;
|
||||
|
||||
@@ -271,7 +271,7 @@ void TeaLeafReader::generateProjectTree(CMakeProjectNode *root, const QList<cons
|
||||
|
||||
// Delete no longer necessary file watcher based on m_cmakeFiles:
|
||||
const QSet<FileName> currentWatched
|
||||
= transform(m_watchedFiles, [](CMakeFile *cmf) { return cmf->filePath(); });
|
||||
= transform(m_watchedFiles, &CMakeFile::filePath);
|
||||
const QSet<FileName> toWatch = m_cmakeFiles;
|
||||
QSet<FileName> toDelete = currentWatched;
|
||||
toDelete.subtract(toWatch);
|
||||
@@ -383,7 +383,7 @@ void TeaLeafReader::updateCodeModel(CppTools::RawProjectParts &rpps)
|
||||
|
||||
rpp.setMacros(cbt.macros);
|
||||
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;
|
||||
rpp.setBuildTargetType(isExecutable ? CppTools::ProjectPart::Executable
|
||||
|
||||
@@ -1537,7 +1537,7 @@ void EditorManagerPrivate::closeView(EditorView *view)
|
||||
if (!view)
|
||||
return;
|
||||
|
||||
emptyView(view);
|
||||
const QList<IEditor *> editorsToDelete = emptyView(view);
|
||||
|
||||
SplitterOrView *splitterOrView = view->parentSplitterOrView();
|
||||
Q_ASSERT(splitterOrView);
|
||||
@@ -1552,15 +1552,23 @@ void EditorManagerPrivate::closeView(EditorView *view)
|
||||
EditorView *newCurrent = splitter->findFirstView();
|
||||
if (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)
|
||||
return;
|
||||
|
||||
QList<IEditor *> editors = view->editors();
|
||||
foreach (IEditor *editor, editors) {
|
||||
return {};
|
||||
const QList<IEditor *> editors = view->editors();
|
||||
QList<IEditor *> removedEditors;
|
||||
for (IEditor *editor : editors) {
|
||||
if (DocumentModel::editorsForDocument(editor->document()).size() == 1) {
|
||||
// it's the only editor for that file
|
||||
// so we need to keep it around (--> in the editor model)
|
||||
@@ -1569,19 +1577,26 @@ void EditorManagerPrivate::emptyView(EditorView *view)
|
||||
setCurrentView(view);
|
||||
setCurrentEditor(nullptr);
|
||||
}
|
||||
editors.removeAll(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()) {
|
||||
emit m_instance->editorsClosed(editors);
|
||||
foreach (IEditor *editor, editors) {
|
||||
delete editor;
|
||||
}
|
||||
qDeleteAll(editors);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2195,7 +2210,7 @@ void EditorManagerPrivate::autoSuspendDocuments()
|
||||
return;
|
||||
|
||||
auto visibleDocuments = Utils::transform<QSet>(EditorManager::visibleEditors(),
|
||||
[](IEditor *editor) { return editor->document(); });
|
||||
&IEditor::document);
|
||||
int keptEditorCount = 0;
|
||||
QList<IDocument *> documentsToSuspend;
|
||||
foreach (const EditLocation &editLocation, d->m_globalHistory) {
|
||||
|
||||
@@ -126,7 +126,8 @@ public:
|
||||
static EditorWindow *createEditorWindow();
|
||||
static void splitNewWindow(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();
|
||||
|
||||
|
||||
@@ -641,7 +641,7 @@ SplitterOrView::~SplitterOrView()
|
||||
delete m_layout;
|
||||
m_layout = nullptr;
|
||||
if (m_view)
|
||||
EditorManagerPrivate::emptyView(m_view);
|
||||
EditorManagerPrivate::deleteEditors(EditorManagerPrivate::emptyView(m_view));
|
||||
delete m_view;
|
||||
m_view = nullptr;
|
||||
delete m_splitter;
|
||||
@@ -772,7 +772,7 @@ void SplitterOrView::unsplitAll()
|
||||
}
|
||||
m_splitter->hide();
|
||||
m_layout->removeWidget(m_splitter); // workaround Qt bug
|
||||
unsplitAll_helper();
|
||||
const QList<IEditor *> editorsToDelete = unsplitAll_helper();
|
||||
m_view = currentView;
|
||||
m_layout->addWidget(m_view);
|
||||
delete m_splitter;
|
||||
@@ -785,19 +785,27 @@ void SplitterOrView::unsplitAll()
|
||||
else
|
||||
m_view->setFocus();
|
||||
}
|
||||
EditorManagerPrivate::deleteEditors(editorsToDelete);
|
||||
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)
|
||||
EditorManagerPrivate::emptyView(m_view);
|
||||
return EditorManagerPrivate::emptyView(m_view);
|
||||
QList<IEditor *> editorsToDelete;
|
||||
if (m_splitter) {
|
||||
for (int i = 0; i < m_splitter->count(); ++i) {
|
||||
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i)))
|
||||
splitterOrView->unsplitAll_helper();
|
||||
editorsToDelete.append(splitterOrView->unsplitAll_helper());
|
||||
}
|
||||
}
|
||||
return editorsToDelete;
|
||||
}
|
||||
|
||||
void SplitterOrView::unsplit()
|
||||
@@ -809,7 +817,7 @@ void SplitterOrView::unsplit()
|
||||
SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(0));
|
||||
QSplitter *oldSplitter = m_splitter;
|
||||
m_splitter = nullptr;
|
||||
|
||||
QList<IEditor *> editorsToDelete;
|
||||
if (childSplitterOrView->isSplitter()) {
|
||||
Q_ASSERT(childSplitterOrView->view() == nullptr);
|
||||
m_splitter = childSplitterOrView->takeSplitter();
|
||||
@@ -825,7 +833,7 @@ void SplitterOrView::unsplit()
|
||||
m_view->addEditor(e);
|
||||
m_view->setCurrentEditor(e);
|
||||
}
|
||||
EditorManagerPrivate::emptyView(childView);
|
||||
editorsToDelete = EditorManagerPrivate::emptyView(childView);
|
||||
} else {
|
||||
m_view = childSplitterOrView->takeView();
|
||||
m_view->setParentSplitterOrView(this);
|
||||
@@ -849,6 +857,7 @@ void SplitterOrView::unsplit()
|
||||
EditorManagerPrivate::activateView(newCurrent);
|
||||
else
|
||||
EditorManagerPrivate::setCurrentView(nullptr);
|
||||
EditorManagerPrivate::deleteEditors(editorsToDelete);
|
||||
emit splitStateChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ signals:
|
||||
void splitStateChanged();
|
||||
|
||||
private:
|
||||
void unsplitAll_helper();
|
||||
const QList<IEditor *> unsplitAll_helper();
|
||||
QStackedLayout *m_layout;
|
||||
EditorView *m_view;
|
||||
QSplitter *m_splitter;
|
||||
|
||||
@@ -243,14 +243,14 @@ Id Id::versionedId(const QByteArray &prefix, int major, int minor)
|
||||
|
||||
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)
|
||||
{
|
||||
QList<Id> idList = ids.toList();
|
||||
Utils::sort(idList);
|
||||
return Utils::transform(idList, [](Id i) { return i.toString(); });
|
||||
return Utils::transform(idList, &Id::toString);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -353,10 +353,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
void MainWindow::openDroppedFiles(const QList<DropSupport::FileSpec> &files)
|
||||
{
|
||||
raiseWindow();
|
||||
QStringList filePaths = Utils::transform(files,
|
||||
[](const DropSupport::FileSpec &spec) -> QString {
|
||||
return spec.filePath;
|
||||
});
|
||||
QStringList filePaths = Utils::transform(files, &DropSupport::FileSpec::filePath);
|
||||
openFiles(filePaths, ICore::SwitchMode);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ bool ClangDiagnosticConfig::operator==(const ClangDiagnosticConfig &other) const
|
||||
&& m_displayName == other.m_displayName
|
||||
&& m_clangOptions == other.m_clangOptions
|
||||
&& m_clangTidyMode == other.m_clangTidyMode
|
||||
&& m_clangTidyChecksPrefixes == other.m_clangTidyChecksPrefixes
|
||||
&& m_clangTidyChecksString == other.m_clangTidyChecksString
|
||||
&& m_clangTidyChecks == other.m_clangTidyChecks
|
||||
&& m_clazyChecks == other.m_clazyChecks
|
||||
&& m_isReadOnly == other.m_isReadOnly;
|
||||
}
|
||||
@@ -96,35 +95,12 @@ void ClangDiagnosticConfig::setClangTidyMode(TidyMode mode)
|
||||
|
||||
QString ClangDiagnosticConfig::clangTidyChecks() const
|
||||
{
|
||||
QString checks;
|
||||
if (m_clangTidyMode == TidyMode::ChecksPrefixList) {
|
||||
checks = QStringLiteral("-*") + clangTidyChecksPrefixes();
|
||||
} else if (m_clangTidyMode == TidyMode::ChecksString) {
|
||||
checks = clangTidyChecksString();
|
||||
checks = checks.simplified();
|
||||
checks.replace(" ", "");
|
||||
}
|
||||
return checks;
|
||||
return m_clangTidyChecks;
|
||||
}
|
||||
|
||||
QString ClangDiagnosticConfig::clangTidyChecksPrefixes() const
|
||||
void ClangDiagnosticConfig::setClangTidyChecks(const QString &checks)
|
||||
{
|
||||
return m_clangTidyChecksPrefixes;
|
||||
}
|
||||
|
||||
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;
|
||||
m_clangTidyChecks = checks;
|
||||
}
|
||||
|
||||
QString ClangDiagnosticConfig::clazyChecks() const
|
||||
|
||||
@@ -41,7 +41,6 @@ public:
|
||||
{
|
||||
Disabled = 0,
|
||||
ChecksPrefixList,
|
||||
ChecksString,
|
||||
File
|
||||
};
|
||||
|
||||
@@ -55,12 +54,7 @@ public:
|
||||
void setClangOptions(const QStringList &options);
|
||||
|
||||
QString clangTidyChecks() const;
|
||||
|
||||
QString clangTidyChecksPrefixes() const;
|
||||
void setClangTidyChecksPrefixes(const QString &checks);
|
||||
|
||||
QString clangTidyChecksString() const;
|
||||
void setClangTidyChecksString(const QString &checks);
|
||||
void setClangTidyChecks(const QString &checks);
|
||||
|
||||
TidyMode clangTidyMode() const;
|
||||
void setClangTidyMode(TidyMode mode);
|
||||
@@ -79,8 +73,7 @@ private:
|
||||
QString m_displayName;
|
||||
QStringList m_clangOptions;
|
||||
TidyMode m_clangTidyMode = TidyMode::Disabled;
|
||||
QString m_clangTidyChecksPrefixes;
|
||||
QString m_clangTidyChecksString;
|
||||
QString m_clangTidyChecks;
|
||||
QString m_clazyChecks;
|
||||
bool m_isReadOnly = false;
|
||||
};
|
||||
|
||||
@@ -165,6 +165,15 @@ QVector<Core::Id> ClangDiagnosticConfigsModel::changedOrRemovedConfigs(
|
||||
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
|
||||
{
|
||||
return Utils::indexOf(m_diagnosticConfigs, [&](const ClangDiagnosticConfig &config) {
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
static QString displayNameWithBuiltinIndication(const ClangDiagnosticConfig &config);
|
||||
static QVector<Core::Id> changedOrRemovedConfigs(const ClangDiagnosticConfigs &oldConfigs,
|
||||
const ClangDiagnosticConfigs &newConfigs);
|
||||
static QStringList globalDiagnosticOptions();
|
||||
|
||||
private:
|
||||
ClangDiagnosticConfigs m_diagnosticConfigs;
|
||||
|
||||
@@ -39,34 +39,6 @@
|
||||
|
||||
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)
|
||||
: QWidget(parent)
|
||||
, m_label(new QLabel(tr("Diagnostic Configuration:"), this))
|
||||
@@ -139,4 +111,32 @@ void ClangDiagnosticConfigsSelectionWidget::showLabel(bool 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
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace CppTools {
|
||||
@@ -55,6 +56,7 @@ signals:
|
||||
void currentConfigChanged(const Core::Id ¤tConfigId);
|
||||
|
||||
private:
|
||||
void connectToClangDiagnosticConfigsDialog(QPushButton *button);
|
||||
void connectToCurrentIndexChanged();
|
||||
void disconnectFromCurrentIndexChanged();
|
||||
|
||||
|
||||
@@ -26,27 +26,169 @@
|
||||
#include "clangdiagnosticconfigswidget.h"
|
||||
|
||||
#include "cppcodemodelsettings.h"
|
||||
#include "cpptools_clangtidychecks.h"
|
||||
#include "cpptoolsreuse.h"
|
||||
#include "ui_clangdiagnosticconfigswidget.h"
|
||||
#include "ui_clangbasechecks.h"
|
||||
#include "ui_clazychecks.h"
|
||||
#include "ui_tidychecks.h"
|
||||
|
||||
#include <projectexplorer/selectablefilesmodel.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QInputDialog>
|
||||
#include <QPushButton>
|
||||
#include <QUuid>
|
||||
|
||||
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)
|
||||
, m_ui(new Ui::ClangDiagnosticConfigsWidget)
|
||||
, m_diagnosticConfigsModel(codeModelSettings()->clangCustomDiagnosticConfigs())
|
||||
, m_tidyTreeModel(new TidyChecksTreeModel())
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setupTabs();
|
||||
@@ -61,7 +203,7 @@ ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(QWidget *parent)
|
||||
this, &ClangDiagnosticConfigsWidget::onRemoveButtonClicked);
|
||||
connectDiagnosticOptionsChanged();
|
||||
|
||||
syncWidgetsToModel();
|
||||
syncWidgetsToModel(configToSelect);
|
||||
}
|
||||
|
||||
ClangDiagnosticConfigsWidget::~ClangDiagnosticConfigsWidget()
|
||||
@@ -133,22 +275,10 @@ void ClangDiagnosticConfigsWidget::onClangTidyModeChanged(int index)
|
||||
syncClangTidyWidgets(config);
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::onClangTidyItemChanged(QListWidgetItem *item)
|
||||
{
|
||||
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)
|
||||
void ClangDiagnosticConfigsWidget::onClangTidyTreeChanged()
|
||||
{
|
||||
ClangDiagnosticConfig config = selectedConfig();
|
||||
config.setClangTidyChecksString(text);
|
||||
config.setClangTidyChecks(m_tidyTreeModel->selectedChecks());
|
||||
updateConfig(config);
|
||||
}
|
||||
|
||||
@@ -301,18 +431,13 @@ void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticCon
|
||||
switch (tidyMode) {
|
||||
case ClangDiagnosticConfig::TidyMode::Disabled:
|
||||
case ClangDiagnosticConfig::TidyMode::File:
|
||||
m_tidyChecks->checksString->setVisible(false);
|
||||
m_tidyChecks->plainTextEditButton->setVisible(false);
|
||||
m_tidyChecks->checksListWrapper->setCurrentIndex(1);
|
||||
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:
|
||||
m_tidyChecks->checksString->setVisible(false);
|
||||
m_tidyChecks->plainTextEditButton->setVisible(true);
|
||||
m_tidyChecks->checksListWrapper->setCurrentIndex(0);
|
||||
syncTidyChecksList(config);
|
||||
syncTidyChecksToTree(config);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -320,25 +445,9 @@ void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticCon
|
||||
connectClangTidyItemChanged();
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::syncTidyChecksList(const ClangDiagnosticConfig &config)
|
||||
void ClangDiagnosticConfigsWidget::syncTidyChecksToTree(const ClangDiagnosticConfig &config)
|
||||
{
|
||||
const QString tidyChecks = config.clangTidyChecksPrefixes();
|
||||
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);
|
||||
}
|
||||
m_tidyTreeModel->selectChecks(config.clangTidyChecks());
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &config)
|
||||
@@ -410,10 +519,8 @@ void ClangDiagnosticConfigsWidget::connectClangTidyItemChanged()
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
&ClangDiagnosticConfigsWidget::onClangTidyModeChanged);
|
||||
connect(m_tidyChecks->checksPrefixesList, &QListWidget::itemChanged,
|
||||
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
|
||||
connect(m_tidyChecks->checksString, &QLineEdit::textEdited,
|
||||
this, &ClangDiagnosticConfigsWidget::onClangTidyLineEdited);
|
||||
connect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged,
|
||||
this, &ClangDiagnosticConfigsWidget::onClangTidyTreeChanged);
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged()
|
||||
@@ -422,10 +529,8 @@ void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged()
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
&ClangDiagnosticConfigsWidget::onClangTidyModeChanged);
|
||||
disconnect(m_tidyChecks->checksPrefixesList, &QListWidget::itemChanged,
|
||||
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
|
||||
disconnect(m_tidyChecks->checksString, &QLineEdit::textEdited,
|
||||
this, &ClangDiagnosticConfigsWidget::onClangTidyLineEdited);
|
||||
disconnect(m_tidyTreeModel.get(), &TidyChecksTreeModel::dataChanged,
|
||||
this, &ClangDiagnosticConfigsWidget::onClangTidyTreeChanged);
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::connectClazyRadioButtonClicked(QRadioButton *button)
|
||||
@@ -492,6 +597,37 @@ void ClangDiagnosticConfigsWidget::setupTabs()
|
||||
m_tidyChecks.reset(new CppTools::Ui::TidyChecks);
|
||||
m_tidyChecksWidget = new QWidget();
|
||||
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();
|
||||
|
||||
m_ui->tabWidget->addTab(m_clangBaseChecksWidget, tr("Clang"));
|
||||
@@ -501,3 +637,5 @@ void ClangDiagnosticConfigsWidget::setupTabs()
|
||||
}
|
||||
|
||||
} // CppTools namespace
|
||||
|
||||
#include "clangdiagnosticconfigswidget.moc"
|
||||
|
||||
@@ -50,12 +50,14 @@ class ClazyChecks;
|
||||
class TidyChecks;
|
||||
}
|
||||
|
||||
class TidyChecksTreeModel;
|
||||
|
||||
class CPPTOOLS_EXPORT ClangDiagnosticConfigsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ClangDiagnosticConfigsWidget(QWidget *parent = nullptr);
|
||||
explicit ClangDiagnosticConfigsWidget(const Core::Id &configToSelect, QWidget *parent = nullptr);
|
||||
~ClangDiagnosticConfigsWidget() override;
|
||||
|
||||
ClangDiagnosticConfigs customConfigs() const;
|
||||
@@ -70,8 +72,7 @@ private:
|
||||
void onCopyButtonClicked();
|
||||
void onRemoveButtonClicked();
|
||||
void onClangTidyModeChanged(int index);
|
||||
void onClangTidyItemChanged(QListWidgetItem *item);
|
||||
void onClangTidyLineEdited(const QString &text);
|
||||
void onClangTidyTreeChanged();
|
||||
void onClazyRadioButtonChanged(bool checked);
|
||||
|
||||
void onDiagnosticOptionsEdited();
|
||||
@@ -81,7 +82,7 @@ private:
|
||||
void syncOtherWidgetsToComboBox();
|
||||
void syncClangTidyWidgets(const ClangDiagnosticConfig &config);
|
||||
void syncClazyWidgets(const ClangDiagnosticConfig &config);
|
||||
void syncTidyChecksList(const ClangDiagnosticConfig &config);
|
||||
void syncTidyChecksToTree(const ClangDiagnosticConfig &config);
|
||||
|
||||
void updateConfig(const CppTools::ClangDiagnosticConfig &config);
|
||||
|
||||
@@ -115,6 +116,7 @@ private:
|
||||
|
||||
std::unique_ptr<CppTools::Ui::TidyChecks> m_tidyChecks;
|
||||
QWidget *m_tidyChecksWidget = nullptr;
|
||||
std::unique_ptr<TidyChecksTreeModel> m_tidyTreeModel;
|
||||
|
||||
int m_selectedConfigIndex = 0;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,20 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
@@ -40,10 +53,13 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
|
||||
@@ -565,10 +565,10 @@ QString clangIncludeDirectory(const QString &clangVersion, const QString &clangR
|
||||
QString clangExecutable(const QString &clangBinDirectory)
|
||||
{
|
||||
const QString hostExeSuffix(QTC_HOST_EXE_SUFFIX);
|
||||
QDir executable(creatorLibexecPath() + "/clang/bin/clang" + hostExeSuffix);
|
||||
QFileInfo executable(creatorLibexecPath() + "/clang/bin/clang" + hostExeSuffix);
|
||||
if (!executable.exists())
|
||||
executable = QDir(clangBinDirectory + "/clang" + hostExeSuffix);
|
||||
return QDir::toNativeSeparators(executable.canonicalPath());
|
||||
executable = QFileInfo(clangBinDirectory + "/clang" + hostExeSuffix);
|
||||
return QDir::toNativeSeparators(executable.canonicalFilePath());
|
||||
}
|
||||
|
||||
void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()
|
||||
|
||||
@@ -55,12 +55,9 @@ static QString clangDiagnosticConfigsArrayDisplayNameKey()
|
||||
static QString clangDiagnosticConfigsArrayWarningsKey()
|
||||
{ return QLatin1String("diagnosticOptions"); }
|
||||
|
||||
static QString clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey()
|
||||
static QString clangDiagnosticConfigsArrayClangTidyChecksKey()
|
||||
{ return QLatin1String("clangTidyChecks"); }
|
||||
|
||||
static QString clangDiagnosticConfigsArrayClangTidyChecksStringKey()
|
||||
{ return QLatin1String("clangTidyChecksString"); }
|
||||
|
||||
static QString clangDiagnosticConfigsArrayClangTidyModeKey()
|
||||
{ return QLatin1String("clangTidyMode"); }
|
||||
|
||||
@@ -96,10 +93,8 @@ static ClangDiagnosticConfigs customDiagnosticConfigsFromSettings(QSettings *s)
|
||||
config.setClangOptions(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList());
|
||||
config.setClangTidyMode(static_cast<ClangDiagnosticConfig::TidyMode>(
|
||||
s->value(clangDiagnosticConfigsArrayClangTidyModeKey()).toInt()));
|
||||
config.setClangTidyChecksPrefixes(
|
||||
s->value(clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey()).toString());
|
||||
config.setClangTidyChecksString(
|
||||
s->value(clangDiagnosticConfigsArrayClangTidyChecksStringKey()).toString());
|
||||
config.setClangTidyChecks(
|
||||
s->value(clangDiagnosticConfigsArrayClangTidyChecksKey()).toString());
|
||||
config.setClazyChecks(s->value(clangDiagnosticConfigsArrayClazyChecksKey()).toString());
|
||||
configs.append(config);
|
||||
}
|
||||
@@ -157,10 +152,8 @@ void CppCodeModelSettings::toSettings(QSettings *s)
|
||||
s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.clangOptions());
|
||||
s->setValue(clangDiagnosticConfigsArrayClangTidyModeKey(),
|
||||
static_cast<int>(config.clangTidyMode()));
|
||||
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksPrefixesKey(),
|
||||
config.clangTidyChecksPrefixes());
|
||||
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksStringKey(),
|
||||
config.clangTidyChecksString());
|
||||
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksKey(),
|
||||
config.clangTidyChecks());
|
||||
s->setValue(clangDiagnosticConfigsArrayClazyChecksKey(), config.clazyChecks());
|
||||
}
|
||||
s->endArray();
|
||||
|
||||
@@ -100,7 +100,8 @@ HEADERS += \
|
||||
cppsymbolinfo.h \
|
||||
cursorineditor.h \
|
||||
wrappablelineedit.h \
|
||||
usages.h
|
||||
usages.h \
|
||||
cpptools_clangtidychecks.h
|
||||
|
||||
SOURCES += \
|
||||
abstracteditorsupport.cpp \
|
||||
|
||||
@@ -155,6 +155,7 @@ Project {
|
||||
"cppsourceprocessor.cpp",
|
||||
"cppsourceprocessor.h",
|
||||
"cpptools.qrc",
|
||||
"cpptools_clangtidychecks.h",
|
||||
"cpptools_global.h",
|
||||
"cpptools_utils.h",
|
||||
"cpptoolsbridge.cpp",
|
||||
|
||||
664
src/plugins/cpptools/cpptools_clangtidychecks.h
Normal 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
|
||||
@@ -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_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("CppTools", "C++ Symbols");
|
||||
|
||||
|
||||
} // namespace Constants
|
||||
} // namespace CppTools
|
||||
|
||||
@@ -37,12 +37,7 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Select Clang-Tidy prefixes</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Provide Clang-Tidy checks string</string>
|
||||
<string>Select Checks</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
@@ -52,6 +47,13 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="plainTextEditButton">
|
||||
<property name="text">
|
||||
<string>Edit Checks as String...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
@@ -67,9 +69,6 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="checksString"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="checksListWrapper">
|
||||
<widget class="QWidget" name="checksPage">
|
||||
@@ -87,87 +86,16 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListWidget" name="checksPrefixesList">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>android-*</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>boost-*</string>
|
||||
</property>
|
||||
</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 class="QTreeView" name="checksPrefixesTree">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -186,19 +114,6 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</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>
|
||||
</widget>
|
||||
</widget>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/kitchooser.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <ssh/sshconnection.h>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
@@ -128,10 +128,10 @@ void StartRemoteDialog::validate()
|
||||
d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(valid);
|
||||
}
|
||||
|
||||
StandardRunnable StartRemoteDialog::runnable() const
|
||||
Runnable StartRemoteDialog::runnable() const
|
||||
{
|
||||
Kit *kit = d->kitChooser->currentKit();
|
||||
StandardRunnable r;
|
||||
Runnable r;
|
||||
r.device = DeviceKitInformation::device(kit);
|
||||
r.executable = d->executable->text();
|
||||
r.commandLineArguments = d->arguments->text();
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace ProjectExplorer { class StandardRunnable; }
|
||||
namespace ProjectExplorer { class Runnable; }
|
||||
|
||||
namespace Debugger {
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
explicit StartRemoteDialog(QWidget *parent = nullptr);
|
||||
~StartRemoteDialog() override;
|
||||
|
||||
ProjectExplorer::StandardRunnable runnable() const;
|
||||
ProjectExplorer::Runnable runnable() const;
|
||||
|
||||
private:
|
||||
void validate();
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
|
||||
#include <app/app_version.h>
|
||||
@@ -147,7 +146,7 @@ public:
|
||||
Id kitId;
|
||||
uint serverPort;
|
||||
QString serverAddress;
|
||||
StandardRunnable runnable;
|
||||
Runnable runnable;
|
||||
bool breakAtMain = false;
|
||||
QString serverStartScript;
|
||||
QString debugInfoLocation;
|
||||
@@ -424,7 +423,7 @@ void StartApplicationDialog::run(bool attachRemote)
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
StandardRunnable inferior = newParameters.runnable;
|
||||
Runnable inferior = newParameters.runnable;
|
||||
const QString inputAddress = dialog.d->channelOverrideEdit->text();
|
||||
if (!inputAddress.isEmpty())
|
||||
debugger->setRemoteChannel(inputAddress);
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
#include "debuggerprotocol.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <texteditor/textmark.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
@@ -82,7 +83,7 @@ public:
|
||||
DebuggerStartMode startMode = NoStartMode;
|
||||
DebuggerCloseMode closeMode = KillAtClose;
|
||||
|
||||
ProjectExplorer::StandardRunnable inferior;
|
||||
ProjectExplorer::Runnable inferior;
|
||||
QString displayName; // Used in the Snapshots view.
|
||||
Utils::ProcessHandle attachPID;
|
||||
QStringList solibSearchPath;
|
||||
@@ -133,7 +134,7 @@ public:
|
||||
bool breakOnMain = false;
|
||||
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 startMessage; // First status message shown.
|
||||
QString debugInfoLocation; // Gdb "set-debug-file-directory".
|
||||
@@ -143,7 +144,7 @@ public:
|
||||
ProjectExplorer::Abi toolChainAbi;
|
||||
|
||||
QString projectSourceDirectory;
|
||||
QStringList projectSourceFiles;
|
||||
Utils::FileNameList projectSourceFiles;
|
||||
|
||||
// Used by Script debugging
|
||||
QString interpreter;
|
||||
|
||||
@@ -254,9 +254,9 @@ const DebuggerItem *DebuggerKitInformation::debugger(const Kit *kit)
|
||||
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)) {
|
||||
runnable.executable = item->command().toString();
|
||||
runnable.workingDirectory = item->workingDirectory().toString();
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "debuggerconstants.h"
|
||||
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
namespace Debugger {
|
||||
class DebuggerItem;
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
void fix(ProjectExplorer::Kit *k) override;
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@@ -100,7 +100,6 @@
|
||||
#include <projectexplorer/projectexplorersettings.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
@@ -3000,11 +2999,8 @@ void DebuggerPluginPrivate::extensionsInitialized()
|
||||
|
||||
auto constraint = [](RunConfiguration *runConfig) {
|
||||
Runnable runnable = runConfig->runnable();
|
||||
if (runnable.is<StandardRunnable>()) {
|
||||
IDevice::ConstPtr device = runnable.as<StandardRunnable>().device;
|
||||
if (device && device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
|
||||
return true;
|
||||
}
|
||||
if (runnable.device && runnable.device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
|
||||
return true;
|
||||
|
||||
if (DeviceTypeKitInformation::deviceTypeId(runConfig->target()->kit())
|
||||
== ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE)
|
||||
@@ -3639,7 +3635,7 @@ void DebuggerUnitTests::testStateMachine()
|
||||
auto runControl = new RunControl(rc, ProjectExplorer::Constants::DEBUG_RUN_MODE);
|
||||
auto debugger = new DebuggerRunTool(runControl);
|
||||
|
||||
debugger->setInferior(rc->runnable().as<StandardRunnable>());
|
||||
debugger->setInferior(rc->runnable());
|
||||
debugger->setTestCase(TestNoBoundsOfCurrentFunction);
|
||||
|
||||
connect(debugger, &DebuggerRunTool::stopped,
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/projectexplorericons.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
#include <projectexplorer/runconfigurationaspects.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
@@ -93,7 +92,7 @@ class LocalProcessRunner : public RunWorker
|
||||
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::LocalProcessRunner)
|
||||
|
||||
public:
|
||||
LocalProcessRunner(RunControl *runControl, const StandardRunnable &runnable)
|
||||
LocalProcessRunner(RunControl *runControl, const Runnable &runnable)
|
||||
: RunWorker(runControl), m_runnable(runnable)
|
||||
{
|
||||
connect(&m_proc, &QProcess::errorOccurred,
|
||||
@@ -177,7 +176,7 @@ public:
|
||||
Core::AsynchronousMessageBox::critical(tr("Error"), msg);
|
||||
}
|
||||
|
||||
StandardRunnable m_runnable;
|
||||
Runnable m_runnable;
|
||||
Utils::QtcProcess m_proc;
|
||||
};
|
||||
|
||||
@@ -278,7 +277,7 @@ void DebuggerRunTool::setStartMode(DebuggerStartMode startMode)
|
||||
projects.insert(0, startupProject);
|
||||
}
|
||||
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())
|
||||
m_runParameters.projectSourceDirectory = projects.first()->projectDirectory().toString();
|
||||
|
||||
@@ -395,7 +394,7 @@ void DebuggerRunTool::setServerStartScript(const QString &serverStartScript)
|
||||
{
|
||||
if (!serverStartScript.isEmpty()) {
|
||||
// Provide script information about the environment
|
||||
StandardRunnable serverStarter;
|
||||
Runnable serverStarter;
|
||||
serverStarter.executable = serverStartScript;
|
||||
QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.inferior.executable);
|
||||
QtcProcess::addArg(&serverStarter.commandLineArguments, m_runParameters.remoteChannel);
|
||||
@@ -435,8 +434,7 @@ void DebuggerRunTool::setOverrideStartScript(const QString &script)
|
||||
|
||||
void DebuggerRunTool::setInferior(const Runnable &runnable)
|
||||
{
|
||||
QTC_ASSERT(runnable.is<StandardRunnable>(), reportFailure(); return);
|
||||
m_runParameters.inferior = runnable.as<StandardRunnable>();
|
||||
m_runParameters.inferior = runnable;
|
||||
setUseTerminal(m_runParameters.inferior.runMode == ApplicationLauncher::Console);
|
||||
}
|
||||
|
||||
@@ -852,14 +850,11 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
|
||||
if (m_runParameters.isCppDebugging)
|
||||
m_runParameters.cppEngineType = DebuggerKitInformation::engineType(kit);
|
||||
|
||||
Runnable r = runnable();
|
||||
if (r.is<StandardRunnable>()) {
|
||||
m_runParameters.inferior = r.as<StandardRunnable>();
|
||||
// Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...)
|
||||
m_runParameters.inferior.workingDirectory =
|
||||
FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory);
|
||||
setUseTerminal(allowTerminal && m_runParameters.inferior.runMode == ApplicationLauncher::Console);
|
||||
}
|
||||
m_runParameters.inferior = runnable();
|
||||
// Normalize to work around QTBUG-17529 (QtDeclarative fails with 'File name case mismatch'...)
|
||||
m_runParameters.inferior.workingDirectory =
|
||||
FileUtils::normalizePathName(m_runParameters.inferior.workingDirectory);
|
||||
setUseTerminal(allowTerminal && m_runParameters.inferior.runMode == ApplicationLauncher::Console);
|
||||
|
||||
const QByteArray envBinary = qgetenv("QTC_DEBUGGER_PATH");
|
||||
if (!envBinary.isEmpty())
|
||||
@@ -868,7 +863,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
|
||||
Project *project = runConfig ? runConfig->target()->project() : nullptr;
|
||||
if (project) {
|
||||
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);
|
||||
@@ -1005,8 +1000,7 @@ GdbServerRunner::GdbServerRunner(RunControl *runControl, GdbServerPortsGatherer
|
||||
: SimpleTargetRunner(runControl), m_portsGatherer(portsGatherer)
|
||||
{
|
||||
setDisplayName("GdbServerRunner");
|
||||
if (runControl->runnable().is<StandardRunnable>())
|
||||
m_runnable = runControl->runnable().as<StandardRunnable>();
|
||||
m_runnable = runControl->runnable();
|
||||
addStartDependency(m_portsGatherer);
|
||||
}
|
||||
|
||||
@@ -1014,7 +1008,7 @@ GdbServerRunner::~GdbServerRunner()
|
||||
{
|
||||
}
|
||||
|
||||
void GdbServerRunner::setRunnable(const StandardRunnable &runnable)
|
||||
void GdbServerRunner::setRunnable(const Runnable &runnable)
|
||||
{
|
||||
m_runnable = runnable;
|
||||
}
|
||||
@@ -1033,7 +1027,7 @@ void GdbServerRunner::start()
|
||||
{
|
||||
QTC_ASSERT(m_portsGatherer, reportFailure(); return);
|
||||
|
||||
StandardRunnable gdbserver;
|
||||
Runnable gdbserver;
|
||||
gdbserver.environment = m_runnable.environment;
|
||||
gdbserver.workingDirectory = m_runnable.workingDirectory;
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ public:
|
||||
|
||||
~GdbServerRunner() override;
|
||||
|
||||
void setRunnable(const ProjectExplorer::StandardRunnable &runnable);
|
||||
void setRunnable(const ProjectExplorer::Runnable &runnable);
|
||||
void setUseMulti(bool on);
|
||||
void setAttachPid(Utils::ProcessHandle pid);
|
||||
|
||||
@@ -189,7 +189,7 @@ private:
|
||||
void start() override;
|
||||
|
||||
GdbServerPortsGatherer *m_portsGatherer;
|
||||
ProjectExplorer::StandardRunnable m_runnable;
|
||||
ProjectExplorer::Runnable m_runnable;
|
||||
Utils::ProcessHandle m_pid;
|
||||
bool m_useMulti = true;
|
||||
};
|
||||
|
||||
@@ -696,7 +696,6 @@ void GdbEngine::interruptInferior()
|
||||
showStatusMessage(tr("Stop requested..."), 5000);
|
||||
showMessage("TRYING TO INTERRUPT INFERIOR");
|
||||
if (HostOsInfo::isWindowsHost() && !m_isQnxGdb) {
|
||||
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); notifyInferiorStopFailed());
|
||||
IDevice::ConstPtr device = runTool()->device();
|
||||
if (!device)
|
||||
device = runParameters().inferior.device;
|
||||
@@ -4832,7 +4831,7 @@ static QString findExecutableFromName(const QString &fileNameFromCore, const QSt
|
||||
return QString();
|
||||
}
|
||||
|
||||
CoreInfo CoreInfo::readExecutableNameFromCore(const StandardRunnable &debugger, const QString &coreFile)
|
||||
CoreInfo CoreInfo::readExecutableNameFromCore(const Runnable &debugger, const QString &coreFile)
|
||||
{
|
||||
CoreInfo cinfo;
|
||||
#if 0
|
||||
|
||||
@@ -61,7 +61,7 @@ struct CoreInfo
|
||||
QString foundExecutableName; // empty if no corresponding exec could be found
|
||||
bool isCore = false;
|
||||
|
||||
static CoreInfo readExecutableNameFromCore(const ProjectExplorer::StandardRunnable &debugger,
|
||||
static CoreInfo readExecutableNameFromCore(const ProjectExplorer::Runnable &debugger,
|
||||
const QString &coreFile);
|
||||
};
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ void AttachCoreDialog::coreFileChanged(const QString &core)
|
||||
if (!HostOsInfo::isWindowsHost() && QFile::exists(core)) {
|
||||
Kit *k = d->kitChooser->currentKit();
|
||||
QTC_ASSERT(k, return);
|
||||
StandardRunnable debugger = DebuggerKitInformation::runnable(k);
|
||||
Runnable debugger = DebuggerKitInformation::runnable(k);
|
||||
CoreInfo cinfo = CoreInfo::readExecutableNameFromCore(debugger, core);
|
||||
if (!cinfo.foundExecutableName.isEmpty())
|
||||
d->localExecFileName->setFileName(FileName::fromString(cinfo.foundExecutableName));
|
||||
|
||||
@@ -437,7 +437,8 @@ LogWindow::LogWindow(QWidget *parent)
|
||||
"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 "
|
||||
"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 "
|
||||
"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")
|
||||
|
||||
@@ -337,6 +337,7 @@ void QmlCppEngine::continueInferior()
|
||||
void QmlCppEngine::interruptInferior()
|
||||
{
|
||||
EDEBUG("\nMASTER INTERRUPT INFERIOR");
|
||||
m_activeEngine->setState(InferiorStopRequested);
|
||||
m_activeEngine->interruptInferior();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <projectexplorer/applicationlauncher.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
|
||||
#include <qmljseditor/qmljseditorconstants.h>
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
@@ -526,7 +525,7 @@ void QmlEngine::runEngine()
|
||||
void QmlEngine::startApplicationLauncher()
|
||||
{
|
||||
if (!d->applicationLauncher.isRunning()) {
|
||||
StandardRunnable runnable = runParameters().inferior;
|
||||
const Runnable runnable = runParameters().inferior;
|
||||
runTool()->appendMessage(tr("Starting %1 %2").arg(
|
||||
QDir::toNativeSeparators(runnable.executable),
|
||||
runnable.commandLineArguments),
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <QSocketNotifier>
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
|
||||
#include <utils/consoleprocess.h>
|
||||
|
||||
@@ -85,7 +84,7 @@ private:
|
||||
void stubError(const QString &msg);
|
||||
|
||||
Utils::ConsoleProcess m_stubProc;
|
||||
ProjectExplorer::StandardRunnable m_stubRunnable;
|
||||
ProjectExplorer::Runnable m_stubRunnable;
|
||||
qint64 m_applicationPid = 0;
|
||||
qint64 m_applicationMainThreadId = 0;
|
||||
};
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/buildconfiguration.h>
|
||||
#include <projectexplorer/runnables.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
@@ -116,11 +115,10 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent)
|
||||
if (activeTarget) {
|
||||
if (RunConfiguration *runConfig = activeTarget->activeRunConfiguration()) {
|
||||
const Runnable runnable = runConfig->runnable();
|
||||
if (runnable.is<StandardRunnable>() && isLocal(runConfig)) {
|
||||
if (isLocal(runConfig)) {
|
||||
resetExecutable->setEnabled(true);
|
||||
connect(resetExecutable, &QPushButton::clicked,
|
||||
this, [this, runnable]() {
|
||||
m_pathChooser->setPath(runnable.as<StandardRunnable>().executable);
|
||||
connect(resetExecutable, &QPushButton::clicked, this, [this, runnable] {
|
||||
m_pathChooser->setPath(runnable.executable);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -198,8 +196,8 @@ void UnstartedAppWatcherDialog::selectExecutable()
|
||||
if (activeTarget) {
|
||||
if (RunConfiguration *runConfig = activeTarget->activeRunConfiguration()) {
|
||||
const Runnable runnable = runConfig->runnable();
|
||||
if (runnable.is<StandardRunnable>() && isLocal(runConfig))
|
||||
path = QFileInfo(runnable.as<StandardRunnable>().executable).path();
|
||||
if (isLocal(runConfig))
|
||||
path = QFileInfo(runnable.executable).path();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ RemoteModel::RemoteModel(QObject *parent) : QAbstractTableModel(parent)
|
||||
|
||||
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
|
||||
|
||||
@@ -70,9 +70,7 @@ void HelpIndexFilter::prepareSearch(const QString &entry)
|
||||
{
|
||||
Q_UNUSED(entry)
|
||||
QStringList namespaces = HelpManager::registeredNamespaces();
|
||||
m_helpDatabases = Utils::transform(namespaces, [](const QString &ns) {
|
||||
return HelpManager::fileFromNamespace(ns);
|
||||
});
|
||||
m_helpDatabases = Utils::transform(namespaces, &HelpManager::fileFromNamespace);
|
||||
}
|
||||
|
||||
QList<LocatorFilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &entry)
|
||||
|
||||