Merge "Merge remote-tracking branch 'origin/4.9'"
38
README.md
@@ -287,6 +287,44 @@ http://llvm.org/docs/GettingStarted.html#git-mirror:
|
||||
Qt Creator includes the following third-party components,
|
||||
we thank the authors who made this possible:
|
||||
|
||||
### KSyntaxHighlighting
|
||||
|
||||
Syntax highlighting engine for Kate syntax definitions
|
||||
|
||||
This is a stand-alone implementation of the Kate syntax highlighting
|
||||
engine. It's meant as a building block for text editors as well as
|
||||
for simple highlighted text rendering (e.g. as HTML), supporting both
|
||||
integration with a custom editor as well as a ready-to-use
|
||||
QSyntaxHighlighter sub-class.
|
||||
|
||||
Distributed under the:
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
The source code of KSyntaxHighlighting can be found here:
|
||||
https://cgit.kde.org/syntax-highlighting.git
|
||||
QtCreator/src/libs/3rdparty/syntax-highlighting
|
||||
https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/syntax-highlighting
|
||||
|
||||
### Clazy
|
||||
|
||||
https://github.com/KDE/clazy
|
||||
|
240
dist/changes-4.9.0.md
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
Qt Creator version 4.9 contains bug fixes and new features.
|
||||
|
||||
The most important changes are listed in this document. For a complete
|
||||
list of changes, see the Git log for the Qt Creator sources that
|
||||
you can check out from the public Git repository. For example:
|
||||
|
||||
git clone git://code.qt.io/qt-creator/qt-creator.git
|
||||
git log --cherry-pick --pretty=oneline origin/4.8..v4.9.0
|
||||
|
||||
General
|
||||
|
||||
* Added high-level introduction to Qt Creator's UI for first-time users
|
||||
(QTCREATORBUG-21585)
|
||||
* Added option to run external tools in build or run environment of
|
||||
active project (QTCREATORBUG-18394, QTCREATORBUG-19892)
|
||||
* Improved selection colors in dark themes (QTCREATORBUG-18888)
|
||||
|
||||
Editing
|
||||
|
||||
* Language Client
|
||||
* Added support for document outline (QTCREATORBUG-21573)
|
||||
* Added support for `Find Usages` (QTCREATORBUG-21577)
|
||||
* Added support for code actions
|
||||
* Highlighter
|
||||
* Replaced custom highlighting file parser with `KSyntaxHighlighting`
|
||||
(QTCREATORBUG-21029)
|
||||
* Made it possible to filter bookmarks by line and text content in Locator
|
||||
(QTCREATORBUG-21771)
|
||||
* Fixed document sort order after rename (QTCREATORBUG-21565)
|
||||
|
||||
Help
|
||||
|
||||
* Improved context help in case of code errors or diagnostics
|
||||
(QTCREATORBUG-15959, QTCREATORBUG-21686)
|
||||
* Improved lookup performance for context help
|
||||
|
||||
All Projects
|
||||
|
||||
* Added `Expand All` to context menu (QTCREATORBUG-17243)
|
||||
* Added `Close All Files in Project` action (QTCREATORBUG-15593)
|
||||
* Added closing of all files of a project when project is closed
|
||||
(QTCREATORBUG-15721)
|
||||
* Added display of command line parameters to `Application Output`
|
||||
(QTCREATORBUG-20577)
|
||||
* Fixed that dragging file from `Projects` view to desktop moved the file
|
||||
(QTCREATORBUG-14494)
|
||||
|
||||
QMake Projects
|
||||
|
||||
* Fixed that adding files did not respect alphabetic sorting and indentation
|
||||
with tabs (QTCREATORBUG-553, QTCREATORBUG-21807)
|
||||
* Fixed updating of `LD_LIBRARY_PATH` environment variable (QTCREATORBUG-21475)
|
||||
* Fixed updating of project tree in case of wildcards in corresponding QMake
|
||||
variable (QTCREATORBUG-21603)
|
||||
|
||||
CMake Projects
|
||||
|
||||
* Fixed that default build directory names contained spaces (QTCREATORBUG-18442)
|
||||
* Fixed that build targets were reset on CMake parse error (QTCREATORBUG-21617)
|
||||
* Fixed scroll behavior when adding configuration item
|
||||
|
||||
Qbs Projects
|
||||
|
||||
* Fixed crash when switching kits (QTCREATORBUG-21544)
|
||||
|
||||
Generic Projects
|
||||
|
||||
* Added deployment via `QtCreatorDeployment.txt` file (QTCREATORBUG-19202)
|
||||
* Added setting C/C++ flags for the code model via `.cflags` and `.cxxflags`
|
||||
files (QTCREATORBUG-19668)
|
||||
* Fixed `Apply Filter` when editing file list (QTCREATORBUG-16237)
|
||||
|
||||
C++ Support
|
||||
|
||||
* Added code snippet for range-based `for` loops
|
||||
* Added option to synchronize `Include Hierarchy` with current document
|
||||
(QTCREATORBUG-12022)
|
||||
* Clang Code Model
|
||||
* Added buttons for copying and ignoring diagnostics to tooltip
|
||||
* Fixed issue with high memory consumption (QTCREATORBUG-19543)
|
||||
* Clang Format
|
||||
* Added option to format code instead of only indenting code
|
||||
|
||||
QML Support
|
||||
|
||||
* Updated to parser from Qt 5.12, adding support for ECMAScript 7
|
||||
(QTCREATORBUG-20341, QTCREATORBUG-21301)
|
||||
* Improved error handling in Qt Quick Application project template (QTBUG-39469)
|
||||
* Fixed crash on `Find Usages`
|
||||
|
||||
Python
|
||||
|
||||
* Added project templates for Qt for Python
|
||||
|
||||
Nim Support
|
||||
|
||||
* Added code completion based on `NimSuggest`
|
||||
|
||||
Debugging
|
||||
|
||||
* GDB
|
||||
* Added support for rvalue references in function arguments
|
||||
* LLDB
|
||||
* Fixed `Source Paths Mappings` functionality (QTCREATORBUG-17468)
|
||||
|
||||
Clang Analyzer Tools
|
||||
|
||||
* Made Clazy configuration options more fine grained (QTCREATORBUG-21120)
|
||||
* Improved Fix-its handling in case of selecting multiple diagnostics and
|
||||
after editing files
|
||||
* Added diagnostics from header files (QTCREATORBUG-21452)
|
||||
* Added sorting to result list (QTCREATORBUG-20660)
|
||||
* Fixed that files were analyzed that are not part of current build
|
||||
configuration (QTCREATORBUG-16016)
|
||||
|
||||
Perf Profiler
|
||||
|
||||
* Made Perf profiler integration opensource
|
||||
|
||||
Qt Quick Designer
|
||||
|
||||
* Made QML Live Preview integration opensource
|
||||
|
||||
Version Control Systems
|
||||
|
||||
* Git
|
||||
* Improved messages when submit editor validation fails and when editor
|
||||
is closed
|
||||
* Added `Subversion` > `DCommit`
|
||||
* `Branches` View
|
||||
* Added `Push` action
|
||||
* Added entry for detached `HEAD` (QTCREATORBUG-21311)
|
||||
* Added tracking of external changes to `HEAD` (QTCREATORBUG-21089)
|
||||
* Subversion
|
||||
* Improved handling of commit errors (QTCREATORBUG-15227)
|
||||
* Perforce
|
||||
* Disabled by default
|
||||
* Fixed issue with setting P4 environment variables (QTCREATORBUG-21573)
|
||||
* Mercurial
|
||||
* Added side-by-side diff viewer (QTCREATORBUG-21124)
|
||||
|
||||
Test Integration
|
||||
|
||||
* Added `Uncheck All Filters`
|
||||
* Added grouping results by application (QTCREATORBUG-21740)
|
||||
* QTest
|
||||
* Added support for `BXPASS` and `BXFAIL`
|
||||
* Fixed parsing of `BFAIL` and `BPASS`
|
||||
|
||||
FakeVim
|
||||
|
||||
* Added option for blinking cursor (QTCREATORBUG-21613)
|
||||
* Added closing completion popups with `Ctrl+[` (QTCREATORBUG-21886)
|
||||
|
||||
Model Editor
|
||||
|
||||
* Added display of base class names
|
||||
|
||||
Serial Terminal
|
||||
|
||||
* Improved error message on connection failure
|
||||
|
||||
Platform Specific
|
||||
|
||||
Windows
|
||||
|
||||
* Added support for MSVC 2019
|
||||
* Changed toolchain detection to use `vswhere` by default, which is recommended
|
||||
by Microsoft
|
||||
|
||||
Linux
|
||||
|
||||
macOS
|
||||
|
||||
* Added support for Touch Bar (QTCREATORBUG-21263)
|
||||
|
||||
Android
|
||||
|
||||
* Removed separate `QmakeAndroidSupport` plugin and merged functionality into
|
||||
other plugins
|
||||
|
||||
Remote Linux
|
||||
|
||||
* Removed use of Botan, exchanging it by use of separately installed OpenSSH
|
||||
tools (QTCREATORBUG-15744, QTCREATORBUG-15807, QTCREATORBUG-19306,
|
||||
QTCREATORBUG-20210)
|
||||
* Added support for `ssh-askpass`
|
||||
* Added optional deployment of public key for authentication to device setup
|
||||
wizard
|
||||
* Added support for X11 forwarding
|
||||
* Added `rsync` based deployment method
|
||||
* Added support for `Run in Terminal`
|
||||
* Added support for opening a remote terminal from device settings
|
||||
* Fixed incremental deployment when target directory is changed
|
||||
(QTCREATORBUG-21225)
|
||||
* Fixed issue with killing remote process (QTCREATORBUG-19941)
|
||||
|
||||
Credits for these changes go to:
|
||||
Aaron Barany
|
||||
Alessandro Portale
|
||||
Andre Hartmann
|
||||
André Pönitz
|
||||
Asit Dhal
|
||||
Bernhard Beschow
|
||||
Chris Rizzitello
|
||||
Christian Kandeler
|
||||
Christian Stenger
|
||||
Cristian Adam
|
||||
Cristian Maureira-Fredes
|
||||
Daniel Wingerd
|
||||
David Schulz
|
||||
Eike Ziller
|
||||
Filip Bucek
|
||||
Filippo Cucchetto
|
||||
Frank Meerkoetter
|
||||
Friedemann Kleint
|
||||
Ivan Donchevskii
|
||||
James McDonnell
|
||||
Jochen Becher
|
||||
Kai Köhne
|
||||
Leena Miettinen
|
||||
Marco Benelli
|
||||
Marco Bubke
|
||||
Michael Kopp
|
||||
Michael Weghorn
|
||||
Miklós Márton
|
||||
Mitch Curtis
|
||||
Nikolai Kosjar
|
||||
Oliver Wolff
|
||||
Orgad Shaneh
|
||||
Przemyslaw Gorszkowski
|
||||
Robert Löhning
|
||||
Thiago Macieira
|
||||
Thomas Hartmann
|
||||
Tim Jenssen
|
||||
Tobias Hunger
|
||||
Ulf Hermann
|
||||
Vikas Pachdha
|
||||
Ville Nummela
|
||||
Xiaofeng Wang
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 4.3 KiB |
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
@@ -90,6 +90,39 @@
|
||||
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/syntax-highlighting}
|
||||
\endlist
|
||||
|
||||
\li \b{Clazy}
|
||||
|
||||
\l {https://github.com/KDE/clazy}
|
||||
|
||||
Copyright (C) 2015-2019 Clazy Team
|
||||
|
||||
Distributed under the \l {https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html}
|
||||
{GNU LIBRARY GENERAL PUBLIC LICENSE Version 2 (LGPL2)}.
|
||||
|
||||
Integrated with patches from
|
||||
\list
|
||||
\li \l{http://code.qt.io/cgit/clang/clang-tools-extra.git}
|
||||
\endlist
|
||||
|
||||
\li \b{LLVM/Clang}
|
||||
|
||||
\list
|
||||
\li \l{http://llvm.org/svn/llvm-project/llvm}
|
||||
\li \l{http://llvm.org/svn/llvm-project/cfe/trunk}
|
||||
\li \l{http://llvm.org/svn/llvm-project/clang-tools-extra/trunk}
|
||||
\endlist
|
||||
|
||||
Copyright (C) 2003-2019 LLVM Team
|
||||
|
||||
Distributed under the \l {https://github.com/llvm-mirror/llvm/blob/master/LICENSE.TXT}
|
||||
{University of Illinois/NCSA Open Source License (NCSA)}.
|
||||
|
||||
With backported/additional patches from
|
||||
\list
|
||||
\li \l{http://code.qt.io/cgit/clang/llvm.git}
|
||||
\li \l{http://code.qt.io/cgit/clang/clang.git}
|
||||
\endlist
|
||||
|
||||
\li \b{Reference implementation for std::experimental::optional}
|
||||
|
||||
Copyright (C) 2011-2012 Andrzej Krzemienski
|
||||
|
@@ -19,6 +19,7 @@ Module {
|
||||
exports: [ "qbs/Depends 1.0" ]
|
||||
prototype: "QQuickItem"
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "enableFallback"; type: "bool" }
|
||||
Property { name: "limitToSubProject"; type: "bool" }
|
||||
Property { name: "multiplexConfigurationIds"; type: "string"; isList: true }
|
||||
Property { name: "name"; type: "string" }
|
||||
@@ -66,6 +67,14 @@ Module {
|
||||
Property { name: "overrideTags"; type: "bool" }
|
||||
Property { name: "prefix"; type: "string" }
|
||||
}
|
||||
Component {
|
||||
name: "JobLimit"
|
||||
exports: [ "qbs/JobLimit 1.0" ]
|
||||
prototype: "QQuickItem"
|
||||
Property { name: "condition"; type: "bool" }
|
||||
Property { name: "jobCount"; type: "int" }
|
||||
Property { name: "jobPool"; type: "string" }
|
||||
}
|
||||
Component {
|
||||
name: "Module"
|
||||
exports: [ "qbs/Module 1.0" ]
|
||||
@@ -80,6 +89,14 @@ Module {
|
||||
Property { name: "validate"; type: "bool" }
|
||||
Property { name: "version"; type: "string" }
|
||||
}
|
||||
Component {
|
||||
name: "ModuleProvider"
|
||||
exports: [ "qbs/ModuleProvider 1.0" ]
|
||||
prototype: "QQuickItem"
|
||||
Property { name: "name"; type: "string" }
|
||||
Property { name: "outputBaseDir"; type: "string" }
|
||||
Property { name: "relativeSearchPaths"; type: "string"; isList: true }
|
||||
}
|
||||
Component {
|
||||
name: "Parameter"
|
||||
exports: [ "qbs/Parameter 1.0" ]
|
||||
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 126 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 527 B After Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 515 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 790 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 790 B |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 55 KiB |
2901
src/libs/3rdparty/syntax-highlighting/patches/0002-Remove-autotests.patch
vendored
Normal file
@@ -0,0 +1,389 @@
|
||||
From c9f4bdaa0902c0fdb5ea750d11935e15777a090d Mon Sep 17 00:00:00 2001
|
||||
From: Alessandro Portale <alessandro.portale@qt.io>
|
||||
Date: Tue, 12 Feb 2019 19:45:08 +0100
|
||||
Subject: [PATCH 3/6] Add qmake/Qbs files and files generated by CMake
|
||||
|
||||
---
|
||||
autogenerated/autogenerated.pri | 9 ++
|
||||
autogenerated/ksyntaxhighlighting_version.h | 12 +++
|
||||
autogenerated/src/lib/AbstractHighlighter | 1 +
|
||||
autogenerated/src/lib/Definition | 1 +
|
||||
autogenerated/src/lib/FoldingRegion | 1 +
|
||||
autogenerated/src/lib/Format | 1 +
|
||||
autogenerated/src/lib/Repository | 1 +
|
||||
autogenerated/src/lib/State | 1 +
|
||||
autogenerated/src/lib/SyntaxHighlighter | 1 +
|
||||
autogenerated/src/lib/Theme | 1 +
|
||||
.../src/lib/ksyntaxhighlighting_logging.cpp | 11 +++
|
||||
.../src/lib/ksyntaxhighlighting_logging.h | 11 +++
|
||||
data/data.pro | 11 +++
|
||||
src/lib/ksyntaxhighlighting_export.h | 34 +++++++
|
||||
syntax-highlighting.pro | 55 ++++++++++++
|
||||
syntax-highlighting.qbs | 88 +++++++++++++++++++
|
||||
syntax-highlighting_dependencies.pri | 3 +
|
||||
17 files changed, 242 insertions(+)
|
||||
create mode 100644 autogenerated/autogenerated.pri
|
||||
create mode 100644 autogenerated/ksyntaxhighlighting_version.h
|
||||
create mode 100644 autogenerated/src/lib/AbstractHighlighter
|
||||
create mode 100644 autogenerated/src/lib/Definition
|
||||
create mode 100644 autogenerated/src/lib/FoldingRegion
|
||||
create mode 100644 autogenerated/src/lib/Format
|
||||
create mode 100644 autogenerated/src/lib/Repository
|
||||
create mode 100644 autogenerated/src/lib/State
|
||||
create mode 100644 autogenerated/src/lib/SyntaxHighlighter
|
||||
create mode 100644 autogenerated/src/lib/Theme
|
||||
create mode 100644 autogenerated/src/lib/ksyntaxhighlighting_logging.cpp
|
||||
create mode 100644 autogenerated/src/lib/ksyntaxhighlighting_logging.h
|
||||
create mode 100644 data/data.pro
|
||||
create mode 100644 src/lib/ksyntaxhighlighting_export.h
|
||||
create mode 100644 syntax-highlighting.pro
|
||||
create mode 100644 syntax-highlighting.qbs
|
||||
create mode 100644 syntax-highlighting_dependencies.pri
|
||||
|
||||
diff --git a/autogenerated/autogenerated.pri b/autogenerated/autogenerated.pri
|
||||
new file mode 100644
|
||||
index 0000000..aee620a
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/autogenerated.pri
|
||||
@@ -0,0 +1,9 @@
|
||||
+INCLUDEPATH *= $$PWD/src/lib
|
||||
+INCLUDEPATH *= $$PWD
|
||||
+
|
||||
+SOURCES += \
|
||||
+ $$PWD/src/lib/ksyntaxhighlighting_logging.cpp
|
||||
+
|
||||
+HEADERS += \
|
||||
+ $$PWD/ksyntaxhighlighting_version.h \
|
||||
+ $$PWD/src/lib/ksyntaxhighlighting_logging.h
|
||||
diff --git a/autogenerated/ksyntaxhighlighting_version.h b/autogenerated/ksyntaxhighlighting_version.h
|
||||
new file mode 100644
|
||||
index 0000000..bd31a4d
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/ksyntaxhighlighting_version.h
|
||||
@@ -0,0 +1,12 @@
|
||||
+// This file was generated by ecm_setup_version(): DO NOT EDIT!
|
||||
+
|
||||
+#ifndef SyntaxHighlighting_VERSION_H
|
||||
+#define SyntaxHighlighting_VERSION_H
|
||||
+
|
||||
+#define SyntaxHighlighting_VERSION_STRING "5.52.0"
|
||||
+#define SyntaxHighlighting_VERSION_MAJOR 5
|
||||
+#define SyntaxHighlighting_VERSION_MINOR 52
|
||||
+#define SyntaxHighlighting_VERSION_PATCH 0
|
||||
+#define SyntaxHighlighting_VERSION ((5<<16)|(52<<8)|(0))
|
||||
+
|
||||
+#endif
|
||||
diff --git a/autogenerated/src/lib/AbstractHighlighter b/autogenerated/src/lib/AbstractHighlighter
|
||||
new file mode 100644
|
||||
index 0000000..b787873
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/AbstractHighlighter
|
||||
@@ -0,0 +1 @@
|
||||
+#include "abstracthighlighter.h"
|
||||
diff --git a/autogenerated/src/lib/Definition b/autogenerated/src/lib/Definition
|
||||
new file mode 100644
|
||||
index 0000000..2c3241f
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/Definition
|
||||
@@ -0,0 +1 @@
|
||||
+#include "definition.h"
|
||||
diff --git a/autogenerated/src/lib/FoldingRegion b/autogenerated/src/lib/FoldingRegion
|
||||
new file mode 100644
|
||||
index 0000000..005b829
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/FoldingRegion
|
||||
@@ -0,0 +1 @@
|
||||
+#include "foldingregion.h"
|
||||
diff --git a/autogenerated/src/lib/Format b/autogenerated/src/lib/Format
|
||||
new file mode 100644
|
||||
index 0000000..b0d6a10
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/Format
|
||||
@@ -0,0 +1 @@
|
||||
+#include "format.h"
|
||||
diff --git a/autogenerated/src/lib/Repository b/autogenerated/src/lib/Repository
|
||||
new file mode 100644
|
||||
index 0000000..189dbc2
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/Repository
|
||||
@@ -0,0 +1 @@
|
||||
+#include "repository.h"
|
||||
diff --git a/autogenerated/src/lib/State b/autogenerated/src/lib/State
|
||||
new file mode 100644
|
||||
index 0000000..e148d70
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/State
|
||||
@@ -0,0 +1 @@
|
||||
+#include "state.h"
|
||||
diff --git a/autogenerated/src/lib/SyntaxHighlighter b/autogenerated/src/lib/SyntaxHighlighter
|
||||
new file mode 100644
|
||||
index 0000000..b429824
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/SyntaxHighlighter
|
||||
@@ -0,0 +1 @@
|
||||
+#include "syntaxhighlighter.h"
|
||||
diff --git a/autogenerated/src/lib/Theme b/autogenerated/src/lib/Theme
|
||||
new file mode 100644
|
||||
index 0000000..34a3e98
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/Theme
|
||||
@@ -0,0 +1 @@
|
||||
+#include "theme.h"
|
||||
diff --git a/autogenerated/src/lib/ksyntaxhighlighting_logging.cpp b/autogenerated/src/lib/ksyntaxhighlighting_logging.cpp
|
||||
new file mode 100644
|
||||
index 0000000..4082ac4
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/ksyntaxhighlighting_logging.cpp
|
||||
@@ -0,0 +1,11 @@
|
||||
+// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT!
|
||||
+
|
||||
+#include "ksyntaxhighlighting_logging.h"
|
||||
+
|
||||
+ namespace KSyntaxHighlighting {
|
||||
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
|
||||
+Q_LOGGING_CATEGORY(Log, "org.kde.ksyntaxhighlighting", QtInfoMsg)
|
||||
+#else
|
||||
+Q_LOGGING_CATEGORY(Log, "org.kde.ksyntaxhighlighting")
|
||||
+#endif
|
||||
+}
|
||||
diff --git a/autogenerated/src/lib/ksyntaxhighlighting_logging.h b/autogenerated/src/lib/ksyntaxhighlighting_logging.h
|
||||
new file mode 100644
|
||||
index 0000000..c351b2c
|
||||
--- /dev/null
|
||||
+++ b/autogenerated/src/lib/ksyntaxhighlighting_logging.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT!
|
||||
+
|
||||
+#ifndef ECM_QLOGGINGCATEGORY_KSYNTAXHIGHLIGHTING_LOG_KSYNTAXHIGHLIGHTING_LOGGING_H
|
||||
+#define ECM_QLOGGINGCATEGORY_KSYNTAXHIGHLIGHTING_LOG_KSYNTAXHIGHLIGHTING_LOGGING_H
|
||||
+
|
||||
+#include <QLoggingCategory>
|
||||
+ namespace KSyntaxHighlighting {
|
||||
+Q_DECLARE_LOGGING_CATEGORY(Log)
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
diff --git a/data/data.pro b/data/data.pro
|
||||
new file mode 100644
|
||||
index 0000000..1028ea1
|
||||
--- /dev/null
|
||||
+++ b/data/data.pro
|
||||
@@ -0,0 +1,11 @@
|
||||
+TEMPLATE = aux
|
||||
+
|
||||
+include(../../../../../qtcreator.pri)
|
||||
+
|
||||
+STATIC_BASE = $$PWD
|
||||
+STATIC_OUTPUT_BASE = $$IDE_DATA_PATH/generic-highlighter
|
||||
+STATIC_INSTALL_BASE = $$INSTALL_DATA_PATH/generic-highlighter
|
||||
+
|
||||
+STATIC_FILES += $$files($$PWD/syntax/*, true)
|
||||
+
|
||||
+include(../../../../../qtcreatordata.pri)
|
||||
diff --git a/src/lib/ksyntaxhighlighting_export.h b/src/lib/ksyntaxhighlighting_export.h
|
||||
new file mode 100644
|
||||
index 0000000..a39adb5
|
||||
--- /dev/null
|
||||
+++ b/src/lib/ksyntaxhighlighting_export.h
|
||||
@@ -0,0 +1,34 @@
|
||||
+/****************************************************************************
|
||||
+**
|
||||
+** 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 <QtGlobal>
|
||||
+
|
||||
+#if defined(KSYNTAXHIGHLIGHTING_LIBRARY)
|
||||
+# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_EXPORT
|
||||
+#else
|
||||
+# define KSYNTAXHIGHLIGHTING_EXPORT Q_DECL_IMPORT
|
||||
+#endif
|
||||
diff --git a/syntax-highlighting.pro b/syntax-highlighting.pro
|
||||
new file mode 100644
|
||||
index 0000000..38127e1
|
||||
--- /dev/null
|
||||
+++ b/syntax-highlighting.pro
|
||||
@@ -0,0 +1,55 @@
|
||||
+include(../../../qtcreatorlibrary.pri)
|
||||
+include(autogenerated/autogenerated.pri)
|
||||
+
|
||||
+QT += network
|
||||
+
|
||||
+DEFINES += KSYNTAXHIGHLIGHTING_LIBRARY
|
||||
+
|
||||
+RESOURCES += \
|
||||
+ data/themes/theme-data.qrc
|
||||
+
|
||||
+HEADERS += \
|
||||
+ src/lib/abstracthighlighter.h \
|
||||
+ src/lib/abstracthighlighter_p.h \
|
||||
+ src/lib/context_p.h \
|
||||
+ src/lib/contextswitch_p.h \
|
||||
+ src/lib/definition.h \
|
||||
+ src/lib/definition_p.h \
|
||||
+ src/lib/definitiondownloader.h \
|
||||
+ src/lib/definitionref_p.h \
|
||||
+ src/lib/foldingregion.h \
|
||||
+ src/lib/format.h \
|
||||
+ src/lib/format_p.h \
|
||||
+ src/lib/htmlhighlighter.h \
|
||||
+ src/lib/keywordlist_p.h \
|
||||
+ src/lib/ksyntaxhighlighting_export.h \
|
||||
+ src/lib/matchresult_p.h \
|
||||
+ src/lib/repository.h \
|
||||
+ src/lib/repository_p.h \
|
||||
+ src/lib/rule_p.h \
|
||||
+ src/lib/state.h \
|
||||
+ src/lib/state_p.h \
|
||||
+ src/lib/syntaxhighlighter.h \
|
||||
+ src/lib/textstyledata_p.h \
|
||||
+ src/lib/theme.h \
|
||||
+ src/lib/themedata_p.h \
|
||||
+ src/lib/wildcardmatcher_p.h \
|
||||
+ src/lib/xml_p.h \
|
||||
+
|
||||
+SOURCES += \
|
||||
+ src/lib/abstracthighlighter.cpp \
|
||||
+ src/lib/context.cpp \
|
||||
+ src/lib/contextswitch.cpp \
|
||||
+ src/lib/definition.cpp \
|
||||
+ src/lib/definitiondownloader.cpp \
|
||||
+ src/lib/foldingregion.cpp \
|
||||
+ src/lib/format.cpp \
|
||||
+ src/lib/htmlhighlighter.cpp \
|
||||
+ src/lib/keywordlist.cpp \
|
||||
+ src/lib/repository.cpp \
|
||||
+ src/lib/rule.cpp \
|
||||
+ src/lib/state.cpp \
|
||||
+ src/lib/syntaxhighlighter.cpp \
|
||||
+ src/lib/theme.cpp \
|
||||
+ src/lib/themedata.cpp \
|
||||
+ src/lib/wildcardmatcher.cpp \
|
||||
diff --git a/syntax-highlighting.qbs b/syntax-highlighting.qbs
|
||||
new file mode 100644
|
||||
index 0000000..248ebe0
|
||||
--- /dev/null
|
||||
+++ b/syntax-highlighting.qbs
|
||||
@@ -0,0 +1,88 @@
|
||||
+import qbs 1.0
|
||||
+import qbs.File
|
||||
+import qbs.FileInfo
|
||||
+import qbs.Environment
|
||||
+
|
||||
+Project {
|
||||
+ QtcDevHeaders {
|
||||
+ productName: "syntax-highlighting (3rd party)"
|
||||
+ baseDir: sourceDirectory + "/src/lib"
|
||||
+ }
|
||||
+ QtcDevHeaders {
|
||||
+ productName: "syntax-highlighting autogenerated (3rd party)"
|
||||
+ baseDir: sourceDirectory + "/autogenerated/src/lib"
|
||||
+ Group {
|
||||
+ prefix: baseDir + '/'
|
||||
+ files: [
|
||||
+ "AbstractHighlighter",
|
||||
+ "Definition",
|
||||
+ "FoldingRegion",
|
||||
+ "Format",
|
||||
+ "Repository",
|
||||
+ "State",
|
||||
+ "SyntaxHighlighter",
|
||||
+ "Theme"
|
||||
+ ]
|
||||
+ qbs.install: true
|
||||
+ qbs.installDir: qtc.ide_include_path + '/' + FileInfo.fileName(product.sourceDirectory)
|
||||
+ qbs.installSourceBase: baseDir
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ QtcLibrary {
|
||||
+ name: "KSyntaxHighlighting"
|
||||
+
|
||||
+ cpp.defines: base.concat("KSYNTAXHIGHLIGHTING_LIBRARY")
|
||||
+ cpp.includePaths: [
|
||||
+ product.sourceDirectory + "/src/lib/",
|
||||
+ product.sourceDirectory + "/autogenerated/src/lib/",
|
||||
+ product.sourceDirectory + "/autogenerated/"
|
||||
+ ]
|
||||
+
|
||||
+ Depends { name: "Qt.gui" }
|
||||
+ Depends { name: "Qt.network" }
|
||||
+
|
||||
+ Group {
|
||||
+ name: "lib"
|
||||
+ prefix: "src/lib/"
|
||||
+ files: [
|
||||
+ "*.h",
|
||||
+ "*.cpp"
|
||||
+ ]
|
||||
+ }
|
||||
+
|
||||
+ Group {
|
||||
+ name: "KSyntaxHighlighting data"
|
||||
+ qbs.install: true
|
||||
+ qbs.installDir: qtc.ide_data_path + "/generic-highlighter/"
|
||||
+ qbs.installSourceBase: project.ide_source_tree + "/src/libs/3rdparty/syntax-highlighting/data/"
|
||||
+ prefix: project.ide_source_tree + "/src/libs/3rdparty/syntax-highlighting/data/"
|
||||
+ files: [
|
||||
+ "syntax/**/*"
|
||||
+ ]
|
||||
+ }
|
||||
+
|
||||
+ Group {
|
||||
+ name: "autogenerated lib"
|
||||
+ prefix: "autogenerated/src/lib/"
|
||||
+ files: [
|
||||
+ "*.h",
|
||||
+ "*.cpp"
|
||||
+ ]
|
||||
+ }
|
||||
+
|
||||
+ Group {
|
||||
+ name: "theme data"
|
||||
+ prefix: "data/themes/"
|
||||
+ files: [ "theme-data.qrc" ]
|
||||
+ }
|
||||
+
|
||||
+ Export {
|
||||
+ Depends { name: "cpp" }
|
||||
+ cpp.includePaths: [
|
||||
+ product.sourceDirectory + "/src/lib/",
|
||||
+ product.sourceDirectory + "/autogenerated/src/lib/",
|
||||
+ ]
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/syntax-highlighting_dependencies.pri b/syntax-highlighting_dependencies.pri
|
||||
new file mode 100644
|
||||
index 0000000..f2fd3e6
|
||||
--- /dev/null
|
||||
+++ b/syntax-highlighting_dependencies.pri
|
||||
@@ -0,0 +1,3 @@
|
||||
+QTC_LIB_NAME = KSyntaxHighlighting
|
||||
+INCLUDEPATH *= $$PWD/src/lib
|
||||
+INCLUDEPATH *= $$PWD/autogenerated/src/lib
|
||||
--
|
||||
2.20.1.windows.1
|
||||
|
281
src/libs/3rdparty/syntax-highlighting/patches/0004-Compile-with-namespaced-Qt.patch
vendored
Normal file
@@ -0,0 +1,281 @@
|
||||
From 916af0204a45c91092e53241e6a867cadb9dedec Mon Sep 17 00:00:00 2001
|
||||
From: Alessandro Portale <alessandro.portale@qt.io>
|
||||
Date: Tue, 12 Feb 2019 19:21:57 +0100
|
||||
Subject: [PATCH 4/6] Compile with namespaced Qt
|
||||
|
||||
---
|
||||
src/lib/abstracthighlighter.h | 4 ++++
|
||||
src/lib/abstracthighlighter_p.h | 2 ++
|
||||
src/lib/context_p.h | 2 ++
|
||||
src/lib/definition.h | 4 ++++
|
||||
src/lib/foldingregion.h | 2 ++
|
||||
src/lib/format.h | 5 ++++-
|
||||
src/lib/htmlhighlighter.h | 2 ++
|
||||
src/lib/keywordlist_p.h | 2 ++
|
||||
src/lib/repository.h | 2 ++
|
||||
src/lib/repository_p.h | 2 ++
|
||||
src/lib/rule_p.h | 2 ++
|
||||
src/lib/state.h | 2 ++
|
||||
src/lib/theme.h | 2 ++
|
||||
src/lib/themedata_p.h | 2 ++
|
||||
src/lib/wildcardmatcher.cpp | 2 +-
|
||||
src/lib/wildcardmatcher_p.h | 4 ++++
|
||||
16 files changed, 39 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/abstracthighlighter.h b/src/lib/abstracthighlighter.h
|
||||
index 056f65b..2b88729 100644
|
||||
--- a/src/lib/abstracthighlighter.h
|
||||
+++ b/src/lib/abstracthighlighter.h
|
||||
@@ -30,7 +30,9 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QString;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
@@ -186,6 +188,8 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_INTERFACE(KSyntaxHighlighting::AbstractHighlighter, "org.kde.SyntaxHighlighting.AbstractHighlighter")
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
#endif // KSYNTAXHIGHLIGHTING_ABSTRACTHIGHLIGHTERM_H
|
||||
diff --git a/src/lib/abstracthighlighter_p.h b/src/lib/abstracthighlighter_p.h
|
||||
index 1690eb0..bdfdf23 100644
|
||||
--- a/src/lib/abstracthighlighter_p.h
|
||||
+++ b/src/lib/abstracthighlighter_p.h
|
||||
@@ -27,7 +27,9 @@
|
||||
#include "definition.h"
|
||||
#include "theme.h"
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QStringList;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
diff --git a/src/lib/context_p.h b/src/lib/context_p.h
|
||||
index 3e3ab97..a034d0e 100644
|
||||
--- a/src/lib/context_p.h
|
||||
+++ b/src/lib/context_p.h
|
||||
@@ -34,7 +34,9 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QXmlStreamReader;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
diff --git a/src/lib/definition.h b/src/lib/definition.h
|
||||
index 25996dd..6f0dba9 100644
|
||||
--- a/src/lib/definition.h
|
||||
+++ b/src/lib/definition.h
|
||||
@@ -31,10 +31,12 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QChar;
|
||||
class QString;
|
||||
class QStringList;
|
||||
template <typename T> class QVector;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
@@ -391,6 +393,8 @@ private:
|
||||
|
||||
}
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Definition, Q_MOVABLE_TYPE);
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
diff --git a/src/lib/foldingregion.h b/src/lib/foldingregion.h
|
||||
index baf65d1..074b947 100644
|
||||
--- a/src/lib/foldingregion.h
|
||||
+++ b/src/lib/foldingregion.h
|
||||
@@ -101,6 +101,8 @@ private:
|
||||
|
||||
}
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::FoldingRegion, Q_PRIMITIVE_TYPE);
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
diff --git a/src/lib/format.h b/src/lib/format.h
|
||||
index ba85f0d..24c58e7 100644
|
||||
--- a/src/lib/format.h
|
||||
+++ b/src/lib/format.h
|
||||
@@ -30,10 +30,11 @@
|
||||
#include <QExplicitlySharedDataPointer>
|
||||
#include <QTypeInfo>
|
||||
|
||||
-
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QColor;
|
||||
class QString;
|
||||
class QXmlStreamReader;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
@@ -144,6 +145,8 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Format, Q_MOVABLE_TYPE);
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
#endif // KSYNTAXHIGHLIGHTING_FORMAT_H
|
||||
diff --git a/src/lib/htmlhighlighter.h b/src/lib/htmlhighlighter.h
|
||||
index 22d33ad..b7eda02 100644
|
||||
--- a/src/lib/htmlhighlighter.h
|
||||
+++ b/src/lib/htmlhighlighter.h
|
||||
@@ -32,8 +32,10 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QFile;
|
||||
class QTextStream;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
diff --git a/src/lib/keywordlist_p.h b/src/lib/keywordlist_p.h
|
||||
index fa70f11..8c41aab 100644
|
||||
--- a/src/lib/keywordlist_p.h
|
||||
+++ b/src/lib/keywordlist_p.h
|
||||
@@ -30,7 +30,9 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QXmlStreamReader;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
diff --git a/src/lib/repository.h b/src/lib/repository.h
|
||||
index 2c32d02..c35da5e 100644
|
||||
--- a/src/lib/repository.h
|
||||
+++ b/src/lib/repository.h
|
||||
@@ -29,8 +29,10 @@
|
||||
#include <qglobal.h>
|
||||
#include <memory>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QString;
|
||||
template <typename T> class QVector;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
/**
|
||||
* @namespace KSyntaxHighlighting
|
||||
diff --git a/src/lib/repository_p.h b/src/lib/repository_p.h
|
||||
index da765a2..9db876b 100644
|
||||
--- a/src/lib/repository_p.h
|
||||
+++ b/src/lib/repository_p.h
|
||||
@@ -27,7 +27,9 @@
|
||||
#include <QHash>
|
||||
#include <QVector>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QString;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
diff --git a/src/lib/rule_p.h b/src/lib/rule_p.h
|
||||
index eccf0df..538fded 100644
|
||||
--- a/src/lib/rule_p.h
|
||||
+++ b/src/lib/rule_p.h
|
||||
@@ -38,7 +38,9 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QXmlStreamReader;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
diff --git a/src/lib/state.h b/src/lib/state.h
|
||||
index c6e5344..fce4bc7 100644
|
||||
--- a/src/lib/state.h
|
||||
+++ b/src/lib/state.h
|
||||
@@ -79,6 +79,8 @@ private:
|
||||
|
||||
}
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::State, Q_MOVABLE_TYPE);
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
#endif // KSYNTAXHIGHLIGHTING_STATE_H
|
||||
diff --git a/src/lib/theme.h b/src/lib/theme.h
|
||||
index 5277429..adb8431 100644
|
||||
--- a/src/lib/theme.h
|
||||
+++ b/src/lib/theme.h
|
||||
@@ -371,6 +371,8 @@ private:
|
||||
|
||||
}
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::Theme, Q_MOVABLE_TYPE);
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
#endif // KSYNTAXHIGHLIGHTING_THEME_H
|
||||
diff --git a/src/lib/themedata_p.h b/src/lib/themedata_p.h
|
||||
index 68cb873..3b5f463 100644
|
||||
--- a/src/lib/themedata_p.h
|
||||
+++ b/src/lib/themedata_p.h
|
||||
@@ -163,6 +163,8 @@ private:
|
||||
|
||||
}
|
||||
|
||||
+QT_BEGIN_NAMESPACE
|
||||
Q_DECLARE_TYPEINFO(KSyntaxHighlighting::TextStyleData, Q_MOVABLE_TYPE);
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
#endif // KSYNTAXHIGHLIGHTING_THEMEDATA_P_H
|
||||
diff --git a/src/lib/wildcardmatcher.cpp b/src/lib/wildcardmatcher.cpp
|
||||
index 963e78d..167295a 100644
|
||||
--- a/src/lib/wildcardmatcher.cpp
|
||||
+++ b/src/lib/wildcardmatcher.cpp
|
||||
@@ -79,5 +79,5 @@ static bool exactMatch(const QString &candidate, const QString &wildcard, int ca
|
||||
bool WildcardMatcher::exactMatch(const QString &candidate, const QString &wildcard,
|
||||
bool caseSensitive)
|
||||
{
|
||||
- return exactMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1, caseSensitive);
|
||||
+ return ::exactMatch(candidate, wildcard, candidate.length() - 1, wildcard.length() - 1, caseSensitive);
|
||||
}
|
||||
diff --git a/src/lib/wildcardmatcher_p.h b/src/lib/wildcardmatcher_p.h
|
||||
index 823dbd5..016b10f 100644
|
||||
--- a/src/lib/wildcardmatcher_p.h
|
||||
+++ b/src/lib/wildcardmatcher_p.h
|
||||
@@ -24,7 +24,11 @@
|
||||
#ifndef KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_P_H
|
||||
#define KSYNTAXHIGHLIGHTING_WILDCARDMATCHER_P_H
|
||||
|
||||
+#include <QtGlobal>
|
||||
+
|
||||
+QT_BEGIN_NAMESPACE
|
||||
class QString;
|
||||
+QT_END_NAMESPACE
|
||||
|
||||
namespace KSyntaxHighlighting {
|
||||
|
||||
--
|
||||
2.20.1.windows.1
|
||||
|
29
src/libs/3rdparty/syntax-highlighting/patches/0005-Prevent-assertion-in-RegExpr-doLoad.patch
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
From 3c05e92c71f6675fa2071036dafbc8d337bd2d01 Mon Sep 17 00:00:00 2001
|
||||
From: Alessandro Portale <alessandro.portale@qt.io>
|
||||
Date: Tue, 12 Feb 2019 19:27:46 +0100
|
||||
Subject: [PATCH 5/6] Prevent assertion in RegExpr::doLoad
|
||||
|
||||
---
|
||||
src/lib/rule.cpp | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/rule.cpp b/src/lib/rule.cpp
|
||||
index a201375..c48753b 100644
|
||||
--- a/src/lib/rule.cpp
|
||||
+++ b/src/lib/rule.cpp
|
||||
@@ -575,7 +575,11 @@ bool RegExpr::doLoad(QXmlStreamReader& reader)
|
||||
}
|
||||
|
||||
// always using m_regexp.isValid() would be better, but parses the regexp and thus is way too expensive for release builds
|
||||
- Q_ASSERT(m_regexp.isValid());
|
||||
+
|
||||
+ if (Log().isDebugEnabled()) {
|
||||
+ if (!m_regexp.isValid())
|
||||
+ qCDebug(Log) << "Invalid regexp:" << m_regexp.pattern();
|
||||
+ }
|
||||
return !m_regexp.pattern().isEmpty();
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1.windows.1
|
||||
|
@@ -0,0 +1,101 @@
|
||||
From 4b64058fe7d788ac79c16a08b280ce05d500e9fb Mon Sep 17 00:00:00 2001
|
||||
From: Alessandro Portale <alessandro.portale@qt.io>
|
||||
Date: Tue, 12 Feb 2019 19:32:54 +0100
|
||||
Subject: [PATCH 6/6] Syntax Highlighter: return all definitions for a file
|
||||
name/mimetype
|
||||
|
||||
Can be used to create user controls to switch between
|
||||
multiple definitions for a file or mime type.
|
||||
|
||||
Change-Id: I5fd3744db1e819d0d6f8448a53adaf9d2c7c168d
|
||||
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
|
||||
---
|
||||
src/lib/repository.cpp | 17 +++++++++++++----
|
||||
src/lib/repository.h | 12 ++++++++++++
|
||||
2 files changed, 25 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/lib/repository.cpp b/src/lib/repository.cpp
|
||||
index 6b2fabd..922225a 100644
|
||||
--- a/src/lib/repository.cpp
|
||||
+++ b/src/lib/repository.cpp
|
||||
@@ -78,7 +78,7 @@ Definition Repository::definitionForName(const QString& defName) const
|
||||
return d->m_defs.value(defName);
|
||||
}
|
||||
|
||||
-static Definition bestCandidate(QVector<Definition>& candidates)
|
||||
+static Definition bestCandidate(QVector<Definition> &&candidates)
|
||||
{
|
||||
if (candidates.isEmpty())
|
||||
return Definition();
|
||||
@@ -91,6 +91,11 @@ static Definition bestCandidate(QVector<Definition>& candidates)
|
||||
}
|
||||
|
||||
Definition Repository::definitionForFileName(const QString& fileName) const
|
||||
+{
|
||||
+ return bestCandidate(definitionsForFileName(fileName));
|
||||
+}
|
||||
+
|
||||
+QVector<Definition> Repository::definitionsForFileName(const QString &fileName) const
|
||||
{
|
||||
QFileInfo fi(fileName);
|
||||
const auto name = fi.fileName();
|
||||
@@ -106,10 +111,15 @@ Definition Repository::definitionForFileName(const QString& fileName) const
|
||||
}
|
||||
}
|
||||
|
||||
- return bestCandidate(candidates);
|
||||
+ return candidates;
|
||||
}
|
||||
|
||||
Definition Repository::definitionForMimeType(const QString& mimeType) const
|
||||
+{
|
||||
+ return bestCandidate(definitionsForMimeType(mimeType));
|
||||
+}
|
||||
+
|
||||
+QVector<Definition> Repository::definitionsForMimeType(const QString &mimeType) const
|
||||
{
|
||||
QVector<Definition> candidates;
|
||||
for (auto it = d->m_defs.constBegin(); it != d->m_defs.constEnd(); ++it) {
|
||||
@@ -121,8 +131,7 @@ Definition Repository::definitionForMimeType(const QString& mimeType) const
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- return bestCandidate(candidates);
|
||||
+ return candidates;
|
||||
}
|
||||
|
||||
QVector<Definition> Repository::definitions() const
|
||||
diff --git a/src/lib/repository.h b/src/lib/repository.h
|
||||
index c35da5e..e4e9bed 100644
|
||||
--- a/src/lib/repository.h
|
||||
+++ b/src/lib/repository.h
|
||||
@@ -166,6 +166,13 @@ public:
|
||||
*/
|
||||
Definition definitionForFileName(const QString &fileName) const;
|
||||
|
||||
+ /**
|
||||
+ * Returns all Definition%s for the file named @p fileName.
|
||||
+ * The match is performed based on the \e extensions and @e mimetype of
|
||||
+ * the definition files.
|
||||
+ */
|
||||
+ QVector<Definition> definitionsForFileName(const QString &fileName) const;
|
||||
+
|
||||
/**
|
||||
* Returns the best matching Definition to the type named @p mimeType
|
||||
*
|
||||
@@ -176,6 +183,11 @@ public:
|
||||
*/
|
||||
Definition definitionForMimeType(const QString &mimeType) const;
|
||||
|
||||
+ /**
|
||||
+ * Returns all Definition%s to the type named @p mimeType
|
||||
+ */
|
||||
+ QVector<Definition> definitionsForMimeType(const QString &mimeType) const;
|
||||
+
|
||||
/**
|
||||
* Returns all available Definition%s.
|
||||
* Definition%ss are ordered by translated section and translated names,
|
||||
--
|
||||
2.20.1.windows.1
|
||||
|
@@ -35,12 +35,15 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
enum class InputFileType : unsigned char { Header, Source };
|
||||
|
||||
template<typename ProjectInfo, typename OutputContainer = Utils::SmallStringVector>
|
||||
class CommandLineBuilder
|
||||
{
|
||||
public:
|
||||
CommandLineBuilder(const ProjectInfo &projectInfo,
|
||||
const Utils::SmallStringVector &toolChainArguments = {},
|
||||
InputFileType sourceType = InputFileType::Header,
|
||||
FilePathView sourcePath = {},
|
||||
FilePathView outputPath = {},
|
||||
FilePathView includePchPath = {})
|
||||
@@ -49,9 +52,9 @@ public:
|
||||
|
||||
addCompiler(projectInfo.language);
|
||||
addToolChainArguments(toolChainArguments);
|
||||
addLanguage(projectInfo);
|
||||
addLanguage(projectInfo, sourceType);
|
||||
addLanguageVersion(projectInfo);
|
||||
addNoStdIncAndNoStdLibInc();
|
||||
addNoStdIncAndNoStdLibInc(projectInfo.language);
|
||||
addCompilerMacros(projectInfo.compilerMacros);
|
||||
addProjectIncludeSearchPaths(
|
||||
sortedIncludeSearchPaths(projectInfo.projectIncludeSearchPaths));
|
||||
@@ -76,26 +79,27 @@ public:
|
||||
commandLine.emplace_back(argument);
|
||||
}
|
||||
|
||||
static const char *language(const ProjectInfo &projectInfo)
|
||||
static const char *language(const ProjectInfo &projectInfo, InputFileType sourceType)
|
||||
{
|
||||
switch (projectInfo.language) {
|
||||
case Utils::Language::C:
|
||||
if (projectInfo.languageExtension && Utils::LanguageExtension::ObjectiveC)
|
||||
return "objective-c-header";
|
||||
return sourceType == InputFileType::Header ? "objective-c-header" : "objective-c";
|
||||
|
||||
return "c-header";
|
||||
return sourceType == InputFileType::Header ? "c-header" : "c";
|
||||
case Utils::Language::Cxx:
|
||||
if (projectInfo.languageExtension && Utils::LanguageExtension::ObjectiveC)
|
||||
return "objective-c++-header";
|
||||
return sourceType == InputFileType::Header ? "objective-c++-header"
|
||||
: "objective-c++";
|
||||
}
|
||||
|
||||
return "c++-header";
|
||||
return sourceType == InputFileType::Header ? "c++-header" : "c++";
|
||||
}
|
||||
|
||||
void addLanguage(const ProjectInfo &projectInfo)
|
||||
void addLanguage(const ProjectInfo &projectInfo, InputFileType sourceType)
|
||||
{
|
||||
commandLine.emplace_back("-x");
|
||||
commandLine.emplace_back(language(projectInfo));
|
||||
commandLine.emplace_back(language(projectInfo, sourceType));
|
||||
}
|
||||
|
||||
const char *standardLanguageVersion(Utils::LanguageVersion languageVersion)
|
||||
@@ -108,7 +112,7 @@ public:
|
||||
case Utils::LanguageVersion::C11:
|
||||
return "-std=c11";
|
||||
case Utils::LanguageVersion::C18:
|
||||
return "-std=c18";
|
||||
return "-std=c17";
|
||||
case Utils::LanguageVersion::CXX98:
|
||||
return "-std=c++98";
|
||||
case Utils::LanguageVersion::CXX03:
|
||||
@@ -136,7 +140,7 @@ public:
|
||||
case Utils::LanguageVersion::C11:
|
||||
return "-std=gnu11";
|
||||
case Utils::LanguageVersion::C18:
|
||||
return "-std=gnu18";
|
||||
return "-std=gnu17";
|
||||
case Utils::LanguageVersion::CXX98:
|
||||
return "-std=gnu++98";
|
||||
case Utils::LanguageVersion::CXX03:
|
||||
@@ -268,10 +272,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void addNoStdIncAndNoStdLibInc()
|
||||
void addNoStdIncAndNoStdLibInc(Utils::Language language)
|
||||
{
|
||||
commandLine.emplace_back("-nostdinc");
|
||||
commandLine.emplace_back("-nostdinc++");
|
||||
if (language == Utils::Language::Cxx)
|
||||
commandLine.emplace_back("-nostdinc++");
|
||||
}
|
||||
|
||||
public:
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
@@ -33,6 +34,7 @@ class ProgressCounter
|
||||
{
|
||||
public:
|
||||
using SetProgressCallback = std::function<void(int, int)>;
|
||||
using Lock = std::lock_guard<std::mutex>;
|
||||
|
||||
ProgressCounter(SetProgressCallback &&progressCallback)
|
||||
: m_progressCallback(std::move(progressCallback))
|
||||
@@ -40,6 +42,8 @@ public:
|
||||
|
||||
void addTotal(int total)
|
||||
{
|
||||
Lock lock(m_mutex);
|
||||
|
||||
if (total) {
|
||||
m_total += total;
|
||||
|
||||
@@ -49,6 +53,8 @@ public:
|
||||
|
||||
void removeTotal(int total)
|
||||
{
|
||||
Lock lock(m_mutex);
|
||||
|
||||
if (total) {
|
||||
m_total -= total;
|
||||
|
||||
@@ -58,6 +64,8 @@ public:
|
||||
|
||||
void addProgress(int progress)
|
||||
{
|
||||
Lock lock(m_mutex);
|
||||
|
||||
if (progress) {
|
||||
m_progress += progress;
|
||||
|
||||
@@ -65,6 +73,21 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int total() const
|
||||
{
|
||||
Lock lock(m_mutex);
|
||||
|
||||
return m_total;
|
||||
}
|
||||
|
||||
int progress() const
|
||||
{
|
||||
Lock lock(m_mutex);
|
||||
|
||||
return m_total;
|
||||
}
|
||||
|
||||
private:
|
||||
void sendProgress()
|
||||
{
|
||||
m_progressCallback(m_progress, m_total);
|
||||
@@ -75,17 +98,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
int total() const
|
||||
{
|
||||
return m_total;
|
||||
}
|
||||
|
||||
int progress() const
|
||||
{
|
||||
return m_total;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::mutex m_mutex;
|
||||
std::function<void(int, int)> m_progressCallback;
|
||||
int m_progress = 0;
|
||||
int m_total = 0;
|
||||
|
@@ -27,14 +27,15 @@
|
||||
#include "lsputils.h"
|
||||
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <utils/textutils.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QHash>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QMap>
|
||||
#include <QTextBlock>
|
||||
#include <QTextDocument>
|
||||
#include <QVector>
|
||||
#include <QFile>
|
||||
|
||||
namespace LanguageServerProtocol {
|
||||
|
||||
@@ -340,6 +341,24 @@ Range::Range(const Position &start, const Position &end)
|
||||
setEnd(end);
|
||||
}
|
||||
|
||||
Range::Range(const QTextCursor &cursor)
|
||||
{
|
||||
int line, character = 0;
|
||||
Utils::Text::convertPosition(cursor.document(), cursor.selectionStart(), &line, &character);
|
||||
if (line <= 0 || character <= 0)
|
||||
return;
|
||||
setStart(Position(line - 1, character - 1));
|
||||
Utils::Text::convertPosition(cursor.document(), cursor.selectionEnd(), &line, &character);
|
||||
if (line <= 0 || character <= 0)
|
||||
return;
|
||||
setEnd(Position(line - 1, character - 1));
|
||||
}
|
||||
|
||||
bool Range::overlaps(const Range &range) const
|
||||
{
|
||||
return contains(range.start()) || contains(range.end());
|
||||
}
|
||||
|
||||
bool DocumentFilter::applies(const Utils::FileName &fileName, const Utils::MimeType &mimeType) const
|
||||
{
|
||||
if (Utils::optional<QString> _scheme = scheme()) {
|
||||
|
@@ -100,6 +100,7 @@ class LANGUAGESERVERPROTOCOL_EXPORT Range : public JsonObject
|
||||
public:
|
||||
Range() = default;
|
||||
Range(const Position &start, const Position &end);
|
||||
explicit Range(const QTextCursor &cursor);
|
||||
using JsonObject::JsonObject;
|
||||
|
||||
// The range's start position.
|
||||
@@ -111,6 +112,7 @@ public:
|
||||
void setEnd(const Position &end) { insert(endKey, end); }
|
||||
|
||||
bool contains(const Position &pos) const { return start() <= pos && pos <= end(); }
|
||||
bool overlaps(const Range &range) const;
|
||||
|
||||
bool isValid(QStringList *error) const override
|
||||
{ return check<Position>(error, startKey) && check<Position>(error, endKey); }
|
||||
|
99
src/libs/utils/jsontreeitem.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "jsontreeitem.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
Utils::JsonTreeItem::JsonTreeItem(const QString &displayName, const QJsonValue &value)
|
||||
: m_name(displayName)
|
||||
, m_value(value)
|
||||
{ }
|
||||
|
||||
static QString typeName(QJsonValue::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case QJsonValue::Null:
|
||||
return Utils::JsonTreeItem::tr("Null");
|
||||
case QJsonValue::Bool:
|
||||
return Utils::JsonTreeItem::tr("Bool");
|
||||
case QJsonValue::Double:
|
||||
return Utils::JsonTreeItem::tr("Double");
|
||||
case QJsonValue::String:
|
||||
return Utils::JsonTreeItem::tr("String");
|
||||
case QJsonValue::Array:
|
||||
return Utils::JsonTreeItem::tr("Array");
|
||||
case QJsonValue::Object:
|
||||
return Utils::JsonTreeItem::tr("Object");
|
||||
case QJsonValue::Undefined:
|
||||
return Utils::JsonTreeItem::tr("Undefined");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant Utils::JsonTreeItem::data(int column, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return {};
|
||||
if (column == 0)
|
||||
return m_name;
|
||||
if (column == 2)
|
||||
return typeName(m_value.type());
|
||||
if (m_value.isObject())
|
||||
return QString('[' + QString::number(m_value.toObject().size()) + ' ' + tr("Items") + ']');
|
||||
if (m_value.isArray())
|
||||
return QString('[' + QString::number(m_value.toArray().size()) + ' ' + tr("Items") + ']');
|
||||
return m_value.toVariant();
|
||||
}
|
||||
|
||||
bool Utils::JsonTreeItem::canFetchMore() const
|
||||
{
|
||||
return canFetchObjectChildren() || canFetchArrayChildren();
|
||||
}
|
||||
|
||||
void Utils::JsonTreeItem::fetchMore()
|
||||
{
|
||||
if (canFetchObjectChildren()) {
|
||||
const QJsonObject &object = m_value.toObject();
|
||||
for (const QString &key : object.keys())
|
||||
appendChild(new JsonTreeItem(key, object.value(key)));
|
||||
} else if (canFetchArrayChildren()) {
|
||||
int index = 0;
|
||||
const QJsonArray &array = m_value.toArray();
|
||||
for (const QJsonValue &val : array)
|
||||
appendChild(new JsonTreeItem(QString::number(index++), val));
|
||||
}
|
||||
}
|
||||
|
||||
bool Utils::JsonTreeItem::canFetchObjectChildren() const
|
||||
{
|
||||
return m_value.isObject() && m_value.toObject().size() > childCount();
|
||||
}
|
||||
|
||||
bool Utils::JsonTreeItem::canFetchArrayChildren() const
|
||||
{
|
||||
return m_value.isArray() && m_value.toArray().size() > childCount();
|
||||
}
|
56
src/libs/utils/jsontreeitem.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "treemodel.h"
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
#include <QJsonValue>
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT JsonTreeItem : public TypedTreeItem<JsonTreeItem>
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(JsonTreeModelItem)
|
||||
public:
|
||||
JsonTreeItem() = default;
|
||||
JsonTreeItem(const QString &displayName, const QJsonValue &value);
|
||||
|
||||
QVariant data(int column, int role) const override;
|
||||
bool canFetchMore() const override;
|
||||
void fetchMore() override;
|
||||
|
||||
private:
|
||||
bool canFetchObjectChildren() const;
|
||||
bool canFetchArrayChildren() const;
|
||||
|
||||
QString m_name;
|
||||
QJsonValue m_value;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
@@ -263,6 +263,7 @@ void ToolTip::showInternal(const QPoint &pos, const QVariant &content,
|
||||
m_tip = new WidgetTip(target);
|
||||
break;
|
||||
}
|
||||
m_tip->setObjectName("qcToolTip");
|
||||
m_tip->setContent(content);
|
||||
m_tip->setContextHelp(contextHelp);
|
||||
setUp(pos, w, rect);
|
||||
|
@@ -124,7 +124,9 @@ SOURCES += \
|
||||
$$PWD/filecrumblabel.cpp \
|
||||
$$PWD/fixedsizeclicklabel.cpp \
|
||||
$$PWD/removefiledialog.cpp \
|
||||
$$PWD/differ.cpp
|
||||
$$PWD/differ.cpp \
|
||||
$$PWD/jsontreeitem.cpp
|
||||
|
||||
|
||||
win32:SOURCES += $$PWD/consoleprocess_win.cpp
|
||||
else:SOURCES += $$PWD/consoleprocess_unix.cpp
|
||||
@@ -265,7 +267,8 @@ HEADERS += \
|
||||
$$PWD/fixedsizeclicklabel.h \
|
||||
$$PWD/removefiledialog.h \
|
||||
$$PWD/differ.h \
|
||||
$$PWD/cpplanguage_details.h
|
||||
$$PWD/cpplanguage_details.h \
|
||||
$$PWD/jsontreeitem.h
|
||||
|
||||
FORMS += $$PWD/filewizardpage.ui \
|
||||
$$PWD/newclasswidget.ui \
|
||||
|
@@ -142,6 +142,8 @@ Project {
|
||||
"itemviews.h",
|
||||
"json.cpp",
|
||||
"json.h",
|
||||
"jsontreeitem.cpp",
|
||||
"jsontreeitem.h",
|
||||
"linecolumn.h",
|
||||
"link.h",
|
||||
"listutils.h",
|
||||
|
@@ -93,79 +93,6 @@ ClangHoverHandler::~ClangHoverHandler()
|
||||
abort();
|
||||
}
|
||||
|
||||
static int skipChars(QTextCursor *tc,
|
||||
QTextCursor::MoveOperation op,
|
||||
int offset,
|
||||
std::function<bool(const QChar &)> skip)
|
||||
{
|
||||
const QTextDocument *doc = tc->document();
|
||||
QChar ch = doc->characterAt(tc->position() + offset);
|
||||
if (ch.isNull())
|
||||
return 0;
|
||||
int count = 0;
|
||||
while (skip(ch)) {
|
||||
if (tc->movePosition(op))
|
||||
++count;
|
||||
else
|
||||
break;
|
||||
ch = doc->characterAt(tc->position() + offset);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int skipCharsForward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
|
||||
{
|
||||
return skipChars(tc, QTextCursor::NextCharacter, 0, skip);
|
||||
}
|
||||
|
||||
static int skipCharsBackward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
|
||||
{
|
||||
return skipChars(tc, QTextCursor::PreviousCharacter, -1, skip);
|
||||
}
|
||||
|
||||
static QStringList fallbackWords(QTextDocument *document, int pos)
|
||||
{
|
||||
const auto isSpace = [](const QChar &c) { return c.isSpace(); };
|
||||
const auto isColon = [](const QChar &c) { return c == ':'; };
|
||||
const auto isValidIdentifierChar = [document](const QTextCursor &tc) {
|
||||
return CppTools::isValidIdentifierChar(document->characterAt(tc.position()));
|
||||
};
|
||||
// move to the end
|
||||
QTextCursor endCursor(document);
|
||||
endCursor.setPosition(pos);
|
||||
do {
|
||||
CppTools::moveCursorToEndOfIdentifier(&endCursor);
|
||||
// possibly skip ::
|
||||
QTextCursor temp(endCursor);
|
||||
skipCharsForward(&temp, isSpace);
|
||||
const int colons = skipCharsForward(&temp, isColon);
|
||||
skipCharsForward(&temp, isSpace);
|
||||
if (colons == 2 && isValidIdentifierChar(temp))
|
||||
endCursor = temp;
|
||||
} while (isValidIdentifierChar(endCursor));
|
||||
|
||||
QStringList results;
|
||||
QTextCursor startCursor(endCursor);
|
||||
do {
|
||||
CppTools::moveCursorToStartOfIdentifier(&startCursor);
|
||||
if (startCursor.position() == endCursor.position())
|
||||
break;
|
||||
QTextCursor temp(endCursor);
|
||||
temp.setPosition(startCursor.position(), QTextCursor::KeepAnchor);
|
||||
results.append(temp.selectedText().remove(QRegularExpression("\\s")));
|
||||
// possibly skip ::
|
||||
temp = startCursor;
|
||||
skipCharsBackward(&temp, isSpace);
|
||||
const int colons = skipCharsBackward(&temp, isColon);
|
||||
skipCharsBackward(&temp, isSpace);
|
||||
if (colons == 2
|
||||
&& CppTools::isValidIdentifierChar(document->characterAt(temp.position() - 1))) {
|
||||
startCursor = temp;
|
||||
}
|
||||
} while (!isValidIdentifierChar(startCursor));
|
||||
return results;
|
||||
}
|
||||
|
||||
void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
|
||||
int pos,
|
||||
BaseHoverHandler::ReportPriority report)
|
||||
@@ -187,7 +114,9 @@ void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
|
||||
qCDebug(hoverLog) << "Requesting tooltip info at" << pos;
|
||||
m_reportPriority = report;
|
||||
m_futureWatcher.reset(new QFutureWatcher<CppTools::ToolTipInfo>());
|
||||
const QStringList fallback = fallbackWords(editorWidget->document(), pos);
|
||||
QTextCursor tc(editorWidget->document());
|
||||
tc.setPosition(pos);
|
||||
const QStringList fallback = CppTools::identifierWordsUnderCursor(tc);
|
||||
QObject::connect(m_futureWatcher.data(),
|
||||
&QFutureWatcherBase::finished,
|
||||
[this, fallback]() {
|
||||
|
@@ -36,16 +36,27 @@
|
||||
|
||||
namespace ClangFormat {
|
||||
|
||||
static void adjustFormatStyleForLineBreak(clang::format::FormatStyle &style)
|
||||
static void adjustFormatStyleForLineBreak(clang::format::FormatStyle &style,
|
||||
ReplacementsToKeep replacementsToKeep)
|
||||
{
|
||||
if (replacementsToKeep == ReplacementsToKeep::All)
|
||||
return;
|
||||
|
||||
style.MaxEmptyLinesToKeep = 2;
|
||||
style.SortIncludes = false;
|
||||
style.SortUsingDeclarations = false;
|
||||
|
||||
// This is a separate pass, don't do it unless it's the full formatting.
|
||||
style.FixNamespaceComments = false;
|
||||
|
||||
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
|
||||
return;
|
||||
|
||||
style.DisableFormat = false;
|
||||
style.ColumnLimit = 0;
|
||||
#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
|
||||
style.KeepLineBreaksForNonEmptyLines = true;
|
||||
#endif
|
||||
style.MaxEmptyLinesToKeep = 2;
|
||||
style.SortIncludes = false;
|
||||
style.SortUsingDeclarations = false;
|
||||
}
|
||||
|
||||
static llvm::StringRef clearExtraNewline(llvm::StringRef text)
|
||||
@@ -59,7 +70,6 @@ static clang::tooling::Replacements filteredReplacements(
|
||||
const clang::tooling::Replacements &replacements,
|
||||
int offset,
|
||||
int utf8LineLengthBeforeCursor,
|
||||
int extraOffsetFromStartOfFile,
|
||||
int extraEmptySpaceOffset,
|
||||
ReplacementsToKeep replacementsToKeep)
|
||||
{
|
||||
@@ -69,14 +79,13 @@ static clang::tooling::Replacements filteredReplacements(
|
||||
const bool replacementDoesNotMatchRestriction
|
||||
= (replacementsToKeep == ReplacementsToKeep::OnlyIndent
|
||||
&& replacementOffset != offset - 1)
|
||||
|| (replacementsToKeep == ReplacementsToKeep::OnlyBeforeIndent
|
||||
&& replacementOffset >= offset + utf8LineLengthBeforeCursor - 1);
|
||||
|| (replacementsToKeep == ReplacementsToKeep::IndentAndBefore
|
||||
&& replacementOffset > offset + utf8LineLengthBeforeCursor - 1);
|
||||
if (replacementDoesNotMatchRestriction)
|
||||
continue;
|
||||
|
||||
if (replacementOffset >= offset - 1)
|
||||
replacementOffset += extraEmptySpaceOffset;
|
||||
replacementOffset += extraOffsetFromStartOfFile;
|
||||
|
||||
llvm::StringRef text = replacementsToKeep == ReplacementsToKeep::OnlyIndent
|
||||
? clearExtraNewline(replacement.getReplacementText())
|
||||
@@ -128,18 +137,6 @@ static void trimFirstNonEmptyBlock(const QTextBlock ¤tBlock)
|
||||
cursor.endEditBlock();
|
||||
}
|
||||
|
||||
static void trimCurrentBlock(const QTextBlock ¤tBlock)
|
||||
{
|
||||
if (currentBlock.text().trimmed().isEmpty()) {
|
||||
// Clear the block containing only spaces
|
||||
QTextCursor cursor(currentBlock);
|
||||
cursor.beginEditBlock();
|
||||
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
|
||||
cursor.removeSelectedText();
|
||||
cursor.endEditBlock();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the total langth of previous lines with pure whitespace.
|
||||
static int previousEmptyLinesLength(const QTextBlock ¤tBlock)
|
||||
{
|
||||
@@ -167,7 +164,7 @@ static void modifyToIndentEmptyLines(
|
||||
|
||||
if (firstNonWhitespace < 0 || closingParenBlock) {
|
||||
//This extra text works for the most cases.
|
||||
QByteArray dummyText("a;");
|
||||
QByteArray dummyText("a;a;");
|
||||
|
||||
// Search for previous character
|
||||
QTextBlock prevBlock = block.previous();
|
||||
@@ -198,8 +195,6 @@ static void modifyToIndentEmptyLines(
|
||||
}
|
||||
}
|
||||
|
||||
static const int kMaxLinesFromCurrentBlock = 200;
|
||||
|
||||
static Utils::LineColumn utf16LineColumn(const QTextBlock &block,
|
||||
int blockOffsetUtf8,
|
||||
const QByteArray &utf8Buffer,
|
||||
@@ -388,24 +383,21 @@ TextEditor::Replacements ClangFormatBaseIndenter::format(
|
||||
return format(cursor, cursorPositionInEditor);
|
||||
}
|
||||
|
||||
int ClangFormatBaseIndenter::indentBeforeCursor(const QTextBlock &block,
|
||||
const QChar &typedChar,
|
||||
int cursorPositionInEditor)
|
||||
void ClangFormatBaseIndenter::indentBeforeCursor(const QTextBlock &block,
|
||||
const QChar &typedChar,
|
||||
int cursorPositionInEditor)
|
||||
{
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
const int utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, block.blockNumber() + 1);
|
||||
QTC_ASSERT(utf8Offset >= 0, return cursorPositionInEditor;);
|
||||
QTC_ASSERT(utf8Offset >= 0, return;);
|
||||
const TextEditor::Replacements toReplace = replacements(buffer,
|
||||
utf8Offset,
|
||||
0,
|
||||
block,
|
||||
cursorPositionInEditor,
|
||||
ReplacementsToKeep::OnlyBeforeIndent,
|
||||
ReplacementsToKeep::IndentAndBefore,
|
||||
typedChar);
|
||||
applyReplacements(block, toReplace);
|
||||
for (const TextEditor::Replacement &replacement : toReplace)
|
||||
cursorPositionInEditor += replacement.text.length() - replacement.length;
|
||||
return cursorPositionInEditor;
|
||||
}
|
||||
|
||||
static bool doNotIndentInContext(QTextDocument *doc, int pos)
|
||||
@@ -466,11 +458,10 @@ void ClangFormatBaseIndenter::indentBlock(const QTextBlock &block,
|
||||
else
|
||||
cursorPositionInEditor = currentBlock.position();
|
||||
|
||||
cursorPositionInEditor = indentBeforeCursor(currentBlock, typedChar, cursorPositionInEditor);
|
||||
currentBlock = m_doc->findBlock(cursorPositionInEditor);
|
||||
indentBeforeCursor(currentBlock, typedChar, cursorPositionInEditor);
|
||||
return;
|
||||
}
|
||||
|
||||
trimCurrentBlock(currentBlock);
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
const int utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, block.blockNumber() + 1);
|
||||
QTC_ASSERT(utf8Offset >= 0, return;);
|
||||
@@ -496,7 +487,6 @@ void ClangFormatBaseIndenter::indentBlock(const QTextBlock &block,
|
||||
int ClangFormatBaseIndenter::indentFor(const QTextBlock &block, int cursorPositionInEditor)
|
||||
{
|
||||
trimFirstNonEmptyBlock(block);
|
||||
trimCurrentBlock(block);
|
||||
const QByteArray buffer = m_doc->toPlainText().toUtf8();
|
||||
const int utf8Offset = Utils::Text::utf8NthLineOffset(m_doc, buffer, block.blockNumber() + 1);
|
||||
QTC_ASSERT(utf8Offset >= 0, return 0;);
|
||||
@@ -571,8 +561,7 @@ static int formattingRangeStart(const QTextBlock ¤tBlock,
|
||||
{
|
||||
QTextBlock prevBlock = currentBlock.previous();
|
||||
while ((prevBlock.position() > 0 || prevBlock.length() > 0)
|
||||
&& prevBlock.revision() != documentRevision
|
||||
&& (currentBlock.blockNumber() - prevBlock.blockNumber() < kMaxLinesFromCurrentBlock)) {
|
||||
&& prevBlock.revision() != documentRevision) {
|
||||
// Find the first block with not matching revision.
|
||||
prevBlock = prevBlock.previous();
|
||||
}
|
||||
@@ -604,41 +593,27 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer
|
||||
= block.text().left(cursorPositionInEditor - block.position()).toUtf8().size();
|
||||
}
|
||||
|
||||
int extraOffsetFromStartOfFile = 0;
|
||||
int extraEmptySpaceOffset = 0;
|
||||
int rangeStart = 0;
|
||||
if (replacementsToKeep != ReplacementsToKeep::All) {
|
||||
if (block.blockNumber() > kMaxLinesFromCurrentBlock) {
|
||||
extraOffsetFromStartOfFile
|
||||
= Utils::Text::utf8NthLineOffset(block.document(),
|
||||
buffer,
|
||||
block.blockNumber() - kMaxLinesFromCurrentBlock);
|
||||
}
|
||||
int endOffset = Utils::Text::utf8NthLineOffset(block.document(),
|
||||
buffer,
|
||||
block.blockNumber()
|
||||
+ kMaxLinesFromCurrentBlock);
|
||||
if (endOffset == -1)
|
||||
endOffset = buffer.size();
|
||||
|
||||
|
||||
if (replacementsToKeep == ReplacementsToKeep::OnlyBeforeIndent)
|
||||
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
|
||||
rangeStart = formattingRangeStart(block, buffer, lastSaveRevision());
|
||||
|
||||
buffer = buffer.mid(extraOffsetFromStartOfFile, endOffset - extraOffsetFromStartOfFile);
|
||||
utf8Offset -= extraOffsetFromStartOfFile;
|
||||
rangeStart -= extraOffsetFromStartOfFile;
|
||||
|
||||
extraEmptySpaceOffset = previousEmptyLinesLength(block);
|
||||
utf8Offset -= extraEmptySpaceOffset;
|
||||
buffer.remove(utf8Offset, extraEmptySpaceOffset);
|
||||
|
||||
if (replacementsToKeep == ReplacementsToKeep::OnlyIndent)
|
||||
adjustFormatStyleForLineBreak(style);
|
||||
adjustFormatStyleForLineBreak(style, replacementsToKeep);
|
||||
modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block, secondTry);
|
||||
|
||||
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore) {
|
||||
buffer.insert(utf8Offset - 1, " //");
|
||||
extraEmptySpaceOffset -= 3;
|
||||
utf8Offset += 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (replacementsToKeep != ReplacementsToKeep::OnlyBeforeIndent || utf8Offset < rangeStart)
|
||||
if (replacementsToKeep != ReplacementsToKeep::IndentAndBefore || utf8Offset < rangeStart)
|
||||
rangeStart = utf8Offset;
|
||||
|
||||
unsigned int rangeLength = static_cast<unsigned int>(utf8Offset + utf8Length - rangeStart);
|
||||
@@ -658,7 +633,6 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer
|
||||
filtered = filteredReplacements(clangReplacements,
|
||||
utf8Offset,
|
||||
utf8LineLengthBeforeCursor,
|
||||
extraOffsetFromStartOfFile,
|
||||
extraEmptySpaceOffset,
|
||||
replacementsToKeep);
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
namespace ClangFormat {
|
||||
|
||||
enum class ReplacementsToKeep { OnlyIndent, OnlyBeforeIndent, All };
|
||||
enum class ReplacementsToKeep { OnlyIndent, IndentAndBefore, All };
|
||||
|
||||
class ClangFormatBaseIndenter : public TextEditor::Indenter
|
||||
{
|
||||
@@ -79,9 +79,9 @@ private:
|
||||
void indent(const QTextCursor &cursor, const QChar &typedChar, int cursorPositionInEditor);
|
||||
void indentBlock(const QTextBlock &block, const QChar &typedChar, int cursorPositionInEditor);
|
||||
int indentFor(const QTextBlock &block, int cursorPositionInEditor);
|
||||
int indentBeforeCursor(const QTextBlock &block,
|
||||
const QChar &typedChar,
|
||||
int cursorPositionInEditor);
|
||||
void indentBeforeCursor(const QTextBlock &block,
|
||||
const QChar &typedChar,
|
||||
int cursorPositionInEditor);
|
||||
TextEditor::Replacements replacements(QByteArray buffer,
|
||||
int utf8Offset,
|
||||
int utf8Length,
|
||||
|
@@ -52,7 +52,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ClangTools::ClangToolsBasicSettings" name="clangToolsBasicSettings" native="true"/>
|
||||
<widget class="ClangTools::Internal::ClangToolsBasicSettings" name="clangToolsBasicSettings" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@@ -87,7 +87,7 @@
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ClangTools::ClangToolsBasicSettings</class>
|
||||
<class>ClangTools::Internal::ClangToolsBasicSettings</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>clangtools/clangtoolsbasicsettings.h</header>
|
||||
</customwidget>
|
||||
|
@@ -219,7 +219,7 @@ ClangTidyClazyTool::ClangTidyClazyTool()
|
||||
m_diagnosticView->sortByColumn(Debugger::DetailedErrorView::DiagnosticColumn,
|
||||
Qt::AscendingOrder);
|
||||
m_diagnosticView->setObjectName(QLatin1String("ClangTidyClazyIssuesView"));
|
||||
m_diagnosticView->setWindowTitle(tr("Clang-Tidy and Clazy Issues"));
|
||||
m_diagnosticView->setWindowTitle(tr("Clang-Tidy and Clazy Diagnostics"));
|
||||
|
||||
foreach (auto * const model,
|
||||
QList<QAbstractItemModel *>({m_diagnosticModel, m_diagnosticFilterModel})) {
|
||||
@@ -281,7 +281,7 @@ ClangTidyClazyTool::ClangTidyClazyTool()
|
||||
// Filter line edit
|
||||
m_filterLineEdit = new Utils::FancyLineEdit();
|
||||
m_filterLineEdit->setFiltering(true);
|
||||
m_filterLineEdit->setPlaceholderText(tr("Filter Issues"));
|
||||
m_filterLineEdit->setPlaceholderText(tr("Filter Diagnostics"));
|
||||
m_filterLineEdit->setHistoryCompleter("CppTools.ClangTidyClazyIssueFilter", true);
|
||||
connect(m_filterLineEdit, &Utils::FancyLineEdit::filterChanged, [this](const QString &filter) {
|
||||
m_diagnosticFilterModel->setFilterRegExp(
|
||||
@@ -309,7 +309,7 @@ ClangTidyClazyTool::ClangTidyClazyTool()
|
||||
|
||||
ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER);
|
||||
const QString toolTip = tr("Clang-Tidy and Clazy use a customized Clang executable from the "
|
||||
"Clang project to search for errors and warnings.");
|
||||
"Clang project to search for diagnostics.");
|
||||
|
||||
m_perspective.addWindow(m_diagnosticView, Perspective::SplitVertical, nullptr);
|
||||
|
||||
@@ -450,14 +450,14 @@ void ClangTidyClazyTool::handleStateUpdate()
|
||||
QString message;
|
||||
if (m_running) {
|
||||
if (issuesFound)
|
||||
message = tr("Running - %n issues found", nullptr, issuesFound);
|
||||
message = tr("Running - %n diagnostics", nullptr, issuesFound);
|
||||
else
|
||||
message = tr("Running - No issues found", nullptr, issuesFound);
|
||||
message = tr("Running - No diagnostics", nullptr, issuesFound);
|
||||
} else {
|
||||
if (issuesFound)
|
||||
message = tr("Finished - %n issues found", nullptr, issuesFound);
|
||||
message = tr("Finished - %n diagnostics", nullptr, issuesFound);
|
||||
else
|
||||
message = tr("Finished - No issues found", nullptr, issuesFound);
|
||||
message = tr("Finished - No diagnostics", nullptr, issuesFound);
|
||||
}
|
||||
|
||||
Debugger::showPermanentStatusMessage(message);
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fancymainwindow.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
@@ -137,7 +138,10 @@ void ClangTool::initDiagnosticView()
|
||||
|
||||
QSet<Diagnostic> ClangTool::diagnostics() const
|
||||
{
|
||||
return m_diagnosticModel->diagnostics();
|
||||
return Utils::filtered(m_diagnosticModel->diagnostics(), [](const Diagnostic &diagnostic) {
|
||||
using CppTools::ProjectFile;
|
||||
return ProjectFile::isSource(ProjectFile::classify(diagnostic.location.filePath));
|
||||
});
|
||||
}
|
||||
|
||||
void ClangTool::onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics)
|
||||
|
@@ -267,6 +267,8 @@ void ClangToolRunControl::init()
|
||||
|
||||
void ClangToolRunControl::start()
|
||||
{
|
||||
TaskHub::clearTasks(Debugger::Constants::ANALYZERTASK_ID);
|
||||
|
||||
if (ClangToolsSettings::instance()->savedBuildBeforeAnalysis()) {
|
||||
QTC_ASSERT(m_projectBuilder, return;);
|
||||
if (!m_projectBuilder->success()) {
|
||||
@@ -441,7 +443,7 @@ void ClangToolRunControl::onRunnerFinishedWithFailure(const QString &errorMessag
|
||||
m_success = false;
|
||||
appendMessage(message, Utils::StdErrFormat);
|
||||
appendMessage(errorDetails, Utils::StdErrFormat);
|
||||
TaskHub::addTask(Task::Warning, message, Debugger::Constants::ANALYZERTASK_ID);
|
||||
TaskHub::addTask(Task::Error, message, Debugger::Constants::ANALYZERTASK_ID);
|
||||
handleFinished();
|
||||
}
|
||||
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "clangtoolsutils.h"
|
||||
|
||||
namespace ClangTools {
|
||||
namespace Internal {
|
||||
|
||||
ClangToolsBasicSettings::ClangToolsBasicSettings(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@@ -47,4 +48,5 @@ Ui::ClangToolsBasicSettings *ClangToolsBasicSettings::ui()
|
||||
return m_ui;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangTools
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include <QWidget>
|
||||
|
||||
namespace ClangTools {
|
||||
namespace Internal {
|
||||
|
||||
namespace Ui { class ClangToolsBasicSettings; }
|
||||
|
||||
@@ -46,4 +47,5 @@ private:
|
||||
Ui::ClangToolsBasicSettings *m_ui;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClangTools
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ClangTools::ClangToolsBasicSettings</class>
|
||||
<widget class="QWidget" name="ClangTools::ClangToolsBasicSettings">
|
||||
<class>ClangTools::Internal::ClangToolsBasicSettings</class>
|
||||
<widget class="QWidget" name="ClangTools::Internal::ClangToolsBasicSettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@@ -21,7 +21,7 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="ClangTools::ClangToolsBasicSettings" name="clangToolsBasicSettings" native="true"/>
|
||||
<widget class="ClangTools::Internal::ClangToolsBasicSettings" name="clangToolsBasicSettings" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="processesLayout">
|
||||
@@ -77,7 +77,7 @@
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ClangTools::ClangToolsBasicSettings</class>
|
||||
<class>ClangTools::Internal::ClangToolsBasicSettings</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>clangtools/clangtoolsbasicsettings.h</header>
|
||||
</customwidget>
|
||||
|
@@ -84,7 +84,7 @@ ClangToolsDiagnosticModel::ClangToolsDiagnosticModel(QObject *parent)
|
||||
: Utils::TreeModel<>(parent)
|
||||
, m_filesWatcher(std::make_unique<QFileSystemWatcher>())
|
||||
{
|
||||
setHeader({tr("Issue"), tr("Fixit Status")});
|
||||
setHeader({tr("Diagnostic")});
|
||||
connectFileWatcher();
|
||||
}
|
||||
|
||||
@@ -192,7 +192,26 @@ void ClangToolsDiagnosticModel::addWatchedPath(const QString &path)
|
||||
m_filesWatcher->addPath(path);
|
||||
}
|
||||
|
||||
static QString createDiagnosticToolTipString(const Diagnostic &diagnostic)
|
||||
static QString fixitStatus(FixitStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
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 QString();
|
||||
}
|
||||
|
||||
static QString createDiagnosticToolTipString(const Diagnostic &diagnostic, FixitStatus fixItStatus)
|
||||
{
|
||||
using StringPair = QPair<QString, QString>;
|
||||
QList<StringPair> lines;
|
||||
@@ -226,6 +245,10 @@ static QString createDiagnosticToolTipString(const Diagnostic &diagnostic)
|
||||
QCoreApplication::translate("ClangTools::Diagnostic", "Location:"),
|
||||
createFullLocationString(diagnostic.location));
|
||||
|
||||
lines << qMakePair(
|
||||
QCoreApplication::translate("ClangTools::Diagnostic", "Fixit Status:"),
|
||||
fixitStatus(fixItStatus));
|
||||
|
||||
QString html = QLatin1String("<html>"
|
||||
"<head>"
|
||||
"<style>dt { font-weight:bold; } dd { font-family: monospace; }</style>\n"
|
||||
@@ -364,19 +387,8 @@ DiagnosticItem::~DiagnosticItem()
|
||||
Qt::ItemFlags DiagnosticItem::flags(int column) const
|
||||
{
|
||||
const Qt::ItemFlags itemFlags = TreeItem::flags(column);
|
||||
if (column == DiagnosticView::FixItColumn) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (column == DiagnosticView::DiagnosticColumn)
|
||||
return itemFlags | Qt::ItemIsUserCheckable;
|
||||
return itemFlags;
|
||||
}
|
||||
|
||||
@@ -395,35 +407,7 @@ static QVariant iconData(const QString &type)
|
||||
|
||||
QVariant DiagnosticItem::data(int column, int role) const
|
||||
{
|
||||
if (column == DiagnosticView::FixItColumn) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
} else if (column == DiagnosticView::DiagnosticColumn) {
|
||||
if (column == DiagnosticView::DiagnosticColumn) {
|
||||
switch (role) {
|
||||
case Debugger::DetailedErrorView::LocationRole:
|
||||
return QVariant::fromValue(m_diagnostic.location);
|
||||
@@ -433,11 +417,36 @@ QVariant DiagnosticItem::data(int column, int role) const
|
||||
return QVariant::fromValue(m_diagnostic);
|
||||
case ClangToolsDiagnosticModel::TextRole:
|
||||
return m_diagnostic.description;
|
||||
case ClangToolsDiagnosticModel::CheckBoxEnabledRole:
|
||||
switch (m_fixitStatus) {
|
||||
case FixitStatus::NotAvailable:
|
||||
case FixitStatus::Applied:
|
||||
case FixitStatus::FailedToApply:
|
||||
case FixitStatus::Invalidated:
|
||||
return false;
|
||||
case FixitStatus::Scheduled:
|
||||
case FixitStatus::NotScheduled:
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case Qt::CheckStateRole: {
|
||||
switch (m_fixitStatus) {
|
||||
case FixitStatus::NotAvailable:
|
||||
case FixitStatus::Invalidated:
|
||||
case FixitStatus::Applied:
|
||||
case FixitStatus::FailedToApply:
|
||||
case FixitStatus::NotScheduled:
|
||||
return Qt::Unchecked;
|
||||
case FixitStatus::Scheduled:
|
||||
return Qt::Checked;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::DisplayRole:
|
||||
return QString("%1: %2").arg(lineColumnString(m_diagnostic.location),
|
||||
m_diagnostic.description);
|
||||
case Qt::ToolTipRole:
|
||||
return createDiagnosticToolTipString(m_diagnostic);
|
||||
return createDiagnosticToolTipString(m_diagnostic, m_fixitStatus);
|
||||
case Qt::DecorationRole:
|
||||
return iconData(m_diagnostic.type);
|
||||
default:
|
||||
@@ -450,7 +459,7 @@ 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) {
|
||||
if (column == DiagnosticView::DiagnosticColumn && role == Qt::CheckStateRole) {
|
||||
if (m_fixitStatus != FixitStatus::Scheduled && m_fixitStatus != FixitStatus::NotScheduled)
|
||||
return false;
|
||||
|
||||
@@ -494,15 +503,6 @@ ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step, int index)
|
||||
, m_index(index)
|
||||
{}
|
||||
|
||||
// We expect something like "note: ..."
|
||||
static QVariant iconForExplainingStepMessage(const QString &message)
|
||||
{
|
||||
const int index = message.indexOf(':');
|
||||
if (index == -1)
|
||||
return QVariant();
|
||||
return iconData(message.mid(0, index));
|
||||
}
|
||||
|
||||
static QString rangeString(const QVector<Debugger::DiagnosticLocation> &ranges)
|
||||
{
|
||||
return QString("%1-%2").arg(lineColumnString(ranges[0]), lineColumnString(ranges[1]));
|
||||
@@ -510,9 +510,6 @@ static QString rangeString(const QVector<Debugger::DiagnosticLocation> &ranges)
|
||||
|
||||
QVariant ExplainingStepItem::data(int column, int role) const
|
||||
{
|
||||
if (column == DiagnosticView::FixItColumn)
|
||||
return QVariant();
|
||||
|
||||
if (column == DiagnosticView::DiagnosticColumn) {
|
||||
// DiagnosticColumn
|
||||
switch (role) {
|
||||
@@ -555,7 +552,7 @@ QVariant ExplainingStepItem::data(int column, int role) const
|
||||
case Qt::DecorationRole:
|
||||
if (m_step.isFixIt)
|
||||
return Utils::Icons::CODEMODEL_FIXIT.icon();
|
||||
return iconForExplainingStepMessage(m_step.message);
|
||||
return Utils::Icons::INFO.icon();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
@@ -112,7 +112,11 @@ public:
|
||||
void addDiagnostics(const QList<Diagnostic> &diagnostics);
|
||||
QSet<Diagnostic> diagnostics() const;
|
||||
|
||||
enum ItemRole { DiagnosticRole = Debugger::DetailedErrorView::FullTextRole + 1, TextRole };
|
||||
enum ItemRole {
|
||||
DiagnosticRole = Debugger::DetailedErrorView::FullTextRole + 1,
|
||||
TextRole,
|
||||
CheckBoxEnabledRole
|
||||
};
|
||||
|
||||
void clear();
|
||||
void removeWatchedPath(const QString &path);
|
||||
|
@@ -30,11 +30,13 @@
|
||||
#include "clangtoolsutils.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/manhattanstyle.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QHeaderView>
|
||||
#include <QPainter>
|
||||
@@ -44,21 +46,22 @@ using namespace Debugger;
|
||||
namespace ClangTools {
|
||||
namespace Internal {
|
||||
|
||||
class ClickableFixItHeader : public QHeaderView
|
||||
// A header view that puts a check box in front of a given column.
|
||||
class HeaderWithCheckBoxInColumn : public QHeaderView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ClickableFixItHeader(Qt::Orientation orientation, QWidget *parent = nullptr)
|
||||
HeaderWithCheckBoxInColumn(Qt::Orientation orientation,
|
||||
int column = 0,
|
||||
QWidget *parent = nullptr)
|
||||
: QHeaderView(orientation, parent)
|
||||
, m_column(column)
|
||||
{
|
||||
setDefaultAlignment(Qt::AlignLeft);
|
||||
}
|
||||
|
||||
void setState(QFlags<QStyle::StateFlag> newState)
|
||||
{
|
||||
state = newState;
|
||||
}
|
||||
void setState(QFlags<QStyle::StateFlag> newState) { state = newState; }
|
||||
|
||||
protected:
|
||||
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const override
|
||||
@@ -66,7 +69,7 @@ protected:
|
||||
painter->save();
|
||||
QHeaderView::paintSection(painter, rect, logicalIndex);
|
||||
painter->restore();
|
||||
if (logicalIndex == DiagnosticView::FixItColumn) {
|
||||
if (logicalIndex == m_column) {
|
||||
QStyleOptionButton option;
|
||||
const int side = sizeHint().height();
|
||||
option.rect = QRect(rect.left() + 1, 1, side - 3, side - 3);
|
||||
@@ -83,34 +86,111 @@ protected:
|
||||
void mouseReleaseEvent(QMouseEvent *event) override
|
||||
{
|
||||
const int x = event->localPos().x();
|
||||
const int fixItColumnX = sectionPosition(DiagnosticView::FixItColumn);
|
||||
const bool isWithinFixitCheckBox = x > fixItColumnX
|
||||
&& x < fixItColumnX + sizeHint().height() - 3;
|
||||
if (isWithinFixitCheckBox) {
|
||||
const int columnX = sectionPosition(m_column);
|
||||
const bool isWithinCheckBox = x > columnX && x < columnX + sizeHint().height() - 3;
|
||||
if (isWithinCheckBox) {
|
||||
state = (state != QStyle::State_On) ? QStyle::State_On : QStyle::State_Off;
|
||||
viewport()->update();
|
||||
emit fixItColumnClicked(state == QStyle::State_On);
|
||||
emit checkBoxClicked(state == QStyle::State_On);
|
||||
return; // Avoid changing sort order
|
||||
}
|
||||
QHeaderView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
signals:
|
||||
void fixItColumnClicked(bool checked);
|
||||
void checkBoxClicked(bool checked);
|
||||
|
||||
private:
|
||||
const int m_column = 0;
|
||||
QFlags<QStyle::StateFlag> state = QStyle::State_Off;
|
||||
};
|
||||
|
||||
static QString getBaseStyleName()
|
||||
{
|
||||
QStyle *style = QApplication::style();
|
||||
if (auto proxyStyle = qobject_cast<QProxyStyle *>(style))
|
||||
style = proxyStyle->baseStyle();
|
||||
return style->objectName();
|
||||
}
|
||||
|
||||
// Paints the check box indicator disabled if requested by client.
|
||||
class DiagnosticViewStyle : public ManhattanStyle
|
||||
{
|
||||
public:
|
||||
DiagnosticViewStyle(const QString &baseStyleName = getBaseStyleName())
|
||||
: ManhattanStyle(baseStyleName)
|
||||
{}
|
||||
|
||||
void setPaintCheckBoxDisabled(bool paintDisabledCheckbox)
|
||||
{
|
||||
m_paintCheckBoxDisabled = paintDisabledCheckbox;
|
||||
}
|
||||
|
||||
void drawPrimitive(PrimitiveElement element,
|
||||
const QStyleOption *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget = nullptr) const final
|
||||
{
|
||||
if (element == QStyle::PE_IndicatorCheckBox && m_paintCheckBoxDisabled) {
|
||||
if (const QStyleOptionButton *o = qstyleoption_cast<const QStyleOptionButton *>(
|
||||
option)) {
|
||||
QStyleOptionButton myOption = *o;
|
||||
myOption.palette.setCurrentColorGroup(QPalette::Disabled);
|
||||
ManhattanStyle::drawPrimitive(element, &myOption, painter, widget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ManhattanStyle::drawPrimitive(element, option, painter, widget);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_paintCheckBoxDisabled = false;
|
||||
};
|
||||
|
||||
// A delegate that allows to paint a disabled check box (indicator).
|
||||
// This is useful if the rest of the item should not be disabled.
|
||||
class DiagnosticViewDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DiagnosticViewDelegate(DiagnosticViewStyle *style)
|
||||
: m_style(style)
|
||||
{}
|
||||
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const final
|
||||
{
|
||||
const bool paintDisabled = !index.data(ClangToolsDiagnosticModel::CheckBoxEnabledRole)
|
||||
.toBool();
|
||||
if (paintDisabled)
|
||||
m_style->setPaintCheckBoxDisabled(true);
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
if (paintDisabled)
|
||||
m_style->setPaintCheckBoxDisabled(false);
|
||||
}
|
||||
|
||||
private:
|
||||
DiagnosticViewStyle *m_style = nullptr;
|
||||
};
|
||||
|
||||
DiagnosticView::DiagnosticView(QWidget *parent)
|
||||
: Debugger::DetailedErrorView(parent)
|
||||
, m_style(new DiagnosticViewStyle)
|
||||
, m_delegate(new DiagnosticViewDelegate(m_style.get()))
|
||||
{
|
||||
m_suppressAction = new QAction(tr("Suppress This Diagnostic"), this);
|
||||
connect(m_suppressAction, &QAction::triggered,
|
||||
this, &DiagnosticView::suppressCurrentDiagnostic);
|
||||
installEventFilter(this);
|
||||
|
||||
setStyle(m_style.get());
|
||||
setItemDelegate(m_delegate.get());
|
||||
}
|
||||
|
||||
DiagnosticView::~DiagnosticView() = default;
|
||||
|
||||
void DiagnosticView::suppressCurrentDiagnostic()
|
||||
{
|
||||
const QModelIndexList indexes = selectionModel()->selectedRows();
|
||||
@@ -199,7 +279,6 @@ bool DiagnosticView::eventFilter(QObject *watched, QEvent *event)
|
||||
switch (key) {
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
case Qt::Key_Space:
|
||||
openEditorForCurrentIndex();
|
||||
}
|
||||
return true;
|
||||
@@ -219,11 +298,11 @@ void DiagnosticView::setSelectedFixItsCount(int fixItsCount)
|
||||
{
|
||||
if (m_ignoreSetSelectedFixItsCount)
|
||||
return;
|
||||
auto *clickableFixItHeader = static_cast<ClickableFixItHeader *>(header());
|
||||
clickableFixItHeader->setState(fixItsCount
|
||||
? (QStyle::State_NoChange | QStyle::State_On | QStyle::State_Off)
|
||||
: QStyle::State_Off);
|
||||
clickableFixItHeader->viewport()->update();
|
||||
auto checkBoxHeader = static_cast<HeaderWithCheckBoxInColumn *>(header());
|
||||
checkBoxHeader->setState(fixItsCount
|
||||
? (QStyle::State_NoChange | QStyle::State_On | QStyle::State_Off)
|
||||
: QStyle::State_Off);
|
||||
checkBoxHeader->viewport()->update();
|
||||
}
|
||||
|
||||
void DiagnosticView::openEditorForCurrentIndex()
|
||||
@@ -237,28 +316,31 @@ void DiagnosticView::openEditorForCurrentIndex()
|
||||
void DiagnosticView::setModel(QAbstractItemModel *theProxyModel)
|
||||
{
|
||||
const auto proxyModel = static_cast<QSortFilterProxyModel *>(theProxyModel);
|
||||
const auto sourceModel = static_cast<ClangToolsDiagnosticModel *>(proxyModel->sourceModel());
|
||||
|
||||
Debugger::DetailedErrorView::setModel(proxyModel);
|
||||
auto *clickableFixItHeader = new ClickableFixItHeader(Qt::Horizontal, this);
|
||||
connect(clickableFixItHeader, &ClickableFixItHeader::fixItColumnClicked, this, [=](bool checked) {
|
||||
|
||||
auto *header = new HeaderWithCheckBoxInColumn(Qt::Horizontal,
|
||||
DiagnosticView::DiagnosticColumn,
|
||||
this);
|
||||
connect(header, &HeaderWithCheckBoxInColumn::checkBoxClicked, this, [=](bool checked) {
|
||||
m_ignoreSetSelectedFixItsCount = true;
|
||||
sourceModel->rootItem()->forChildrenAtLevel(2, [&](::Utils::TreeItem *item) {
|
||||
auto diagnosticItem = static_cast<DiagnosticItem *>(item);
|
||||
diagnosticItem->setData(FixItColumn,
|
||||
checked ? Qt::Checked : Qt::Unchecked,
|
||||
Qt::CheckStateRole);
|
||||
});
|
||||
for (int i = 0, count = proxyModel->rowCount(); i < count; ++i) {
|
||||
const QModelIndex filePathItemIndex = proxyModel->index(i, 0);
|
||||
for (int j = 0, count = proxyModel->rowCount(filePathItemIndex); j < count; ++j) {
|
||||
const QModelIndex proxyIndex = proxyModel->index(j, 0, filePathItemIndex);
|
||||
const QModelIndex diagnosticItemIndex = proxyModel->mapToSource(proxyIndex);
|
||||
auto item = static_cast<DiagnosticItem *>(diagnosticItemIndex.internalPointer());
|
||||
item->setData(DiagnosticView::DiagnosticColumn,
|
||||
checked ? Qt::Checked : Qt::Unchecked,
|
||||
Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
m_ignoreSetSelectedFixItsCount = false;
|
||||
});
|
||||
setHeader(clickableFixItHeader);
|
||||
clickableFixItHeader->setStretchLastSection(false);
|
||||
clickableFixItHeader->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
clickableFixItHeader->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
|
||||
const int fixitColumnWidth = clickableFixItHeader->sectionSizeHint(DiagnosticView::FixItColumn);
|
||||
const int checkboxWidth = clickableFixItHeader->height();
|
||||
clickableFixItHeader->setMinimumSectionSize(fixitColumnWidth + 1.2 * checkboxWidth);
|
||||
setHeader(header);
|
||||
header->setSectionResizeMode(DiagnosticView::DiagnosticColumn, QHeaderView::Stretch);
|
||||
const int columnWidth = header->sectionSizeHint(DiagnosticView::DiagnosticColumn);
|
||||
const int checkboxWidth = header->height();
|
||||
header->setMinimumSectionSize(columnWidth + 1.2 * checkboxWidth);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -27,19 +27,21 @@
|
||||
|
||||
#include <debugger/analyzer/detailederrorview.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace ClangTools {
|
||||
namespace Internal {
|
||||
|
||||
class DiagnosticViewStyle;
|
||||
class DiagnosticViewDelegate;
|
||||
|
||||
class DiagnosticView : public Debugger::DetailedErrorView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DiagnosticView(QWidget *parent = nullptr);
|
||||
|
||||
enum ExtraColumn {
|
||||
FixItColumn = DiagnosticColumn + 1,
|
||||
};
|
||||
~DiagnosticView() override;
|
||||
|
||||
void setSelectedFixItsCount(int fixItsCount);
|
||||
|
||||
@@ -59,6 +61,8 @@ private:
|
||||
void setModel(QAbstractItemModel *theProxyModel) override;
|
||||
|
||||
QAction *m_suppressAction;
|
||||
std::unique_ptr<DiagnosticViewStyle> m_style;
|
||||
std::unique_ptr<DiagnosticViewDelegate> m_delegate;
|
||||
bool m_ignoreSetSelectedFixItsCount = false;
|
||||
};
|
||||
|
||||
|
@@ -94,7 +94,7 @@ static ExplainingStep buildChildDiagnostic(const CXDiagnostic cxDiagnostic)
|
||||
|
||||
const CXSourceLocation cxLocation = clang_getDiagnosticLocation(cxDiagnostic);
|
||||
diagnosticStep.location = diagLocationFromSourceLocation(cxLocation);
|
||||
diagnosticStep.message = type + ": " + fromCXString(clang_getDiagnosticSpelling(cxDiagnostic));
|
||||
diagnosticStep.message = fromCXString(clang_getDiagnosticSpelling(cxDiagnostic));
|
||||
return diagnosticStep;
|
||||
}
|
||||
|
||||
|
@@ -270,7 +270,7 @@ static const HelpItem::Links getBestLink(const HelpItem::Links &links)
|
||||
|
||||
const HelpItem::Links HelpItem::bestLinks() const
|
||||
{
|
||||
if (m_isFuzzyMatch)
|
||||
if (isFuzzyMatch())
|
||||
return getBestLinks(links());
|
||||
return getBestLink(links());
|
||||
}
|
||||
@@ -279,3 +279,10 @@ const QString HelpItem::keyword() const
|
||||
{
|
||||
return m_keyword;
|
||||
}
|
||||
|
||||
bool HelpItem::isFuzzyMatch() const
|
||||
{
|
||||
// make sure m_isFuzzyMatch is correct
|
||||
links();
|
||||
return m_isFuzzyMatch;
|
||||
}
|
||||
|
@@ -86,6 +86,8 @@ public:
|
||||
const QString keyword() const;
|
||||
|
||||
private:
|
||||
bool isFuzzyMatch() const;
|
||||
|
||||
QUrl m_helpUrl;
|
||||
QStringList m_helpIds;
|
||||
QString m_docMark;
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 515 B |
Before Width: | Height: | Size: 650 B After Width: | Height: | Size: 557 B |
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 976 B After Width: | Height: | Size: 790 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -41,6 +41,7 @@
|
||||
|
||||
#include <QDir>
|
||||
#include <QRegularExpression>
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
@@ -701,6 +702,10 @@ void CompilerOptionsBuilder::reset()
|
||||
// QMakeProject: -pipe -Whello -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC
|
||||
void CompilerOptionsBuilder::evaluateCompilerFlags()
|
||||
{
|
||||
static QStringList userBlackList = QString::fromLocal8Bit(
|
||||
qgetenv("QTC_CLANG_CMD_OPTIONS_BLACKLIST"))
|
||||
.split(';', QString::SkipEmptyParts);
|
||||
|
||||
bool containsDriverMode = false;
|
||||
bool skipNext = false;
|
||||
for (const QString &option : m_projectPart.compilerFlags) {
|
||||
@@ -709,6 +714,9 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (userBlackList.contains(option))
|
||||
continue;
|
||||
|
||||
// Ignore warning flags as these interfere with our user-configured diagnostics.
|
||||
// Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows.
|
||||
if (m_useBuildSystemWarnings == UseBuildSystemWarnings::No
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "cpphoverhandler.h"
|
||||
|
||||
#include "cppelementevaluator.h"
|
||||
#include "cpptoolsreuse.h"
|
||||
|
||||
#include <coreplugin/helpmanager.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
@@ -56,14 +57,16 @@ void CppHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos, Rep
|
||||
tip += evaluator.diagnosis();
|
||||
setPriority(Priority_Diagnostic);
|
||||
}
|
||||
const QStringList fallback = identifierWordsUnderCursor(tc);
|
||||
if (evaluator.identifiedCppElement()) {
|
||||
const QSharedPointer<CppElement> &cppElement = evaluator.cppElement();
|
||||
QStringList candidates = cppElement->helpIdCandidates;
|
||||
candidates.removeDuplicates();
|
||||
const HelpItem helpItem(candidates, cppElement->helpMark, cppElement->helpCategory);
|
||||
const QStringList candidates = cppElement->helpIdCandidates;
|
||||
const HelpItem helpItem(candidates + fallback, cppElement->helpMark, cppElement->helpCategory);
|
||||
setLastHelpItemIdentified(helpItem); // tool tip appended by decorateToolTip
|
||||
if (!helpItem.isValid())
|
||||
tip += cppElement->tooltip;
|
||||
} else {
|
||||
setLastHelpItemIdentified({fallback, {}, HelpItem::Unknown});
|
||||
}
|
||||
setToolTip(tip);
|
||||
}
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
#include <QStringRef>
|
||||
#include <QTextCursor>
|
||||
@@ -50,29 +51,91 @@ using namespace CPlusPlus;
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
static void moveCursorToStartOrEndOfIdentifier(QTextCursor *tc,
|
||||
QTextCursor::MoveOperation op,
|
||||
int posDiff = 0)
|
||||
static int skipChars(QTextCursor *tc,
|
||||
QTextCursor::MoveOperation op,
|
||||
int offset,
|
||||
std::function<bool(const QChar &)> skip)
|
||||
{
|
||||
QTextDocument *doc = tc->document();
|
||||
const QTextDocument *doc = tc->document();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
QChar ch = doc->characterAt(tc->position() - posDiff);
|
||||
while (isValidIdentifierChar(ch)) {
|
||||
tc->movePosition(op);
|
||||
ch = doc->characterAt(tc->position() - posDiff);
|
||||
return 0;
|
||||
QChar ch = doc->characterAt(tc->position() + offset);
|
||||
if (ch.isNull())
|
||||
return 0;
|
||||
int count = 0;
|
||||
while (skip(ch)) {
|
||||
if (tc->movePosition(op))
|
||||
++count;
|
||||
else
|
||||
break;
|
||||
ch = doc->characterAt(tc->position() + offset);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int skipCharsForward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
|
||||
{
|
||||
return skipChars(tc, QTextCursor::NextCharacter, 0, skip);
|
||||
}
|
||||
|
||||
static int skipCharsBackward(QTextCursor *tc, std::function<bool(const QChar &)> skip)
|
||||
{
|
||||
return skipChars(tc, QTextCursor::PreviousCharacter, -1, skip);
|
||||
}
|
||||
|
||||
QStringList identifierWordsUnderCursor(const QTextCursor &tc)
|
||||
{
|
||||
const QTextDocument *document = tc.document();
|
||||
if (!document)
|
||||
return {};
|
||||
const auto isSpace = [](const QChar &c) { return c.isSpace(); };
|
||||
const auto isColon = [](const QChar &c) { return c == ':'; };
|
||||
const auto isValidIdentifierCharAt = [document](const QTextCursor &tc) {
|
||||
return isValidIdentifierChar(document->characterAt(tc.position()));
|
||||
};
|
||||
// move to the end
|
||||
QTextCursor endCursor(tc);
|
||||
do {
|
||||
moveCursorToEndOfIdentifier(&endCursor);
|
||||
// possibly skip ::
|
||||
QTextCursor temp(endCursor);
|
||||
skipCharsForward(&temp, isSpace);
|
||||
const int colons = skipCharsForward(&temp, isColon);
|
||||
skipCharsForward(&temp, isSpace);
|
||||
if (colons == 2 && isValidIdentifierCharAt(temp))
|
||||
endCursor = temp;
|
||||
} while (isValidIdentifierCharAt(endCursor));
|
||||
|
||||
QStringList results;
|
||||
QTextCursor startCursor(endCursor);
|
||||
do {
|
||||
moveCursorToStartOfIdentifier(&startCursor);
|
||||
if (startCursor.position() == endCursor.position())
|
||||
break;
|
||||
QTextCursor temp(endCursor);
|
||||
temp.setPosition(startCursor.position(), QTextCursor::KeepAnchor);
|
||||
results.append(temp.selectedText().remove(QRegularExpression("\\s")));
|
||||
// possibly skip ::
|
||||
temp = startCursor;
|
||||
skipCharsBackward(&temp, isSpace);
|
||||
const int colons = skipCharsBackward(&temp, isColon);
|
||||
skipCharsBackward(&temp, isSpace);
|
||||
if (colons == 2
|
||||
&& isValidIdentifierChar(document->characterAt(temp.position() - 1))) {
|
||||
startCursor = temp;
|
||||
}
|
||||
} while (!isValidIdentifierCharAt(startCursor));
|
||||
return results;
|
||||
}
|
||||
|
||||
void moveCursorToEndOfIdentifier(QTextCursor *tc)
|
||||
{
|
||||
moveCursorToStartOrEndOfIdentifier(tc, QTextCursor::NextCharacter);
|
||||
skipCharsForward(tc, isValidIdentifierChar);
|
||||
}
|
||||
|
||||
void moveCursorToStartOfIdentifier(QTextCursor *tc)
|
||||
{
|
||||
moveCursorToStartOrEndOfIdentifier(tc, QTextCursor::PreviousCharacter, 1);
|
||||
skipCharsBackward(tc, isValidIdentifierChar);
|
||||
}
|
||||
|
||||
static bool isOwnershipRAIIName(const QString &name)
|
||||
|
@@ -58,6 +58,7 @@ bool CPPTOOLS_EXPORT isValidFirstIdentifierChar(const QChar &ch);
|
||||
bool CPPTOOLS_EXPORT isValidIdentifierChar(const QChar &ch);
|
||||
bool CPPTOOLS_EXPORT isValidIdentifier(const QString &s);
|
||||
|
||||
QStringList CPPTOOLS_EXPORT identifierWordsUnderCursor(const QTextCursor &tc);
|
||||
QString CPPTOOLS_EXPORT identifierUnderCursor(QTextCursor *cursor);
|
||||
|
||||
bool CPPTOOLS_EXPORT isOwnershipRAIIType(CPlusPlus::Symbol *symbol,
|
||||
|
@@ -69,6 +69,7 @@ class TextMark : public TextEditor::TextMark
|
||||
public:
|
||||
TextMark(const Utils::FileName &fileName, const Diagnostic &diag)
|
||||
: TextEditor::TextMark(fileName, diag.range().start().line() + 1, "lspmark")
|
||||
, m_diagnostic(diag)
|
||||
{
|
||||
using namespace Utils;
|
||||
setLineAnnotation(diag.message());
|
||||
@@ -81,11 +82,17 @@ public:
|
||||
setIcon(isError ? Icons::CODEMODEL_ERROR.icon()
|
||||
: Icons::CODEMODEL_WARNING.icon());
|
||||
}
|
||||
|
||||
const Diagnostic &diagnostic() const { return m_diagnostic; }
|
||||
|
||||
private:
|
||||
const Diagnostic m_diagnostic;
|
||||
};
|
||||
|
||||
Client::Client(BaseClientInterface *clientInterface)
|
||||
: m_id(Core::Id::fromString(QUuid::createUuid().toString()))
|
||||
, m_completionProvider(this)
|
||||
, m_quickFixProvider(this)
|
||||
, m_clientInterface(clientInterface)
|
||||
{
|
||||
m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(),
|
||||
@@ -101,8 +108,10 @@ Client::~Client()
|
||||
using namespace TextEditor;
|
||||
// FIXME: instead of replacing the completion provider in the text document store the
|
||||
// completion provider as a prioritised list in the text document
|
||||
for (TextDocument *document : m_resetCompletionProvider)
|
||||
for (TextDocument *document : m_resetAssistProvider) {
|
||||
document->setCompletionAssistProvider(nullptr);
|
||||
document->setQuickFixAssistProvider(nullptr);
|
||||
}
|
||||
for (Core::IEditor * editor : Core::DocumentModel::editorsForOpenedDocuments()) {
|
||||
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor)) {
|
||||
TextEditorWidget *widget = textEditor->editorWidget();
|
||||
@@ -192,10 +201,12 @@ void Client::openDocument(Core::IDocument *document)
|
||||
documentContentsChanged(document);
|
||||
});
|
||||
if (textDocument) {
|
||||
m_resetCompletionProvider << textDocument;
|
||||
textDocument->completionAssistProvider();
|
||||
m_resetAssistProvider << textDocument;
|
||||
textDocument->setCompletionAssistProvider(&m_completionProvider);
|
||||
textDocument->setQuickFixAssistProvider(&m_quickFixProvider);
|
||||
connect(textDocument, &QObject::destroyed, this, [this, textDocument]{
|
||||
m_resetCompletionProvider.remove(textDocument);
|
||||
m_resetAssistProvider.remove(textDocument);
|
||||
});
|
||||
if (BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(textDocument)) {
|
||||
if (QPointer<TextEditorWidget> widget = editor->editorWidget()) {
|
||||
@@ -543,25 +554,10 @@ void Client::cursorPositionChanged(TextEditor::TextEditorWidget *widget)
|
||||
void Client::requestCodeActions(const DocumentUri &uri, const QList<Diagnostic> &diagnostics)
|
||||
{
|
||||
const Utils::FileName fileName = uri.toFileName();
|
||||
TextEditor::TextDocument *doc = textDocumentForFileName(fileName);
|
||||
TextEditor::TextDocument *doc = TextEditor::TextDocument::textDocumentForFileName(fileName);
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
const QString method(CodeActionRequest::methodName);
|
||||
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
||||
if (!registered.value())
|
||||
return;
|
||||
const TextDocumentRegistrationOptions option(
|
||||
m_dynamicCapabilities.option(method).toObject());
|
||||
if (option.isValid(nullptr) && !option.filterApplies(fileName))
|
||||
return;
|
||||
} else {
|
||||
Utils::variant<bool, CodeActionOptions> provider
|
||||
= m_serverCapabilities.codeActionProvider().value_or(false);
|
||||
if (!(Utils::holds_alternative<CodeActionOptions>(provider) || Utils::get<bool>(provider)))
|
||||
return;
|
||||
}
|
||||
|
||||
CodeActionParams codeActionParams;
|
||||
CodeActionParams::CodeActionContext context;
|
||||
context.setDiagnostics(diagnostics);
|
||||
@@ -577,6 +573,32 @@ void Client::requestCodeActions(const DocumentUri &uri, const QList<Diagnostic>
|
||||
if (self)
|
||||
self->handleCodeActionResponse(response, uri);
|
||||
});
|
||||
requestCodeActions(request);
|
||||
}
|
||||
|
||||
void Client::requestCodeActions(const CodeActionRequest &request)
|
||||
{
|
||||
if (!request.isValid(nullptr))
|
||||
return;
|
||||
|
||||
const Utils::FileName fileName
|
||||
= request.params().value_or(CodeActionParams()).textDocument().uri().toFileName();
|
||||
|
||||
const QString method(CodeActionRequest::methodName);
|
||||
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
|
||||
if (!registered.value())
|
||||
return;
|
||||
const TextDocumentRegistrationOptions option(
|
||||
m_dynamicCapabilities.option(method).toObject());
|
||||
if (option.isValid(nullptr) && !option.filterApplies(fileName))
|
||||
return;
|
||||
} else {
|
||||
Utils::variant<bool, CodeActionOptions> provider
|
||||
= m_serverCapabilities.codeActionProvider().value_or(false);
|
||||
if (!(Utils::holds_alternative<CodeActionOptions>(provider) || Utils::get<bool>(provider)))
|
||||
return;
|
||||
}
|
||||
|
||||
sendContent(request);
|
||||
}
|
||||
|
||||
@@ -682,6 +704,17 @@ bool Client::needsRestart(const BaseSettings *settings) const
|
||||
|| m_languagFilter.filePattern != settings->m_languageFilter.filePattern;
|
||||
}
|
||||
|
||||
QList<Diagnostic> Client::diagnosticsAt(const DocumentUri &uri, const Range &range) const
|
||||
{
|
||||
QList<Diagnostic> diagnostics;
|
||||
for (const TextMark *mark : m_diagnostics[uri]) {
|
||||
const Diagnostic diagnostic = mark->diagnostic();
|
||||
if (diagnostic.range().overlaps(range))
|
||||
diagnostics << diagnostic;
|
||||
}
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
bool Client::start()
|
||||
{
|
||||
return m_clientInterface->start();
|
||||
@@ -778,7 +811,8 @@ void Client::showMessageBox(const ShowMessageRequestParams &message, const Messa
|
||||
|
||||
void Client::showDiagnostics(const DocumentUri &uri)
|
||||
{
|
||||
if (TextEditor::TextDocument *doc = textDocumentForFileName(uri.toFileName())) {
|
||||
if (TextEditor::TextDocument *doc
|
||||
= TextEditor::TextDocument::textDocumentForFileName(uri.toFileName())) {
|
||||
for (TextMark *mark : m_diagnostics.value(uri))
|
||||
doc->addMark(mark);
|
||||
}
|
||||
@@ -786,7 +820,8 @@ void Client::showDiagnostics(const DocumentUri &uri)
|
||||
|
||||
void Client::removeDiagnostics(const DocumentUri &uri)
|
||||
{
|
||||
TextEditor::TextDocument *doc = textDocumentForFileName(uri.toFileName());
|
||||
TextEditor::TextDocument *doc
|
||||
= TextEditor::TextDocument::textDocumentForFileName(uri.toFileName());
|
||||
|
||||
for (TextMark *mark : m_diagnostics.take(uri)) {
|
||||
if (doc)
|
||||
|
@@ -26,7 +26,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "dynamiccapabilities.h"
|
||||
#include "languageclientcodeassist.h"
|
||||
#include "languageclientcompletionassist.h"
|
||||
#include "languageclientquickfix.h"
|
||||
#include "languageclientsettings.h"
|
||||
|
||||
#include <coreplugin/id.h>
|
||||
@@ -104,6 +105,7 @@ public:
|
||||
|
||||
void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri,
|
||||
const QList<LanguageServerProtocol::Diagnostic> &diagnostics);
|
||||
void requestCodeActions(const LanguageServerProtocol::CodeActionRequest &request);
|
||||
void handleCodeActionResponse(const LanguageServerProtocol::CodeActionRequest::Response &response,
|
||||
const LanguageServerProtocol::DocumentUri &uri);
|
||||
void executeCommand(const LanguageServerProtocol::Command &command);
|
||||
@@ -129,6 +131,10 @@ public:
|
||||
|
||||
bool needsRestart(const BaseSettings *) const;
|
||||
|
||||
QList<LanguageServerProtocol::Diagnostic> diagnosticsAt(
|
||||
const LanguageServerProtocol::DocumentUri &uri,
|
||||
const LanguageServerProtocol::Range &range) const;
|
||||
|
||||
bool start();
|
||||
bool reset();
|
||||
|
||||
@@ -184,7 +190,8 @@ private:
|
||||
LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
|
||||
DynamicCapabilities m_dynamicCapabilities;
|
||||
LanguageClientCompletionAssistProvider m_completionProvider;
|
||||
QSet<TextEditor::TextDocument *> m_resetCompletionProvider;
|
||||
LanguageClientQuickFixProvider m_quickFixProvider;
|
||||
QSet<TextEditor::TextDocument *> m_resetAssistProvider;
|
||||
QHash<LanguageServerProtocol::DocumentUri, LanguageServerProtocol::MessageId> m_highlightRequests;
|
||||
int m_restartsLeft = 5;
|
||||
QScopedPointer<BaseClientInterface> m_clientInterface;
|
||||
|
@@ -6,11 +6,12 @@ HEADERS += \
|
||||
client.h \
|
||||
dynamiccapabilities.h \
|
||||
languageclient_global.h \
|
||||
languageclientcodeassist.h \
|
||||
languageclientcompletionassist.h \
|
||||
languageclientinterface.h \
|
||||
languageclientmanager.h \
|
||||
languageclientoutline.h \
|
||||
languageclientplugin.h \
|
||||
languageclientquickfix.h \
|
||||
languageclientsettings.h \
|
||||
languageclientutils.h
|
||||
|
||||
@@ -18,11 +19,12 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
client.cpp \
|
||||
dynamiccapabilities.cpp \
|
||||
languageclientcodeassist.cpp \
|
||||
languageclientcompletionassist.cpp \
|
||||
languageclientinterface.cpp \
|
||||
languageclientmanager.cpp \
|
||||
languageclientoutline.cpp \
|
||||
languageclientplugin.cpp \
|
||||
languageclientquickfix.cpp \
|
||||
languageclientsettings.cpp \
|
||||
languageclientutils.cpp
|
||||
|
||||
|
@@ -20,16 +20,18 @@ QtcPlugin {
|
||||
"dynamiccapabilities.h",
|
||||
"languageclient.qrc",
|
||||
"languageclient_global.h",
|
||||
"languageclientcodeassist.cpp",
|
||||
"languageclientcodeassist.h",
|
||||
"languageclientinterface.cpp",
|
||||
"languageclientinterface.h",
|
||||
"languageclientcompletionassist.cpp",
|
||||
"languageclientcompletionassist.h",
|
||||
"languageclientmanager.cpp",
|
||||
"languageclientmanager.h",
|
||||
"languageclientoutline.cpp",
|
||||
"languageclientoutline.h",
|
||||
"languageclientplugin.cpp",
|
||||
"languageclientplugin.h",
|
||||
"languageclientquickfix.cpp",
|
||||
"languageclientquickfix.h",
|
||||
"languageclientsettings.cpp",
|
||||
"languageclientsettings.h",
|
||||
"languageclientutils.cpp",
|
||||
|
@@ -23,7 +23,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "languageclientcodeassist.h"
|
||||
#include "languageclientcompletionassist.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "languageclientutils.h"
|
@@ -48,7 +48,7 @@ public:
|
||||
private:
|
||||
QList<QString> m_triggerChars;
|
||||
int m_activationCharSequenceLength = 0;
|
||||
Client *m_client;
|
||||
Client *m_client = nullptr; // not owned
|
||||
};
|
||||
|
||||
} // namespace LanguageClient
|
166
src/plugins/languageclient/languageclientquickfix.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "languageclientquickfix.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "languageclientutils.h"
|
||||
|
||||
#include <texteditor/codeassist/assistinterface.h>
|
||||
#include <texteditor/codeassist/genericproposal.h>
|
||||
#include <texteditor/codeassist/iassistprocessor.h>
|
||||
#include <texteditor/quickfix.h>
|
||||
|
||||
|
||||
using namespace LanguageServerProtocol;
|
||||
using namespace TextEditor;
|
||||
|
||||
namespace LanguageClient {
|
||||
|
||||
class CodeActionQuickFixOperation : public QuickFixOperation
|
||||
{
|
||||
public:
|
||||
CodeActionQuickFixOperation(const CodeAction &action, Client *client)
|
||||
: m_action(action)
|
||||
, m_client(client)
|
||||
{ setDescription(action.title()); }
|
||||
|
||||
void perform() override
|
||||
{
|
||||
if (Utils::optional<WorkspaceEdit> edit = m_action.edit()) {
|
||||
applyWorkspaceEdit(*edit);
|
||||
} else if (Utils::optional<Command> command = m_action.command()) {
|
||||
if (m_client)
|
||||
m_client->executeCommand(*command);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CodeAction m_action;
|
||||
QPointer<Client> m_client;
|
||||
};
|
||||
|
||||
class CommandQuickFixOperation : public QuickFixOperation
|
||||
{
|
||||
public:
|
||||
CommandQuickFixOperation(const Command &command, Client *client)
|
||||
: m_command(command)
|
||||
, m_client(client)
|
||||
{ setDescription(command.title()); }
|
||||
void perform() override
|
||||
{
|
||||
if (m_client)
|
||||
m_client->executeCommand(m_command);
|
||||
}
|
||||
|
||||
private:
|
||||
Command m_command;
|
||||
QPointer<Client> m_client;
|
||||
};
|
||||
|
||||
class LanguageClientQuickFixAssistProcessor : public IAssistProcessor
|
||||
{
|
||||
public:
|
||||
explicit LanguageClientQuickFixAssistProcessor(Client *client) : m_client(client) {}
|
||||
bool running() override { return m_running; }
|
||||
IAssistProposal *perform(const AssistInterface *interface) override;
|
||||
|
||||
private:
|
||||
void handleCodeActionResponse(const CodeActionRequest::Response &response);
|
||||
|
||||
QSharedPointer<const AssistInterface> m_assistInterface;
|
||||
Client *m_client = nullptr; // not owned
|
||||
bool m_running = false;
|
||||
};
|
||||
|
||||
IAssistProposal *LanguageClientQuickFixAssistProcessor::perform(const AssistInterface *interface)
|
||||
{
|
||||
m_assistInterface = QSharedPointer<const AssistInterface>(interface);
|
||||
|
||||
CodeActionParams params;
|
||||
params.setContext({});
|
||||
QTextCursor cursor(interface->textDocument());
|
||||
cursor.setPosition(interface->position());
|
||||
if (cursor.atBlockEnd() || cursor.atBlockStart())
|
||||
cursor.select(QTextCursor::LineUnderCursor);
|
||||
else
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
if (!cursor.hasSelection())
|
||||
cursor.select(QTextCursor::LineUnderCursor);
|
||||
Range range(cursor);
|
||||
params.setRange(range);
|
||||
auto uri = DocumentUri::fromFileName(Utils::FileName::fromString(interface->fileName()));
|
||||
params.setTextDocument(uri);
|
||||
CodeActionParams::CodeActionContext context;
|
||||
context.setDiagnostics(m_client->diagnosticsAt(uri, range));
|
||||
params.setContext(context);
|
||||
|
||||
CodeActionRequest request(params);
|
||||
request.setResponseCallback([this](const CodeActionRequest::Response &response){
|
||||
handleCodeActionResponse(response);
|
||||
});
|
||||
|
||||
m_client->requestCodeActions(request);
|
||||
m_running = true;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse(
|
||||
const CodeActionRequest::Response &response)
|
||||
{
|
||||
m_running = false;
|
||||
if (const Utils::optional<CodeActionRequest::Response::Error> &error = response.error())
|
||||
m_client->log(*error);
|
||||
QuickFixOperations ops;
|
||||
if (const Utils::optional<CodeActionResult> &_result = response.result()) {
|
||||
const CodeActionResult &result = _result.value();
|
||||
if (auto list = Utils::get_if<QList<Utils::variant<Command, CodeAction>>>(&result)) {
|
||||
for (const Utils::variant<Command, CodeAction> &item : *list) {
|
||||
if (auto action = Utils::get_if<CodeAction>(&item))
|
||||
ops << new CodeActionQuickFixOperation(*action, m_client);
|
||||
else if (auto command = Utils::get_if<Command>(&item))
|
||||
ops << new CommandQuickFixOperation(*command, m_client);
|
||||
}
|
||||
}
|
||||
}
|
||||
setAsyncProposalAvailable(GenericProposal::createProposal(m_assistInterface.data(), ops));
|
||||
}
|
||||
|
||||
LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client) : m_client(client)
|
||||
{
|
||||
QTC_CHECK(client);
|
||||
}
|
||||
|
||||
IAssistProvider::RunType LanguageClientQuickFixProvider::runType() const
|
||||
{
|
||||
return Asynchronous;
|
||||
}
|
||||
|
||||
IAssistProcessor *LanguageClientQuickFixProvider::createProcessor() const
|
||||
{
|
||||
return new LanguageClientQuickFixAssistProcessor(m_client);
|
||||
}
|
||||
|
||||
} // namespace LanguageClient
|
45
src/plugins/languageclient/languageclientquickfix.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <texteditor/codeassist/iassistprovider.h>
|
||||
|
||||
namespace LanguageClient {
|
||||
|
||||
class Client;
|
||||
|
||||
class LanguageClientQuickFixProvider : public TextEditor::IAssistProvider
|
||||
{
|
||||
public:
|
||||
explicit LanguageClientQuickFixProvider(Client *client);
|
||||
IAssistProvider::RunType runType() const override;
|
||||
TextEditor::IAssistProcessor *createProcessor() const override;
|
||||
|
||||
private:
|
||||
Client *m_client = nullptr; // not owned
|
||||
};
|
||||
|
||||
} // namespace LanguageClient
|
@@ -34,9 +34,8 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/delegates.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <languageserverprotocol/lsptypes.h>
|
||||
#include <utils/jsontreeitem.h>
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QCheckBox>
|
||||
@@ -150,7 +149,6 @@ LanguageClientSettingsPageWidget::LanguageClientSettingsPageWidget(LanguageClien
|
||||
connect(addButton, &QPushButton::pressed, this, &LanguageClientSettingsPageWidget::addItem);
|
||||
auto deleteButton = new QPushButton(LanguageClientSettingsPage::tr("&Delete"));
|
||||
connect(deleteButton, &QPushButton::pressed, this, &LanguageClientSettingsPageWidget::deleteItem);
|
||||
|
||||
mainLayout->addLayout(layout);
|
||||
setLayout(mainLayout);
|
||||
layout->addWidget(m_view);
|
||||
@@ -505,6 +503,24 @@ BaseClientInterface *StdIOSettings::createInterface() const
|
||||
return new StdIOClientInterface(m_executable, m_arguments);
|
||||
}
|
||||
|
||||
static QWidget *createCapabilitiesView(
|
||||
const LanguageServerProtocol::ServerCapabilities &capabilities)
|
||||
{
|
||||
auto root = new Utils::JsonTreeItem("Capabilities", QJsonValue(capabilities));
|
||||
if (root->canFetchMore())
|
||||
root->fetchMore();
|
||||
|
||||
auto capabilitiesModel = new Utils::TreeModel<Utils::JsonTreeItem>(root);
|
||||
capabilitiesModel->setHeader({BaseSettingsWidget::tr("Name"),
|
||||
BaseSettingsWidget::tr("Value"),
|
||||
BaseSettingsWidget::tr("Type")});
|
||||
auto capabilitiesView = new QTreeView();
|
||||
capabilitiesView->setModel(capabilitiesModel);
|
||||
capabilitiesView->setAlternatingRowColors(true);
|
||||
capabilitiesView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
return capabilitiesView;
|
||||
}
|
||||
|
||||
BaseSettingsWidget::BaseSettingsWidget(const BaseSettings *settings, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_name(new QLineEdit(settings->m_name, this))
|
||||
@@ -528,6 +544,30 @@ BaseSettingsWidget::BaseSettingsWidget(const BaseSettings *settings, QWidget *pa
|
||||
connect(addMimeTypeButton, &QPushButton::pressed,
|
||||
this, &BaseSettingsWidget::showAddMimeTypeDialog);
|
||||
|
||||
auto createInfoLabel = []() {
|
||||
return new QLabel(tr("Available after server was initialized"));
|
||||
};
|
||||
|
||||
mainLayout->addWidget(new QLabel(tr("Capabilities:")), ++row, 0, Qt::AlignTop);
|
||||
if (Client *client = settings->m_client.data()) {
|
||||
if (client->state() == Client::Initialized)
|
||||
mainLayout->addWidget(createCapabilitiesView(client->capabilities()));
|
||||
else
|
||||
mainLayout->addWidget(createInfoLabel(), row, 1);
|
||||
connect(client, &Client::finished, mainLayout, [mainLayout, row, createInfoLabel]() {
|
||||
delete mainLayout->itemAtPosition(row, 1)->widget();
|
||||
mainLayout->addWidget(createInfoLabel(), row, 1);
|
||||
});
|
||||
connect(client, &Client::initialized, mainLayout,
|
||||
[mainLayout, row](
|
||||
const LanguageServerProtocol::ServerCapabilities &capabilities) {
|
||||
delete mainLayout->itemAtPosition(row, 1)->widget();
|
||||
mainLayout->addWidget(createCapabilitiesView(capabilities), row, 1);
|
||||
});
|
||||
} else {
|
||||
mainLayout->addWidget(createInfoLabel());
|
||||
}
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
using namespace LanguageServerProtocol;
|
||||
using namespace Utils;
|
||||
using namespace TextEditor;
|
||||
|
||||
namespace LanguageClient {
|
||||
|
||||
@@ -72,7 +73,7 @@ bool applyTextDocumentEdit(const TextDocumentEdit &edit)
|
||||
if (edits.isEmpty())
|
||||
return true;
|
||||
const DocumentUri &uri = edit.id().uri();
|
||||
if (TextEditor::TextDocument* doc = textDocumentForFileName(uri.toFileName())) {
|
||||
if (TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFileName())) {
|
||||
LanguageClientValue<int> version = edit.id().version();
|
||||
if (!version.isNull() && version.value(0) < doc->document()->revision())
|
||||
return false;
|
||||
@@ -84,14 +85,14 @@ bool applyTextEdits(const DocumentUri &uri, const QList<TextEdit> &edits)
|
||||
{
|
||||
if (edits.isEmpty())
|
||||
return true;
|
||||
TextEditor::RefactoringChanges changes;
|
||||
TextEditor::RefactoringFilePtr file;
|
||||
RefactoringChanges changes;
|
||||
RefactoringFilePtr file;
|
||||
file = changes.file(uri.toFileName().toString());
|
||||
file->setChangeSet(editsToChangeSet(edits, file->document()));
|
||||
return file->apply();
|
||||
}
|
||||
|
||||
void applyTextEdit(TextEditor::TextDocumentManipulatorInterface &manipulator, const TextEdit &edit)
|
||||
void applyTextEdit(TextDocumentManipulatorInterface &manipulator, const TextEdit &edit)
|
||||
{
|
||||
using namespace Utils::Text;
|
||||
const Range range = edit.range();
|
||||
@@ -118,12 +119,6 @@ bool applyWorkspaceEdit(const WorkspaceEdit &edit)
|
||||
return result;
|
||||
}
|
||||
|
||||
TextEditor::TextDocument *textDocumentForFileName(const FileName &fileName)
|
||||
{
|
||||
return qobject_cast<TextEditor::TextDocument *>(
|
||||
Core::DocumentModel::documentForFilePath(fileName.toString()));
|
||||
}
|
||||
|
||||
QTextCursor endOfLineCursor(const QTextCursor &cursor)
|
||||
{
|
||||
QTextCursor ret = cursor;
|
||||
@@ -135,8 +130,7 @@ void updateCodeActionRefactoringMarker(Client *client,
|
||||
const CodeAction &action,
|
||||
const DocumentUri &uri)
|
||||
{
|
||||
using namespace TextEditor;
|
||||
TextDocument* doc = textDocumentForFileName(uri.toFileName());
|
||||
TextDocument* doc = TextDocument::textDocumentForFileName(uri.toFileName());
|
||||
if (!doc)
|
||||
return;
|
||||
BaseTextEditor *editor = BaseTextEditor::textEditorForDocument(doc);
|
||||
|
@@ -45,7 +45,6 @@ bool applyTextEdits(const LanguageServerProtocol::DocumentUri &uri,
|
||||
const QList<LanguageServerProtocol::TextEdit> &edits);
|
||||
void applyTextEdit(TextEditor::TextDocumentManipulatorInterface &manipulator,
|
||||
const LanguageServerProtocol::TextEdit &edit);
|
||||
TextEditor::TextDocument *textDocumentForFileName(const Utils::FileName &fileName);
|
||||
void updateCodeActionRefactoringMarker(Client *client,
|
||||
const LanguageServerProtocol::CodeAction &action,
|
||||
const LanguageServerProtocol::DocumentUri &uri);
|
||||
|
@@ -77,7 +77,8 @@ PerfDataReader::PerfDataReader(QObject *parent) :
|
||||
QMessageBox::warning(Core::ICore::mainWindow(),
|
||||
tr("Perf data parser failed"),
|
||||
tr("The perf data parser failed to process all the samples. "
|
||||
"Your trace is incomplete."));
|
||||
"Your trace is incomplete. The exit code was %1.")
|
||||
.arg(exitCode));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -120,6 +121,7 @@ PerfDataReader::PerfDataReader(QObject *parent) :
|
||||
qWarning() << "Cannot send data to perfparser";
|
||||
break;
|
||||
case QProcess::Timedout:
|
||||
qWarning() << "QProcess::Timedout";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -349,8 +351,10 @@ void PerfDataReader::writeChunk()
|
||||
"Your trace is incomplete."));
|
||||
}
|
||||
}
|
||||
} else if (m_dataFinished) {
|
||||
m_input.closeWriteChannel();
|
||||
} else if (m_dataFinished && m_input.isWritable()) {
|
||||
// Delay closing of the write channel. Closing the channel from within a handler
|
||||
// for bytesWritten() is dangerous on windows.
|
||||
QTimer::singleShot(0, &m_input, &QProcess::closeWriteChannel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -46,7 +46,6 @@
|
||||
#include <QVariantMap>
|
||||
|
||||
#include <qbs.h>
|
||||
#include <qtprofilesetup.h>
|
||||
|
||||
const QChar sep = QLatin1Char('.');
|
||||
|
||||
@@ -166,45 +165,9 @@ void QbsManager::addProfile(const QString &name, const QVariantMap &data)
|
||||
|
||||
void QbsManager::addQtProfileFromKit(const QString &profileName, const ProjectExplorer::Kit *k)
|
||||
{
|
||||
const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(k);
|
||||
if (!qt)
|
||||
return;
|
||||
|
||||
qbs::QtEnvironment qtEnv;
|
||||
const QList<ProjectExplorer::Abi> abi = qt->qtAbis();
|
||||
if (!abi.empty()) {
|
||||
qtEnv.architecture = ProjectExplorer::Abi::toString(abi.first().architecture());
|
||||
if (abi.first().wordWidth() == 64)
|
||||
qtEnv.architecture.append(QLatin1String("_64"));
|
||||
}
|
||||
qtEnv.binaryPath = qt->binPath().toString();
|
||||
qtEnv.documentationPath = qt->docsPath().toString();
|
||||
qtEnv.includePath = qt->headerPath().toString();
|
||||
qtEnv.libraryPath = qt->libraryPath().toString();
|
||||
qtEnv.pluginPath = qt->pluginPath().toString();
|
||||
qtEnv.mkspecBasePath = qt->mkspecsPath().toString();
|
||||
qtEnv.mkspecName = qt->mkspec().toString();
|
||||
qtEnv.mkspecPath = qt->mkspecPath().toString();
|
||||
qtEnv.qtNameSpace = qt->qtNamespace();
|
||||
qtEnv.qtLibInfix = qt->qtLibInfix();
|
||||
qtEnv.qtVersion = qt->qtVersionString();
|
||||
qtEnv.qtMajorVersion = qt->qtVersion().majorVersion;
|
||||
qtEnv.qtMinorVersion = qt->qtVersion().minorVersion;
|
||||
qtEnv.qtPatchVersion = qt->qtVersion().patchVersion;
|
||||
qtEnv.frameworkBuild = qt->isFrameworkBuild();
|
||||
qtEnv.configItems = qt->configValues();
|
||||
qtEnv.qtConfigItems = qt->qtConfigValues();
|
||||
foreach (const QString &buildVariant,
|
||||
QStringList() << QLatin1String("debug") << QLatin1String("release")) {
|
||||
if (qtEnv.qtConfigItems.contains(buildVariant))
|
||||
qtEnv.buildVariant << buildVariant;
|
||||
}
|
||||
qtEnv.qmlPath = qt->qmlPath().toString();
|
||||
qtEnv.qmlImportPath = qt->qmakeProperty("QT_INSTALL_IMPORTS");
|
||||
const qbs::ErrorInfo errorInfo = qbs::setupQtProfile(profileName, settings(), qtEnv);
|
||||
if (errorInfo.hasError()) {
|
||||
Core::MessageManager::write(tr("Failed to set up kit for Qbs: %1")
|
||||
.arg(errorInfo.toString()), Core::MessageManager::ModeSwitch);
|
||||
if (const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitAspect::qtVersion(k)) {
|
||||
qbs::Profile(profileName, settings()).setValue("moduleProviders.Qt.qmakeFilePaths",
|
||||
qt->qmakeCommand().toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,11 +5,9 @@ isEmpty(QBS_INSTALL_DIR): QBS_INSTALL_DIR = $$(QBS_INSTALL_DIR)
|
||||
isEmpty(QBS_INSTALL_DIR) {
|
||||
QBS_SOURCE_DIR = $$PWD/../../shared/qbs
|
||||
include($$QBS_SOURCE_DIR/src/lib/corelib/use_corelib.pri)
|
||||
include($$QBS_SOURCE_DIR/src/lib/qtprofilesetup/use_qtprofilesetup.pri)
|
||||
osx:QMAKE_LFLAGS += -Wl,-rpath,@loader_path/../Frameworks # OS X: fix rpath for qbscore soname
|
||||
} else {
|
||||
include($${QBS_INSTALL_DIR}/include/qbs/use_installed_corelib.pri)
|
||||
include($${QBS_INSTALL_DIR}/include/qbs/use_installed_qtprofilesetup.pri)
|
||||
}
|
||||
QBS_INSTALL_DIR_FWD_SLASHES = $$replace(QBS_INSTALL_DIR, \\\\, /)
|
||||
DEFINES += QBS_INSTALL_DIR=\\\"$$QBS_INSTALL_DIR_FWD_SLASHES\\\"
|
||||
|
@@ -20,7 +20,7 @@ QtcPlugin {
|
||||
if (qbs.enableDebugCode)
|
||||
suffix = "d";
|
||||
}
|
||||
libs.push("qbscore" + suffix, "qbsqtprofilesetup" + suffix);
|
||||
libs.push("qbscore" + suffix);
|
||||
return libs
|
||||
}
|
||||
|
||||
@@ -33,10 +33,6 @@ QtcPlugin {
|
||||
name: "qbscore"
|
||||
condition: product.useInternalQbsProducts
|
||||
}
|
||||
Depends {
|
||||
name: "qbsqtprofilesetup"
|
||||
condition: product.useInternalQbsProducts
|
||||
}
|
||||
Depends { name: "QmlJS" }
|
||||
Depends { name: "Utils" }
|
||||
|
||||
|
@@ -322,10 +322,12 @@ protected:
|
||||
|
||||
bool visit(AST::UiPublicMember *node) override
|
||||
{
|
||||
if (node->memberType->name == _name){
|
||||
const ObjectValue * tVal = _context->lookupType(_doc.data(), QStringList(_name));
|
||||
if (tVal == _typeValue)
|
||||
_usages.append(node->typeToken);
|
||||
if (UiQualifiedId *memberType = node->memberType) {
|
||||
if (memberType->name == _name) {
|
||||
const ObjectValue * tVal = _context->lookupType(_doc.data(), QStringList(_name));
|
||||
if (tVal == _typeValue)
|
||||
_usages.append(node->typeToken);
|
||||
}
|
||||
}
|
||||
if (AST::cast<Block *>(node->statement)) {
|
||||
_builder.push(node);
|
||||
|
@@ -42,6 +42,9 @@ LinuxDeviceProcess::LinuxDeviceProcess(const QSharedPointer<const ProjectExplore
|
||||
: ProjectExplorer::SshDeviceProcess(device, parent), m_processId(0)
|
||||
{
|
||||
connect(this, &DeviceProcess::finished, this, [this]() {
|
||||
m_processId = -1;
|
||||
});
|
||||
connect(this, &DeviceProcess::started, this, [this]() {
|
||||
m_processId = 0;
|
||||
});
|
||||
}
|
||||
@@ -70,7 +73,7 @@ QByteArray LinuxDeviceProcess::readAllStandardOutput()
|
||||
|
||||
qint64 LinuxDeviceProcess::processId() const
|
||||
{
|
||||
return m_processId;
|
||||
return m_processId < 0 ? 0 : m_processId;
|
||||
}
|
||||
|
||||
QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const
|
||||
|
@@ -100,6 +100,7 @@ public:
|
||||
QTextDocument m_document;
|
||||
SyntaxHighlighter *m_highlighter = nullptr;
|
||||
CompletionAssistProvider *m_completionAssistProvider = nullptr;
|
||||
IAssistProvider *m_quickFixProvider = nullptr;
|
||||
QScopedPointer<Indenter> m_indenter;
|
||||
|
||||
bool m_fileIsReadOnly = false;
|
||||
@@ -298,6 +299,11 @@ TextDocument *TextDocument::currentTextDocument()
|
||||
return qobject_cast<TextDocument *>(EditorManager::currentDocument());
|
||||
}
|
||||
|
||||
TextDocument *TextDocument::textDocumentForFileName(const Utils::FileName &fileName)
|
||||
{
|
||||
return qobject_cast<TextDocument *>(DocumentModel::documentForFilePath(fileName.toString()));
|
||||
}
|
||||
|
||||
QString TextDocument::plainText() const
|
||||
{
|
||||
return document()->toPlainText();
|
||||
@@ -388,9 +394,14 @@ CompletionAssistProvider *TextDocument::completionAssistProvider() const
|
||||
return d->m_completionAssistProvider;
|
||||
}
|
||||
|
||||
void TextDocument::setQuickFixAssistProvider(IAssistProvider *provider) const
|
||||
{
|
||||
d->m_quickFixProvider = provider;
|
||||
}
|
||||
|
||||
IAssistProvider *TextDocument::quickFixAssistProvider() const
|
||||
{
|
||||
return nullptr;
|
||||
return d->m_quickFixProvider;
|
||||
}
|
||||
|
||||
void TextDocument::applyFontSettings()
|
||||
|
@@ -70,6 +70,7 @@ public:
|
||||
static QMap<QString, QString> openedTextDocumentContents();
|
||||
static QMap<QString, QTextCodec *> openedTextDocumentEncodings();
|
||||
static TextDocument *currentTextDocument();
|
||||
static TextDocument *textDocumentForFileName(const Utils::FileName &fileName);
|
||||
|
||||
virtual QString plainText() const;
|
||||
virtual QString textAt(int pos, int length) const;
|
||||
@@ -140,6 +141,7 @@ public:
|
||||
|
||||
void setCompletionAssistProvider(CompletionAssistProvider *provider);
|
||||
virtual CompletionAssistProvider *completionAssistProvider() const;
|
||||
void setQuickFixAssistProvider(IAssistProvider *provider) const;
|
||||
virtual IAssistProvider *quickFixAssistProvider() const;
|
||||
|
||||
void setTabSettings(const TextEditor::TabSettings &tabSettings);
|
||||
|
@@ -361,11 +361,8 @@ TextMarkRegistry::TextMarkRegistry(QObject *parent)
|
||||
void TextMarkRegistry::add(TextMark *mark)
|
||||
{
|
||||
instance()->m_marks[mark->fileName()].insert(mark);
|
||||
auto document = qobject_cast<TextDocument *>(
|
||||
DocumentModel::documentForFilePath(mark->fileName().toString()));
|
||||
if (!document)
|
||||
return;
|
||||
document->addMark(mark);
|
||||
if (TextDocument *document = TextDocument::textDocumentForFileName(mark->fileName()))
|
||||
document->addMark(mark);
|
||||
}
|
||||
|
||||
bool TextMarkRegistry::remove(TextMark *mark)
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QEvent>
|
||||
#include <QGuiApplication>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
@@ -349,8 +350,17 @@ void IntroductionWidget::keyPressEvent(QKeyEvent *ke)
|
||||
{
|
||||
if (ke->key() == Qt::Key_Escape)
|
||||
finish();
|
||||
else if (ke->modifiers() == Qt::NoModifier)
|
||||
step();
|
||||
else if ((ke->modifiers()
|
||||
& (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier | Qt::MetaModifier))
|
||||
== Qt::NoModifier) {
|
||||
const Qt::Key backKey = QGuiApplication::isLeftToRight() ? Qt::Key_Left : Qt::Key_Right;
|
||||
if (ke->key() == backKey) {
|
||||
if (m_step > 0)
|
||||
setStep(m_step - 1);
|
||||
} else {
|
||||
step();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntroductionWidget::mouseReleaseEvent(QMouseEvent *me)
|
||||
|
@@ -27,6 +27,8 @@
|
||||
#include "prowriter.h"
|
||||
#include "proitems.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QPair>
|
||||
#include <QRegularExpression>
|
||||
@@ -36,7 +38,7 @@ using namespace QmakeProjectManager::Internal;
|
||||
static uint getBlockLen(const ushort *&tokPtr)
|
||||
{
|
||||
uint len = *tokPtr++;
|
||||
len |= (uint)*tokPtr++ << 16;
|
||||
len |= uint(*tokPtr++ << 16);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -51,10 +53,10 @@ static bool getLiteral(const ushort *tokPtr, const ushort *tokEnd, QString &tmp)
|
||||
break;
|
||||
case TokHashLiteral:
|
||||
tokPtr += 2;
|
||||
// fallthrough
|
||||
Q_FALLTHROUGH();
|
||||
case TokLiteral: {
|
||||
uint len = *tokPtr++;
|
||||
tmp.setRawData((const QChar *)tokPtr, len);
|
||||
int len = *tokPtr++;
|
||||
tmp.setRawData(reinterpret_cast<const QChar *>(tokPtr), len);
|
||||
count++;
|
||||
tokPtr += len;
|
||||
break; }
|
||||
@@ -87,7 +89,7 @@ static void skipBlock(const ushort *&tokPtr)
|
||||
static void skipExpression(const ushort *&pTokPtr, int &lineNo)
|
||||
{
|
||||
const ushort *tokPtr = pTokPtr;
|
||||
forever {
|
||||
for (;;) {
|
||||
ushort tok = *tokPtr++;
|
||||
switch (tok) {
|
||||
case TokLine:
|
||||
@@ -136,13 +138,13 @@ static const ushort *skipToken(ushort tok, const ushort *&tokPtr, int &lineNo)
|
||||
case TokRemove:
|
||||
case TokReplace:
|
||||
tokPtr++;
|
||||
// fallthrough
|
||||
Q_FALLTHROUGH();
|
||||
case TokTestCall:
|
||||
skipExpression(tokPtr, lineNo);
|
||||
break;
|
||||
case TokForLoop:
|
||||
skipHashStr(tokPtr);
|
||||
// fallthrough
|
||||
Q_FALLTHROUGH();
|
||||
case TokBranch:
|
||||
skipBlock(tokPtr);
|
||||
skipBlock(tokPtr);
|
||||
@@ -168,14 +170,14 @@ static const ushort *skipToken(ushort tok, const ushort *&tokPtr, int &lineNo)
|
||||
}
|
||||
Q_ASSERT_X(false, "skipToken", "unexpected item type");
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString ProWriter::compileScope(const QString &scope)
|
||||
{
|
||||
if (scope.isEmpty())
|
||||
return QString();
|
||||
QMakeParser parser(0, 0, 0);
|
||||
QMakeParser parser(nullptr, nullptr, nullptr);
|
||||
ProFile *includeFile = parser.parsedProBlock(QStringRef(&scope), 0, QLatin1String("no-file"), 1);
|
||||
if (!includeFile)
|
||||
return QString();
|
||||
@@ -204,11 +206,11 @@ bool ProWriter::locateVarValues(const ushort *tokPtr, const ushort *tokPtrEnd,
|
||||
const bool inScope = scope.isEmpty();
|
||||
int lineNo = *scopeStart + 1;
|
||||
QString tmp;
|
||||
const ushort *lastXpr = 0;
|
||||
const ushort *lastXpr = nullptr;
|
||||
bool fresh = true;
|
||||
|
||||
QString compiledScope = compileScope(scope);
|
||||
const ushort *cTokPtr = (const ushort *)compiledScope.constData();
|
||||
const ushort *cTokPtr = reinterpret_cast<const ushort *>(compiledScope.constData());
|
||||
|
||||
while (ushort tok = *tokPtr++) {
|
||||
if (inScope && (tok == TokAssign || tok == TokAppend || tok == TokAppendUnique)) {
|
||||
@@ -323,7 +325,7 @@ void ProWriter::putVarValues(ProFile *profile, QStringList *lines, const QString
|
||||
if (eqs >= 0) // If this is not true, we mess up the file a bit.
|
||||
line.truncate(eqs + 1);
|
||||
// put new values
|
||||
foreach (const QString &v, values) {
|
||||
for (const QString &v : values) {
|
||||
line += ((flags & MultiLine) ? QLatin1String(" \\\n") + effectiveContIndent(contInfo)
|
||||
: QString::fromLatin1(" ")) + v;
|
||||
}
|
||||
@@ -388,9 +390,10 @@ void ProWriter::putVarValues(ProFile *profile, QStringList *lines, const QString
|
||||
if (lNo != scopeStart + 1)
|
||||
added += QLatin1Char('\n');
|
||||
added += indent + var + QLatin1String((flags & AppendOperator) ? " +=" : " =");
|
||||
foreach (const QString &v, values)
|
||||
for (const QString &v : values) {
|
||||
added += ((flags & MultiLine) ? QLatin1String(" \\\n") + effectiveContIndent(contInfo)
|
||||
: QString::fromLatin1(" ")) + v;
|
||||
}
|
||||
if (!scope.isEmpty() && scopeStart < 0)
|
||||
added += QLatin1String("\n}");
|
||||
lines->insert(lNo, added);
|
||||
@@ -405,7 +408,7 @@ void ProWriter::addFiles(ProFile *profile, QStringList *lines, const QStringList
|
||||
QDir baseDir = QFileInfo(profile->fileName()).absoluteDir();
|
||||
if (profile->fileName().endsWith(QLatin1String(".pri")))
|
||||
prefixPwd = QLatin1String("$$PWD/");
|
||||
foreach (const QString &v, values)
|
||||
for (const QString &v : values)
|
||||
valuesToWrite << (prefixPwd + baseDir.relativeFilePath(v));
|
||||
|
||||
putVarValues(profile, lines, valuesToWrite, var, AppendValues | MultiLine | AppendOperator,
|
||||
@@ -417,7 +420,7 @@ static void findProVariables(const ushort *tokPtr, const QStringList &vars,
|
||||
{
|
||||
int lineNo = firstLine;
|
||||
QString tmp;
|
||||
const ushort *lastXpr = 0;
|
||||
const ushort *lastXpr = nullptr;
|
||||
while (ushort tok = *tokPtr++) {
|
||||
if (tok == TokBranch) {
|
||||
uint blockLen = getBlockLen(tokPtr);
|
||||
@@ -453,7 +456,7 @@ QList<int> ProWriter::removeVarValues(ProFile *profile, QStringList *lines,
|
||||
|
||||
// This code expects proVars to be sorted by the variables' appearance in the file.
|
||||
int delta = 1;
|
||||
foreach (int ln, varLines) {
|
||||
for (int ln : qAsConst(varLines)) {
|
||||
bool first = true;
|
||||
int lineNo = ln - delta;
|
||||
typedef QPair<int, int> ContPos;
|
||||
@@ -467,7 +470,7 @@ QList<int> ProWriter::removeVarValues(ProFile *profile, QStringList *lines,
|
||||
if (idx >= 0)
|
||||
lineLen = idx;
|
||||
QChar *chars = line.data();
|
||||
forever {
|
||||
for (;;) {
|
||||
if (!lineLen) {
|
||||
if (idx >= 0)
|
||||
goto nextLine;
|
||||
@@ -530,7 +533,7 @@ QList<int> ProWriter::removeVarValues(ProFile *profile, QStringList *lines,
|
||||
// Entries existed, but were all removed
|
||||
if (contCol < 0) {
|
||||
// This is the last line, so clear continuations leading to it
|
||||
foreach (const ContPos &pos, contPos) {
|
||||
for (const ContPos &pos : qAsConst(contPos)) {
|
||||
QString &bline = (*lines)[pos.first];
|
||||
bline.remove(pos.second, 1);
|
||||
if (pos.second == bline.length())
|
||||
@@ -564,12 +567,12 @@ QStringList ProWriter::removeFiles(ProFile *profile, QStringList *lines,
|
||||
// This is a tad stupid - basically, it can remove only entries which
|
||||
// the above code added.
|
||||
QStringList valuesToFind;
|
||||
foreach (const QString &absoluteFilePath, values)
|
||||
for (const QString &absoluteFilePath : values)
|
||||
valuesToFind << proFileDir.relativeFilePath(absoluteFilePath);
|
||||
|
||||
QStringList notYetChanged;
|
||||
foreach (int i, removeVarValues(profile, lines, valuesToFind, vars))
|
||||
notYetChanged.append(values.at(i));
|
||||
const QStringList notYetChanged =
|
||||
Utils::transform(removeVarValues(profile, lines, valuesToFind, vars),
|
||||
[values](int i) { return values.at(i); });
|
||||
|
||||
if (!profile->fileName().endsWith(QLatin1String(".pri")))
|
||||
return notYetChanged;
|
||||
@@ -580,12 +583,12 @@ QStringList ProWriter::removeFiles(ProFile *profile, QStringList *lines,
|
||||
valuesToFind.clear();
|
||||
const QDir baseDir = QFileInfo(profile->fileName()).absoluteDir();
|
||||
const QString prefixPwd = QLatin1String("$$PWD/");
|
||||
foreach (const QString &absoluteFilePath, notYetChanged)
|
||||
for (const QString &absoluteFilePath : notYetChanged)
|
||||
valuesToFind << (prefixPwd + baseDir.relativeFilePath(absoluteFilePath));
|
||||
|
||||
QStringList notChanged;
|
||||
foreach (int i, removeVarValues(profile, lines, valuesToFind, vars))
|
||||
notChanged.append(notYetChanged.at(i));
|
||||
const QStringList notChanged =
|
||||
Utils::transform(removeVarValues(profile, lines, valuesToFind, vars),
|
||||
[notYetChanged](int i) { return notYetChanged.at(i); });
|
||||
|
||||
return notChanged;
|
||||
}
|
||||
|
@@ -2,17 +2,14 @@ TEMPLATE = subdirs
|
||||
|
||||
QBS_DIRS = \
|
||||
qbscorelib \
|
||||
qbsqtprofilesetup \
|
||||
qbsapps \
|
||||
qbslibexec \
|
||||
qbsplugins \
|
||||
qbsstatic
|
||||
|
||||
qbscorelib.subdir = qbs/src/lib/corelib
|
||||
qbsqtprofilesetup.subdir = qbs/src/lib/qtprofilesetup
|
||||
qbsqtprofilesetup.depends = qbscorelib
|
||||
qbsapps.subdir = qbs/src/app
|
||||
qbsapps.depends = qbsqtprofilesetup
|
||||
qbsapps.depends = qbscorelib
|
||||
qbslibexec.subdir = qbs/src/libexec
|
||||
qbslibexec.depends = qbscorelib
|
||||
qbsplugins.subdir = qbs/src/plugins
|
||||
|
@@ -72,6 +72,48 @@ using ClangBackEnd::FilePathCache;
|
||||
using ClangBackEnd::FilePathView;
|
||||
using ClangBackEnd::TimeStamp;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
template<typename CallableType>
|
||||
class CallableEvent : public QEvent
|
||||
{
|
||||
public:
|
||||
using Callable = std::decay_t<CallableType>;
|
||||
CallableEvent(Callable &&callable)
|
||||
: QEvent(QEvent::None)
|
||||
, callable(std::move(callable))
|
||||
{}
|
||||
CallableEvent(const Callable &callable)
|
||||
: QEvent(QEvent::None)
|
||||
, callable(callable)
|
||||
{}
|
||||
|
||||
~CallableEvent() { callable(); }
|
||||
|
||||
public:
|
||||
Callable callable;
|
||||
};
|
||||
|
||||
template<typename Callable>
|
||||
void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance())
|
||||
{
|
||||
if (QThread *thread = qobject_cast<QThread *>(object))
|
||||
object = QAbstractEventDispatcher::instance(thread);
|
||||
|
||||
QCoreApplication::postEvent(object,
|
||||
new CallableEvent<Callable>(std::forward<Callable>(callable)),
|
||||
Qt::HighEventPriority);
|
||||
}
|
||||
#else
|
||||
template<typename Callable>
|
||||
void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance())
|
||||
{
|
||||
if (QThread *thread = qobject_cast<QThread *>(object))
|
||||
object = QAbstractEventDispatcher::instance(thread);
|
||||
|
||||
QMetaObject::invokeMethod(object, std::forward<Callable>(callable));
|
||||
}
|
||||
#endif
|
||||
|
||||
class PchManagerApplication final : public QCoreApplication
|
||||
{
|
||||
public:
|
||||
@@ -182,8 +224,9 @@ struct Data // because we have a cycle dependency
|
||||
clangPchManagerServer,
|
||||
includeWatcher};
|
||||
PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
|
||||
ClangBackEnd::ProgressCounter progressCounter{
|
||||
[&](int progress, int total) { clangPchManagerServer.setProgress(progress, total); }};
|
||||
ClangBackEnd::ProgressCounter progressCounter{[&](int progress, int total) {
|
||||
executeInLoop([&] { clangPchManagerServer.setProgress(progress, total); });
|
||||
}};
|
||||
ClangBackEnd::PchTaskQueue pchTaskQueue{systemTaskScheduler,
|
||||
projectTaskScheduler,
|
||||
progressCounter,
|
||||
@@ -191,7 +234,9 @@ struct Data // because we have a cycle dependency
|
||||
database};
|
||||
ClangBackEnd::PchTasksMerger pchTaskMerger{pchTaskQueue};
|
||||
ClangBackEnd::BuildDependenciesStorage<> buildDependencyStorage{database};
|
||||
ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache, generatedFiles};
|
||||
ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache,
|
||||
generatedFiles,
|
||||
environment};
|
||||
std::function<TimeStamp(FilePathView filePath)> getModifiedTime{
|
||||
[&](ClangBackEnd::FilePathView path) -> TimeStamp {
|
||||
return QFileInfo(QString(path)).lastModified().toSecsSinceEpoch();
|
||||
|
@@ -28,10 +28,12 @@
|
||||
#include "collectbuilddependencytoolaction.h"
|
||||
#include "commandlinebuilder.h"
|
||||
|
||||
#include <environment.h>
|
||||
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <iostream>
|
||||
namespace ClangBackEnd {
|
||||
|
||||
namespace {
|
||||
@@ -47,10 +49,10 @@ FilePathIds operator+(const FilePathIds &first, const FilePathIds &second)
|
||||
|
||||
BuildDependency BuildDependencyCollector::create(const ProjectPartContainer &projectPart)
|
||||
{
|
||||
CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector> builder{
|
||||
projectPart, projectPart.toolChainArguments};
|
||||
CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector>
|
||||
builder{projectPart, projectPart.toolChainArguments, InputFileType::Source};
|
||||
|
||||
addFiles(projectPart.sourcePathIds, builder.commandLine);
|
||||
addFiles(projectPart.sourcePathIds, std::move(builder.commandLine));
|
||||
|
||||
setExcludedFilePaths(
|
||||
m_filePathCache.filePaths(projectPart.headerPathIds + projectPart.sourcePathIds));
|
||||
@@ -66,6 +68,33 @@ BuildDependency BuildDependencyCollector::create(const ProjectPartContainer &pro
|
||||
return buildDependency;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::size_t contentSize(const FilePaths &includes)
|
||||
{
|
||||
auto countIncludeSize = [](std::size_t size, const auto &include) {
|
||||
return size + include.size();
|
||||
};
|
||||
|
||||
return std::accumulate(includes.begin(), includes.end(), std::size_t(0), countIncludeSize);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Utils::SmallString BuildDependencyCollector::generateFakeFileContent(
|
||||
const FilePathIds &includeIds) const
|
||||
{
|
||||
Utils::SmallString fileContent;
|
||||
const std::size_t lineTemplateSize = 12;
|
||||
auto includes = m_filePathCache.filePaths(includeIds);
|
||||
|
||||
fileContent.reserve(includes.size() * lineTemplateSize + contentSize(includes));
|
||||
|
||||
for (Utils::SmallStringView include : includes)
|
||||
fileContent += {"#include \"", include, "\"\n"};
|
||||
|
||||
return fileContent;
|
||||
}
|
||||
|
||||
void BuildDependencyCollector::collect()
|
||||
{
|
||||
clang::tooling::ClangTool tool = m_clangTool.createTool();
|
||||
@@ -96,25 +125,26 @@ void BuildDependencyCollector::setExcludedFilePaths(ClangBackEnd::FilePaths &&ex
|
||||
}
|
||||
|
||||
void BuildDependencyCollector::addFiles(const FilePathIds &filePathIds,
|
||||
const Utils::SmallStringVector &arguments)
|
||||
Utils::SmallStringVector &&arguments)
|
||||
{
|
||||
m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments);
|
||||
m_clangTool.addFile(FilePath{m_environment.pchBuildDirectory().toStdString(), "dummy.cpp"},
|
||||
generateFakeFileContent(filePathIds),
|
||||
std::move(arguments));
|
||||
m_buildDependency.sourceFiles.insert(m_buildDependency.sourceFiles.end(),
|
||||
filePathIds.begin(),
|
||||
filePathIds.end());
|
||||
}
|
||||
|
||||
void BuildDependencyCollector::addFile(FilePathId filePathId,
|
||||
const Utils::SmallStringVector &arguments)
|
||||
void BuildDependencyCollector::addFile(FilePathId filePathId, Utils::SmallStringVector &&arguments)
|
||||
{
|
||||
addFiles({filePathId}, arguments);
|
||||
addFiles({filePathId}, std::move(arguments));
|
||||
}
|
||||
|
||||
void BuildDependencyCollector::addFile(FilePath filePath,
|
||||
const FilePathIds &sourceFileIds,
|
||||
const Utils::SmallStringVector &arguments)
|
||||
Utils::SmallStringVector &&arguments)
|
||||
{
|
||||
m_clangTool.addFiles({filePath}, arguments);
|
||||
m_clangTool.addFiles({filePath}, std::move(arguments));
|
||||
m_buildDependency.sourceFiles.insert(m_buildDependency.sourceFiles.end(),
|
||||
sourceFileIds.begin(),
|
||||
sourceFileIds.end());
|
||||
|
@@ -34,33 +34,35 @@
|
||||
#include <filepathcachingfwd.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
class Environment;
|
||||
|
||||
class BuildDependencyCollector : public BuildDependencyGeneratorInterface
|
||||
{
|
||||
public:
|
||||
BuildDependencyCollector(const FilePathCachingInterface &filePathCache,
|
||||
const GeneratedFilesInterface &generatedFiles)
|
||||
const GeneratedFilesInterface &generatedFiles,
|
||||
const Environment &environment)
|
||||
: m_filePathCache(filePathCache)
|
||||
, m_generatedFiles(generatedFiles)
|
||||
{
|
||||
}
|
||||
, m_environment(environment)
|
||||
{}
|
||||
|
||||
BuildDependency create(const ProjectPartContainer &projectPart) override;
|
||||
|
||||
void collect();
|
||||
|
||||
void setExcludedFilePaths(ClangBackEnd::FilePaths &&excludedIncludes);
|
||||
void addFiles(const FilePathIds &filePathIds,
|
||||
const Utils::SmallStringVector &arguments);
|
||||
void addFile(FilePathId filePathId,
|
||||
const Utils::SmallStringVector &arguments);
|
||||
void addFiles(const FilePathIds &filePathIds, Utils::SmallStringVector &&arguments);
|
||||
void addFile(FilePathId filePathId, Utils::SmallStringVector &&arguments);
|
||||
void addFile(FilePath filePath,
|
||||
const FilePathIds &sourceFileIds,
|
||||
const Utils::SmallStringVector &arguments);
|
||||
Utils::SmallStringVector &&arguments);
|
||||
void addUnsavedFiles(const V2::FileContainers &unsavedFiles);
|
||||
|
||||
void clear();
|
||||
|
||||
Utils::SmallString generateFakeFileContent(const FilePathIds &includeIds) const;
|
||||
|
||||
const FileStatuses &fileStatuses() const
|
||||
{
|
||||
return m_buildDependency.fileStatuses;
|
||||
@@ -96,6 +98,7 @@ private:
|
||||
SourcesManager m_sourcesManager;
|
||||
const FilePathCachingInterface &m_filePathCache;
|
||||
const GeneratedFilesInterface &m_generatedFiles;
|
||||
const Environment &m_environment;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -54,27 +54,28 @@ public:
|
||||
|
||||
bool BeginSourceFileAction(clang::CompilerInstance &compilerInstance) override
|
||||
{
|
||||
if (clang::PreprocessOnlyAction::BeginSourceFileAction(compilerInstance)) {
|
||||
auto &preprocessor = compilerInstance.getPreprocessor();
|
||||
if (clang::PreprocessOnlyAction::BeginSourceFileAction(compilerInstance)) {
|
||||
auto &preprocessor = compilerInstance.getPreprocessor();
|
||||
|
||||
preprocessor.SetSuppressIncludeNotFoundError(true);
|
||||
preprocessor.SetMacroExpansionOnlyInDirectives();
|
||||
preprocessor.SetSuppressIncludeNotFoundError(true);
|
||||
preprocessor.SetMacroExpansionOnlyInDirectives();
|
||||
|
||||
auto macroPreprocessorCallbacks = new CollectBuildDependencyPreprocessorCallbacks(
|
||||
m_buildDependency,
|
||||
m_filePathCache,
|
||||
m_excludedIncludeUID,
|
||||
m_alreadyIncludedFileUIDs,
|
||||
compilerInstance.getSourceManager(),
|
||||
m_sourcesManager,
|
||||
compilerInstance.getPreprocessorPtr());
|
||||
auto macroPreprocessorCallbacks = new CollectBuildDependencyPreprocessorCallbacks(
|
||||
m_buildDependency,
|
||||
m_filePathCache,
|
||||
m_excludedIncludeUID,
|
||||
m_alreadyIncludedFileUIDs,
|
||||
compilerInstance.getSourceManager(),
|
||||
m_sourcesManager,
|
||||
compilerInstance.getPreprocessorPtr());
|
||||
|
||||
preprocessor.addPPCallbacks(std::unique_ptr<clang::PPCallbacks>(macroPreprocessorCallbacks));
|
||||
preprocessor.addPPCallbacks(
|
||||
std::unique_ptr<clang::PPCallbacks>(macroPreprocessorCallbacks));
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void EndSourceFileAction() override
|
||||
|
@@ -72,15 +72,27 @@ public:
|
||||
void FileChanged(clang::SourceLocation sourceLocation,
|
||||
clang::PPCallbacks::FileChangeReason reason,
|
||||
clang::SrcMgr::CharacteristicKind,
|
||||
clang::FileID) override
|
||||
clang::FileID previousFileId) override
|
||||
{
|
||||
if (reason == clang::PPCallbacks::EnterFile)
|
||||
{
|
||||
const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(
|
||||
m_sourceManager->getFileID(sourceLocation));
|
||||
if (fileEntry) {
|
||||
addFileStatus(fileEntry);
|
||||
addSourceFile(fileEntry);
|
||||
if (reason == clang::PPCallbacks::EnterFile) {
|
||||
clang::FileID currentFileId = m_sourceManager->getFileID(sourceLocation);
|
||||
if (m_mainFileId.isInvalid()) {
|
||||
m_mainFileId = currentFileId;
|
||||
} else {
|
||||
const clang::FileEntry *fileEntry = m_sourceManager->getFileEntryForID(
|
||||
currentFileId);
|
||||
if (fileEntry) {
|
||||
if (previousFileId == m_mainFileId) {
|
||||
uint sourceFileUID = fileEntry->getUID();
|
||||
auto notAlreadyIncluded = isNotAlreadyIncluded(sourceFileUID);
|
||||
if (notAlreadyIncluded.first)
|
||||
m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second,
|
||||
sourceFileUID);
|
||||
} else {
|
||||
addFileStatus(fileEntry);
|
||||
addSourceFile(fileEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +108,8 @@ public:
|
||||
const clang::Module * /*imported*/,
|
||||
clang::SrcMgr::CharacteristicKind fileType) override
|
||||
{
|
||||
if (file) {
|
||||
clang::FileID currentFileId = m_sourceManager->getFileID(hashLocation);
|
||||
if (file && currentFileId != m_mainFileId) {
|
||||
addSourceDependency(file, hashLocation);
|
||||
auto fileUID = file->getUID();
|
||||
auto sourceFileUID = m_sourceManager
|
||||
@@ -343,6 +356,7 @@ private:
|
||||
BuildDependency &m_buildDependency;
|
||||
const std::vector<uint> &m_excludedIncludeUID;
|
||||
std::vector<uint> &m_alreadyIncludedFileUIDs;
|
||||
clang::FileID m_mainFileId;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|