From 3ed40074ffc81e9fcf038352cb102b3665dc3297 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 24 Nov 2015 16:02:01 +0100 Subject: [PATCH 01/47] C++: Add missing includes ...that are needed for building unittest.pro. Change-Id: I05a87febbb4a17752c4321b868f71cabf258e1dd Reviewed-by: Marco Bubke --- src/libs/3rdparty/cplusplus/Bind.cpp | 1 + src/libs/3rdparty/cplusplus/Templates.cpp | 1 + src/libs/cplusplus/MatchingText.h | 1 + 3 files changed, 3 insertions(+) diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 63940d19ddc..e5802d44283 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -30,6 +30,7 @@ #include "cppassert.h" +#include #include #include #include diff --git a/src/libs/3rdparty/cplusplus/Templates.cpp b/src/libs/3rdparty/cplusplus/Templates.cpp index 3b8ae9a23f6..61c6e612ae4 100644 --- a/src/libs/3rdparty/cplusplus/Templates.cpp +++ b/src/libs/3rdparty/cplusplus/Templates.cpp @@ -27,6 +27,7 @@ #include "cppassert.h" +#include using namespace CPlusPlus; diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h index bf4738f8572..6c041defdfa 100644 --- a/src/libs/cplusplus/MatchingText.h +++ b/src/libs/cplusplus/MatchingText.h @@ -31,6 +31,7 @@ #ifndef CPLUSPLUS_MATCHINGTEXT_H #define CPLUSPLUS_MATCHINGTEXT_H +#include #include QT_FORWARD_DECLARE_CLASS(QTextCursor) From 6687b60a99987ba8c6eab5f4f26f533bf77b2c85 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 24 Nov 2015 11:07:51 +0100 Subject: [PATCH 02/47] Clang: Tests on MSVC2013: Fix string literal concatenation Change-Id: I1b1cefbace16cf0161bfe522d2ac37704e374713 Reviewed-by: Marco Bubke --- tests/unit/unittest/clangfixitoperationtest.cpp | 10 +++++----- tests/unit/unittest/codecompletiontest.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/unit/unittest/clangfixitoperationtest.cpp b/tests/unit/unittest/clangfixitoperationtest.cpp index 1ed3e86c937..7989b3c839c 100644 --- a/tests/unit/unittest/clangfixitoperationtest.cpp +++ b/tests/unit/unittest/clangfixitoperationtest.cpp @@ -82,11 +82,11 @@ protected: FixItContainer semicolonFixItContainer{Utf8StringLiteral(";"), {{filePath, 3u, 29u}, {filePath, 3u, 29u}}}; - QString semicolonErrorFile{QStringLiteral(TESTDATA_DIR"/diagnostic_semicolon_fixit.cpp")}; - QString semicolonExpectedFile{QStringLiteral(TESTDATA_DIR"/diagnostic_semicolon_fixit_expected.cpp")}; - QString compareWarningFile{QStringLiteral(TESTDATA_DIR"/diagnostic_comparison_fixit.cpp")}; - QString compareExpected1File{QStringLiteral(TESTDATA_DIR"/diagnostic_comparison_fixit_expected1.cpp")}; - QString compareExpected2File{QStringLiteral(TESTDATA_DIR"/diagnostic_comparison_fixit_expected2.cpp")}; + QString semicolonErrorFile{QString::fromUtf8(TESTDATA_DIR "/diagnostic_semicolon_fixit.cpp")}; + QString semicolonExpectedFile{QString::fromUtf8(TESTDATA_DIR"/diagnostic_semicolon_fixit_expected.cpp")}; + QString compareWarningFile{QString::fromUtf8(TESTDATA_DIR"/diagnostic_comparison_fixit.cpp")}; + QString compareExpected1File{QString::fromUtf8(TESTDATA_DIR"/diagnostic_comparison_fixit_expected1.cpp")}; + QString compareExpected2File{QString::fromUtf8(TESTDATA_DIR"/diagnostic_comparison_fixit_expected2.cpp")}; FixItContainer compareFixItContainer{Utf8StringLiteral("=="), {{filePath, 4u, 43u}, {filePath, 4u, 44u}}}; diff --git a/tests/unit/unittest/codecompletiontest.cpp b/tests/unit/unittest/codecompletiontest.cpp index 80679f7cd72..33a79d177be 100644 --- a/tests/unit/unittest/codecompletiontest.cpp +++ b/tests/unit/unittest/codecompletiontest.cpp @@ -118,7 +118,7 @@ Utf8String CodeCompleter::readFileContent(const QString &fileName) void CodeCompleter::copyTargetHeaderToTemporaryIncludeDirecory() { QFile::remove(targetHeaderPath); - bool hasCopied = QFile::copy(QStringLiteral(TESTDATA_DIR "/complete_target_header.h"), + bool hasCopied = QFile::copy(QString::fromUtf8(TESTDATA_DIR "/complete_target_header.h"), targetHeaderPath); EXPECT_TRUE(hasCopied); } @@ -126,7 +126,7 @@ void CodeCompleter::copyTargetHeaderToTemporaryIncludeDirecory() void CodeCompleter::copyChangedTargetHeaderToTemporaryIncludeDirecory() { QFile::remove(targetHeaderPath); - bool hasCopied = QFile::copy(QStringLiteral(TESTDATA_DIR "/complete_target_header_changed.h"), + bool hasCopied = QFile::copy(QString::fromUtf8(TESTDATA_DIR "/complete_target_header_changed.h"), targetHeaderPath); EXPECT_TRUE(hasCopied); } From ccd92d8c0bc27e203ed05afcdb5ee3532a5d17ed Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 25 Nov 2015 13:13:01 +0100 Subject: [PATCH 03/47] Update qbs submodule. To HEAD of 1.4 branch. Change-Id: I158c75917f285a2e902614d1750691bd231a5d16 Reviewed-by: Jake Petroules --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index ca3974a0828..73386649711 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit ca3974a0828c029e47f644931386fe6df200fbad +Subproject commit 7338664971101a76a54fda7196c411f0235186c0 From 216f110385f4854c22229430b839b3245a255135 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 24 Nov 2015 11:17:18 +0100 Subject: [PATCH 04/47] Clang: Tests on MSVC2013: Fix file name clashes The following files conflicted: src\tools\clangbackend\ipcsource\translationunit.cpp src\libs\3rdparty\cplusplus\TranslationUnit.cpp src\libs\3rdparty\cplusplus\Type.cpp src\tools\clangbackend\ipcsource\type.cpp src\libs\3rdparty\cplusplus\Symbol.cpp src\plugins\clangcodemodel\symbol.cpp Change-Id: If7865570cd70e39e25cc8d508f771c8023288f0c Reviewed-by: Marco Bubke --- src/plugins/clangcodemodel/clangcodemodel.pro | 4 ++-- src/plugins/clangcodemodel/clangcodemodel.qbs | 4 ++-- .../clangcodemodel/{symbol.cpp => clangsymbol.cpp} | 2 +- .../clangcodemodel/{symbol.h => clangsymbol.h} | 0 src/plugins/clangcodemodel/index.h | 2 +- src/plugins/clangcodemodel/indexer.h | 2 +- .../ipcsource/clangbackendclangipc-source.pri | 12 ++++++------ src/tools/clangbackend/ipcsource/clangipcserver.h | 2 +- ...{translationunit.cpp => clangtranslationunit.cpp} | 2 +- .../{translationunit.h => clangtranslationunit.h} | 0 .../ipcsource/{type.cpp => clangtype.cpp} | 2 +- .../clangbackend/ipcsource/{type.h => clangtype.h} | 0 src/tools/clangbackend/ipcsource/codecompleter.cpp | 2 +- src/tools/clangbackend/ipcsource/codecompleter.h | 2 +- src/tools/clangbackend/ipcsource/cursor.h | 2 +- src/tools/clangbackend/ipcsource/sourcelocation.cpp | 2 +- src/tools/clangbackend/ipcsource/translationunits.h | 2 +- tests/unit/unittest/clangcodecompleteresultstest.cpp | 2 +- tests/unit/unittest/codecompletionsextractortest.cpp | 2 +- tests/unit/unittest/codecompletiontest.cpp | 2 +- tests/unit/unittest/cursortest.cpp | 2 +- tests/unit/unittest/diagnosticsettest.cpp | 2 +- tests/unit/unittest/diagnostictest.cpp | 2 +- tests/unit/unittest/fixittest.cpp | 2 +- tests/unit/unittest/highlightinginformationstest.cpp | 2 +- tests/unit/unittest/skippedsourcerangestest.cpp | 2 +- tests/unit/unittest/sourcelocationtest.cpp | 2 +- tests/unit/unittest/sourcerangetest.cpp | 2 +- tests/unit/unittest/translationunitstest.cpp | 2 +- tests/unit/unittest/translationunittest.cpp | 2 +- 30 files changed, 34 insertions(+), 34 deletions(-) rename src/plugins/clangcodemodel/{symbol.cpp => clangsymbol.cpp} (99%) rename src/plugins/clangcodemodel/{symbol.h => clangsymbol.h} (100%) rename src/tools/clangbackend/ipcsource/{translationunit.cpp => clangtranslationunit.cpp} (99%) rename src/tools/clangbackend/ipcsource/{translationunit.h => clangtranslationunit.h} (100%) rename src/tools/clangbackend/ipcsource/{type.cpp => clangtype.cpp} (99%) rename src/tools/clangbackend/ipcsource/{type.h => clangtype.h} (100%) diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index e8578cbb7cf..3a73d66790d 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -33,6 +33,7 @@ SOURCES += \ clangmodelmanagersupport.cpp \ clangprojectsettings.cpp \ clangprojectsettingspropertiespage.cpp \ + clangsymbol.cpp \ clangtextmark.cpp \ clangutils.cpp \ completionchunkstotextconverter.cpp \ @@ -46,7 +47,6 @@ SOURCES += \ semanticmarker.cpp \ sourcelocation.cpp \ sourcemarker.cpp \ - symbol.cpp \ unit.cpp \ unsavedfiledata.cpp \ utils.cpp \ @@ -76,6 +76,7 @@ HEADERS += \ clangmodelmanagersupport.h \ clangprojectsettings.h \ clangprojectsettingspropertiespage.h \ + clangsymbol.h \ clangtextmark.h \ clangutils.h \ completionchunkstotextconverter.h \ @@ -91,7 +92,6 @@ HEADERS += \ semanticmarker.h \ sourcelocation.h \ sourcemarker.h \ - symbol.h \ unit.h \ unsavedfiledata.h \ utils.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index 858903aa776..26543eda86b 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -143,6 +143,8 @@ QtcPlugin { "clangprojectsettingspropertiespage.cpp", "clangprojectsettingspropertiespage.h", "clangprojectsettingspropertiespage.ui", + "clangsymbol.cpp", + "clangsymbol.h", "clangtextmark.cpp", "clangtextmark.h", "clangutils.cpp", @@ -169,8 +171,6 @@ QtcPlugin { "sourcelocation.h", "sourcemarker.cpp", "sourcemarker.h", - "symbol.cpp", - "symbol.h", "unit.cpp", "unit.h", "unsavedfiledata.cpp", diff --git a/src/plugins/clangcodemodel/symbol.cpp b/src/plugins/clangcodemodel/clangsymbol.cpp similarity index 99% rename from src/plugins/clangcodemodel/symbol.cpp rename to src/plugins/clangcodemodel/clangsymbol.cpp index b37270c7453..a4c9a024f46 100644 --- a/src/plugins/clangcodemodel/symbol.cpp +++ b/src/plugins/clangcodemodel/clangsymbol.cpp @@ -28,7 +28,7 @@ ** ****************************************************************************/ -#include "symbol.h" +#include "clangsymbol.h" #include diff --git a/src/plugins/clangcodemodel/symbol.h b/src/plugins/clangcodemodel/clangsymbol.h similarity index 100% rename from src/plugins/clangcodemodel/symbol.h rename to src/plugins/clangcodemodel/clangsymbol.h diff --git a/src/plugins/clangcodemodel/index.h b/src/plugins/clangcodemodel/index.h index 6809e4676a6..357d136c6b8 100644 --- a/src/plugins/clangcodemodel/index.h +++ b/src/plugins/clangcodemodel/index.h @@ -31,7 +31,7 @@ #ifndef INDEX_H #define INDEX_H -#include "symbol.h" +#include "clangsymbol.h" #include #include diff --git a/src/plugins/clangcodemodel/indexer.h b/src/plugins/clangcodemodel/indexer.h index 5a1c435494d..dbe352ae58a 100644 --- a/src/plugins/clangcodemodel/indexer.h +++ b/src/plugins/clangcodemodel/indexer.h @@ -32,7 +32,7 @@ #define INDEXER_H #include "clang_global.h" -#include "symbol.h" +#include "clangsymbol.h" #include "unit.h" #include diff --git a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri index 93131082bf9..1724c5799c2 100644 --- a/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri +++ b/src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri @@ -3,7 +3,6 @@ INCLUDEPATH += $$PWD HEADERS += $$PWD/clangipcserver.h \ $$PWD/codecompleter.h \ $$PWD/clangstring.h \ - $$PWD/translationunit.h \ $$PWD/translationunitisnullexception.h \ $$PWD/codecompletefailedexception.h \ $$PWD/clangcodecompleteresults.h \ @@ -27,16 +26,16 @@ HEADERS += $$PWD/clangipcserver.h \ $$PWD/translationunitalreadyexistsexception.h \ $$PWD/commandlinearguments.h \ $$PWD/cursor.h \ - $$PWD/type.h \ $$PWD/highlightinginformations.h \ $$PWD/highlightinginformation.h \ $$PWD/highlightinginformationsiterator.h \ - $$PWD/skippedsourceranges.h + $$PWD/skippedsourceranges.h \ + $$PWD/clangtranslationunit.h \ + $$PWD/clangtype.h SOURCES += $$PWD/clangipcserver.cpp \ $$PWD/codecompleter.cpp \ $$PWD/clangstring.cpp \ - $$PWD/translationunit.cpp \ $$PWD/translationunitisnullexception.cpp \ $$PWD/codecompletefailedexception.cpp \ $$PWD/clangcodecompleteresults.cpp \ @@ -59,7 +58,8 @@ SOURCES += $$PWD/clangipcserver.cpp \ $$PWD/translationunitalreadyexistsexception.cpp \ $$PWD/commandlinearguments.cpp \ $$PWD/cursor.cpp \ - $$PWD/type.cpp \ $$PWD/highlightinginformations.cpp \ $$PWD/highlightinginformation.cpp \ - $$PWD/skippedsourceranges.cpp + $$PWD/skippedsourceranges.cpp \ + $$PWD/clangtranslationunit.cpp \ + $$PWD/clangtype.cpp diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.h b/src/tools/clangbackend/ipcsource/clangipcserver.h index bfb1313e64f..88daf5b4104 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.h +++ b/src/tools/clangbackend/ipcsource/clangipcserver.h @@ -35,7 +35,7 @@ #include "projectpart.h" #include "projects.h" -#include "translationunit.h" +#include "clangtranslationunit.h" #include "translationunits.h" #include "unsavedfiles.h" diff --git a/src/tools/clangbackend/ipcsource/translationunit.cpp b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp similarity index 99% rename from src/tools/clangbackend/ipcsource/translationunit.cpp rename to src/tools/clangbackend/ipcsource/clangtranslationunit.cpp index cd880f0567d..ed9799652a4 100644 --- a/src/tools/clangbackend/ipcsource/translationunit.cpp +++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp @@ -28,7 +28,7 @@ ** ****************************************************************************/ -#include "translationunit.h" +#include "clangtranslationunit.h" #include "cursor.h" #include "clangstring.h" diff --git a/src/tools/clangbackend/ipcsource/translationunit.h b/src/tools/clangbackend/ipcsource/clangtranslationunit.h similarity index 100% rename from src/tools/clangbackend/ipcsource/translationunit.h rename to src/tools/clangbackend/ipcsource/clangtranslationunit.h diff --git a/src/tools/clangbackend/ipcsource/type.cpp b/src/tools/clangbackend/ipcsource/clangtype.cpp similarity index 99% rename from src/tools/clangbackend/ipcsource/type.cpp rename to src/tools/clangbackend/ipcsource/clangtype.cpp index a1f78e44eb2..b839a8dee39 100644 --- a/src/tools/clangbackend/ipcsource/type.cpp +++ b/src/tools/clangbackend/ipcsource/clangtype.cpp @@ -28,7 +28,7 @@ ** ****************************************************************************/ -#include "type.h" +#include "clangtype.h" #include "clangstring.h" #include "cursor.h" diff --git a/src/tools/clangbackend/ipcsource/type.h b/src/tools/clangbackend/ipcsource/clangtype.h similarity index 100% rename from src/tools/clangbackend/ipcsource/type.h rename to src/tools/clangbackend/ipcsource/clangtype.h diff --git a/src/tools/clangbackend/ipcsource/codecompleter.cpp b/src/tools/clangbackend/ipcsource/codecompleter.cpp index 3f581b5c1cb..99d0637a03e 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.cpp +++ b/src/tools/clangbackend/ipcsource/codecompleter.cpp @@ -34,7 +34,7 @@ #include "clangstring.h" #include "codecompletefailedexception.h" #include "codecompletionsextractor.h" -#include "translationunit.h" +#include "clangtranslationunit.h" #include diff --git a/src/tools/clangbackend/ipcsource/codecompleter.h b/src/tools/clangbackend/ipcsource/codecompleter.h index 2d2dc1abe0f..971f209c361 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.h +++ b/src/tools/clangbackend/ipcsource/codecompleter.h @@ -31,7 +31,7 @@ #ifndef CLANGBACKEND_CODECOMPLETER_H #define CLANGBACKEND_CODECOMPLETER_H -#include "translationunit.h" +#include "clangtranslationunit.h" #include diff --git a/src/tools/clangbackend/ipcsource/cursor.h b/src/tools/clangbackend/ipcsource/cursor.h index d4256401e5d..4b15e232823 100644 --- a/src/tools/clangbackend/ipcsource/cursor.h +++ b/src/tools/clangbackend/ipcsource/cursor.h @@ -31,7 +31,7 @@ #ifndef CLANGBACKEND_CURSOR_H #define CLANGBACKEND_CURSOR_H -#include "type.h" +#include "clangtype.h" #include diff --git a/src/tools/clangbackend/ipcsource/sourcelocation.cpp b/src/tools/clangbackend/ipcsource/sourcelocation.cpp index e04f44c7d88..92c5464d7f8 100644 --- a/src/tools/clangbackend/ipcsource/sourcelocation.cpp +++ b/src/tools/clangbackend/ipcsource/sourcelocation.cpp @@ -31,7 +31,7 @@ #include "sourcelocation.h" #include "clangstring.h" -#include "translationunit.h" +#include "clangtranslationunit.h" #include diff --git a/src/tools/clangbackend/ipcsource/translationunits.h b/src/tools/clangbackend/ipcsource/translationunits.h index a08d642d48b..abc0c4670f8 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.h +++ b/src/tools/clangbackend/ipcsource/translationunits.h @@ -32,7 +32,7 @@ #define CLANGBACKEND_TRANSLATIONUNITS_H #include "clangfilesystemwatcher.h" -#include "translationunit.h" +#include "clangtranslationunit.h" #include diff --git a/tests/unit/unittest/clangcodecompleteresultstest.cpp b/tests/unit/unittest/clangcodecompleteresultstest.cpp index c91c80ec932..410d73dad7d 100644 --- a/tests/unit/unittest/clangcodecompleteresultstest.cpp +++ b/tests/unit/unittest/clangcodecompleteresultstest.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/codecompletionsextractortest.cpp b/tests/unit/unittest/codecompletionsextractortest.cpp index 42b5a6152b4..cf31413085b 100644 --- a/tests/unit/unittest/codecompletionsextractortest.cpp +++ b/tests/unit/unittest/codecompletionsextractortest.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/codecompletiontest.cpp b/tests/unit/unittest/codecompletiontest.cpp index 33a79d177be..3fbc7d0a203 100644 --- a/tests/unit/unittest/codecompletiontest.cpp +++ b/tests/unit/unittest/codecompletiontest.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/cursortest.cpp b/tests/unit/unittest/cursortest.cpp index e0e18c13083..c095122081e 100644 --- a/tests/unit/unittest/cursortest.cpp +++ b/tests/unit/unittest/cursortest.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/unit/unittest/diagnosticsettest.cpp b/tests/unit/unittest/diagnosticsettest.cpp index a3d89e5105d..e1271cbe075 100644 --- a/tests/unit/unittest/diagnosticsettest.cpp +++ b/tests/unit/unittest/diagnosticsettest.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/unit/unittest/diagnostictest.cpp b/tests/unit/unittest/diagnostictest.cpp index 01925a980df..bc81ba8d477 100644 --- a/tests/unit/unittest/diagnostictest.cpp +++ b/tests/unit/unittest/diagnostictest.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/fixittest.cpp b/tests/unit/unittest/fixittest.cpp index 6942bf6e323..4de92f3990f 100644 --- a/tests/unit/unittest/fixittest.cpp +++ b/tests/unit/unittest/fixittest.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/highlightinginformationstest.cpp b/tests/unit/unittest/highlightinginformationstest.cpp index 8e5ee4f0ee0..39238d8f7a8 100644 --- a/tests/unit/unittest/highlightinginformationstest.cpp +++ b/tests/unit/unittest/highlightinginformationstest.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/unit/unittest/skippedsourcerangestest.cpp b/tests/unit/unittest/skippedsourcerangestest.cpp index b37b8726909..33506efb334 100644 --- a/tests/unit/unittest/skippedsourcerangestest.cpp +++ b/tests/unit/unittest/skippedsourcerangestest.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/unit/unittest/sourcelocationtest.cpp b/tests/unit/unittest/sourcelocationtest.cpp index 9213d9359c3..4cbab547627 100644 --- a/tests/unit/unittest/sourcelocationtest.cpp +++ b/tests/unit/unittest/sourcelocationtest.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/sourcerangetest.cpp b/tests/unit/unittest/sourcerangetest.cpp index b517c423804..1e18225fb5a 100644 --- a/tests/unit/unittest/sourcerangetest.cpp +++ b/tests/unit/unittest/sourcerangetest.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/translationunitstest.cpp b/tests/unit/unittest/translationunitstest.cpp index 0b19ecdf62d..9c84b4973ed 100644 --- a/tests/unit/unittest/translationunitstest.cpp +++ b/tests/unit/unittest/translationunitstest.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/unittest/translationunittest.cpp b/tests/unit/unittest/translationunittest.cpp index 4bc2d110611..12b0137a6e1 100644 --- a/tests/unit/unittest/translationunittest.cpp +++ b/tests/unit/unittest/translationunittest.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include From 7874d619984566856143e39bef0d0c8431cc3d36 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 24 Nov 2015 17:44:48 +0100 Subject: [PATCH 05/47] Clang: Enable not exporting symbols Having a dllexport in the sources for a TEMPLATE=app project (e.g. unittest.pro) will create a library on Windows, which is not needed. Change-Id: I1ebdd8b5ada06965c3dd89074ac2bc6dff09299c Reviewed-by: Marco Bubke --- src/libs/clangbackendipc/clangbackendipc-lib.pri | 2 -- src/libs/clangbackendipc/clangbackendipc_global.h | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri index 3084a13761b..6ac4144d5cb 100644 --- a/src/libs/clangbackendipc/clangbackendipc-lib.pri +++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri @@ -6,8 +6,6 @@ contains(CONFIG, dll) { QT += network -DEFINES += CLANGBACKENDIPC_LIBRARY - INCLUDEPATH += $$PWD SOURCES += $$PWD/ipcserverinterface.cpp \ diff --git a/src/libs/clangbackendipc/clangbackendipc_global.h b/src/libs/clangbackendipc/clangbackendipc_global.h index c9851069b58..3efaf48c3c3 100644 --- a/src/libs/clangbackendipc/clangbackendipc_global.h +++ b/src/libs/clangbackendipc/clangbackendipc_global.h @@ -33,8 +33,10 @@ #include -#if defined(CLANGBACKENDIPC_LIBRARY) +#if defined(CLANGBACKENDIPC_BUILD_LIB) # define CMBIPC_EXPORT Q_DECL_EXPORT +#elif defined(CLANGBACKENDIPC_BUILD_STATIC_LIB) +# define CMBIPC_EXPORT #else # define CMBIPC_EXPORT Q_DECL_IMPORT #endif From eaa93e86317eed6a325bd5196b317281a3a4f52b Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 25 Nov 2015 11:07:35 +0100 Subject: [PATCH 06/47] CppTools: Enable not exporting symbols Having a dllexport in the sources for a TEMPLATE=app project (e.g. unittest.pro) will create a library on Windows, which is not needed. Change-Id: I0d454cdb7e3eb862200766ea101d41cef2758986 Reviewed-by: Marco Bubke --- src/plugins/cpptools/cpptools_global.h | 2 ++ src/plugins/cpptools/cpptoolsunittestfiles.pri | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/plugins/cpptools/cpptools_global.h b/src/plugins/cpptools/cpptools_global.h index 57b5dbab707..b30e9e29190 100644 --- a/src/plugins/cpptools/cpptools_global.h +++ b/src/plugins/cpptools/cpptools_global.h @@ -35,6 +35,8 @@ #if defined(CPPTOOLS_LIBRARY) # define CPPTOOLS_EXPORT Q_DECL_EXPORT +#elif defined(CPPTOOLS_STATIC_LIBRARY) +# define CPPTOOLS_EXPORT #else # define CPPTOOLS_EXPORT Q_DECL_IMPORT #endif diff --git a/src/plugins/cpptools/cpptoolsunittestfiles.pri b/src/plugins/cpptools/cpptoolsunittestfiles.pri index 6e0ab0d990c..2d011718e66 100644 --- a/src/plugins/cpptools/cpptoolsunittestfiles.pri +++ b/src/plugins/cpptools/cpptoolsunittestfiles.pri @@ -1,3 +1,9 @@ +contains(CONFIG, dll) { + DEFINES += CPPTOOLS_LIBRARY +} else { + DEFINES += CPPTOOLS_STATIC_LIBRARY +} + HEADERS += $$PWD/senddocumenttracker.h SOURCES += $$PWD/senddocumenttracker.cpp From e244784ed3f83a4063f5e30835a5531c2bc25860 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 25 Nov 2015 15:01:48 +0100 Subject: [PATCH 07/47] Sqlite: Move export define to *.pro ...since we do not need that in e.g. unittest.pro. Change-Id: I90da96e81eae3f0fdffd073c4314502c1e0d0c83 Reviewed-by: Marco Bubke --- src/libs/3rdparty/sqlite/sqlite.pri | 4 ---- src/libs/sqlite/sqlite.pro | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/3rdparty/sqlite/sqlite.pri b/src/libs/3rdparty/sqlite/sqlite.pri index 896616f7360..469a76955e9 100644 --- a/src/libs/3rdparty/sqlite/sqlite.pri +++ b/src/libs/3rdparty/sqlite/sqlite.pri @@ -4,12 +4,8 @@ HEADERS += $$PWD/okapi_bm25.h \ $$PWD/sqlite3.h \ $$PWD/sqlite3ext.h - SOURCES += $$PWD/sqlite3.c -win32:DEFINES += SQLITE_API=__declspec(dllexport) -unix:DEFINES += SQLITE_API=\"__attribute__((visibility(\\\"default\\\")))\" - gcc { QMAKE_CFLAGS_WARN_ON = -w } diff --git a/src/libs/sqlite/sqlite.pro b/src/libs/sqlite/sqlite.pro index 741e6a6cbfa..f3c75fa3731 100644 --- a/src/libs/sqlite/sqlite.pro +++ b/src/libs/sqlite/sqlite.pro @@ -2,4 +2,8 @@ unix:QMAKE_CXXFLAGS_DEBUG += -O2 win32:QMAKE_CXXFLAGS_DEBUG += -O2 include(../../qtcreatorlibrary.pri) + +win32:DEFINES += SQLITE_API=__declspec(dllexport) +unix:DEFINES += SQLITE_API=\"__attribute__((visibility(\\\"default\\\")))\" + include(sqlite-lib.pri) From eb2457869d2c2b44fcbf6665c5fef9188ac8b240 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 26 Nov 2015 14:11:39 +0100 Subject: [PATCH 08/47] Clang: Remove faulty copy constructor of HighlightingInformationsIterator The test HighlightingInformations.ForFullTranslationUnitRange crashed on Windows because of this. Change-Id: I6dbf1e1ce127fedceccea92afe7c59c1d6a90db7 Reviewed-by: Marco Bubke --- .../clangbackend/ipcsource/highlightinginformationsiterator.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tools/clangbackend/ipcsource/highlightinginformationsiterator.h b/src/tools/clangbackend/ipcsource/highlightinginformationsiterator.h index 53f540970e6..ae868569bf1 100644 --- a/src/tools/clangbackend/ipcsource/highlightinginformationsiterator.h +++ b/src/tools/clangbackend/ipcsource/highlightinginformationsiterator.h @@ -56,10 +56,6 @@ public: cxTranslationUnit(cxTranslationUnit) {} - HighlightingInformationsIterator(const HighlightingInformationsIterator &other) - : cxCursorIterator(other.cxCursorIterator) - {} - HighlightingInformationsIterator& operator++() { ++cxCursorIterator; From 7ce9ef9db4ae499f4c7ac67e3640785634d5e369 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 18 Nov 2015 17:07:44 +0100 Subject: [PATCH 09/47] Clang: Integrate highlighting results from backend Change-Id: I2c3fb69aabfe075bde76d63eafc2ca370f17493c Reviewed-by: Marco Bubke --- .../clangbackendipc/clangbackendipc-lib.pri | 10 +- src/libs/clangbackendipc/cmbmessages.cpp | 7 + .../highlightingchangedmessage.cpp | 119 +++++++++++ .../highlightingchangedmessage.h | 80 ++++++++ .../highlightingmarkcontainer.cpp | 173 ++++++++++++++++ .../highlightingmarkcontainer.h | 79 ++++++++ .../clangbackendipc/ipcclientdispatcher.cpp | 6 + .../clangbackendipc/ipcclientdispatcher.h | 1 + .../clangbackendipc/ipcclientinterface.cpp | 4 + src/libs/clangbackendipc/ipcclientinterface.h | 3 + src/libs/clangbackendipc/ipcclientproxy.cpp | 6 + src/libs/clangbackendipc/ipcclientproxy.h | 1 + .../clangbackendipc/ipcserverinterface.cpp | 5 +- src/libs/clangbackendipc/ipcserverinterface.h | 1 + src/libs/clangbackendipc/ipcserverproxy.cpp | 6 + src/libs/clangbackendipc/ipcserverproxy.h | 2 + .../requesthighlightingmessage.cpp | 89 ++++++++ .../requesthighlightingmessage.h | 69 +++++++ .../clangbackendipcintegration.cpp | 74 +++++-- .../clangbackendipcintegration.h | 12 +- src/plugins/clangcodemodel/clangcodemodel.pro | 2 + src/plugins/clangcodemodel/clangcodemodel.qbs | 2 + .../clangcodemodel/clangcodemodelplugin.cpp | 5 - .../clangcodemodel/clangcodemodelplugin.h | 2 - .../clangcodemodelunittestfiles.pri | 6 +- .../clangeditordocumentparser.cpp | 91 +-------- .../clangeditordocumentparser.h | 15 +- .../clangeditordocumentprocessor.cpp | 116 +++++------ .../clangeditordocumentprocessor.h | 12 +- .../clangmodelmanagersupport.cpp | 2 +- .../highlightingmarksreporter.cpp | 155 ++++++++++++++ .../highlightingmarksreporter.h | 80 ++++++++ .../test/clangcodecompletion_test.cpp | 7 + src/plugins/cpptools/cppprojects.h | 2 - .../clangbackend/ipcsource/clangipcserver.cpp | 83 +++++--- .../clangbackend/ipcsource/clangipcserver.h | 5 +- .../ipcsource/clangtranslationunit.cpp | 14 ++ .../ipcsource/clangtranslationunit.h | 2 + .../ipcsource/highlightinginformation.cpp | 35 +--- .../ipcsource/highlightinginformation.h | 4 +- .../ipcsource/highlightinginformations.cpp | 18 ++ .../ipcsource/highlightinginformations.h | 3 + .../ipcsource/translationunits.cpp | 79 +++++--- .../clangbackend/ipcsource/translationunits.h | 28 ++- tests/unit/echoserver/echoipcserver.cpp | 6 + tests/unit/echoserver/echoipcserver.h | 1 + .../mockup/texteditor/semantichighlighter.h | 68 +++++++ tests/unit/unittest/chunksreportedmonitor.cpp | 64 ++++++ tests/unit/unittest/chunksreportedmonitor.h | 63 ++++++ tests/unit/unittest/clangipcservertest.cpp | 20 ++ .../unittest/clientserverinprocesstest.cpp | 28 +++ .../unittest/clientserveroutsideprocess.cpp | 1 + .../unittest/highlightinginformationstest.cpp | 8 + .../highlightingmarksreportertest.cpp | 190 ++++++++++++++++++ tests/unit/unittest/mockipclient.h | 2 + tests/unit/unittest/mockipcserver.h | 2 + ...back.h => mocksendeditorupdatescallback.h} | 16 +- .../unittest/readandwritemessageblocktest.cpp | 17 ++ tests/unit/unittest/translationunitstest.cpp | 134 +++++++----- tests/unit/unittest/translationunittest.cpp | 106 ++++++---- tests/unit/unittest/unittest.pro | 7 +- 61 files changed, 1855 insertions(+), 393 deletions(-) create mode 100644 src/libs/clangbackendipc/highlightingchangedmessage.cpp create mode 100644 src/libs/clangbackendipc/highlightingchangedmessage.h create mode 100644 src/libs/clangbackendipc/highlightingmarkcontainer.cpp create mode 100644 src/libs/clangbackendipc/highlightingmarkcontainer.h create mode 100644 src/libs/clangbackendipc/requesthighlightingmessage.cpp create mode 100644 src/libs/clangbackendipc/requesthighlightingmessage.h create mode 100644 src/plugins/clangcodemodel/highlightingmarksreporter.cpp create mode 100644 src/plugins/clangcodemodel/highlightingmarksreporter.h create mode 100644 tests/unit/mockup/texteditor/semantichighlighter.h create mode 100644 tests/unit/unittest/chunksreportedmonitor.cpp create mode 100644 tests/unit/unittest/chunksreportedmonitor.h create mode 100644 tests/unit/unittest/highlightingmarksreportertest.cpp rename tests/unit/unittest/{mocksenddiagnosticscallback.h => mocksendeditorupdatescallback.h} (82%) diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri index 6ac4144d5cb..cbe5ad01fe3 100644 --- a/src/libs/clangbackendipc/clangbackendipc-lib.pri +++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri @@ -42,10 +42,13 @@ SOURCES += $$PWD/ipcserverinterface.cpp \ $$PWD/sourcelocationcontainer.cpp \ $$PWD/fixitcontainer.cpp \ $$PWD/requestdiagnosticsmessage.cpp \ + $$PWD/requesthighlightingmessage.cpp \ $$PWD/registerunsavedfilesforeditormessage.cpp \ $$PWD/unregisterunsavedfilesforeditormessage.cpp \ $$PWD/updatetranslationunitsforeditormessage.cpp \ - $$PWD/updatevisibletranslationunitsmessage.cpp + $$PWD/updatevisibletranslationunitsmessage.cpp \ + $$PWD/highlightingchangedmessage.cpp \ + $$PWD/highlightingmarkcontainer.cpp HEADERS += \ $$PWD/ipcserverinterface.h \ @@ -84,9 +87,12 @@ HEADERS += \ $$PWD/sourcelocationcontainer.h \ $$PWD/fixitcontainer.h \ $$PWD/requestdiagnosticsmessage.h \ + $$PWD/requesthighlightingmessage.h \ $$PWD/registerunsavedfilesforeditormessage.h \ $$PWD/unregisterunsavedfilesforeditormessage.h \ $$PWD/updatetranslationunitsforeditormessage.h \ - $$PWD/updatevisibletranslationunitsmessage.h + $$PWD/updatevisibletranslationunitsmessage.h \ + $$PWD/highlightingchangedmessage.h \ + $$PWD/highlightingmarkcontainer.h contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols diff --git a/src/libs/clangbackendipc/cmbmessages.cpp b/src/libs/clangbackendipc/cmbmessages.cpp index d275de5353d..c3ce8d0e172 100644 --- a/src/libs/clangbackendipc/cmbmessages.cpp +++ b/src/libs/clangbackendipc/cmbmessages.cpp @@ -43,6 +43,9 @@ #include "diagnosticschangedmessage.h" #include "registerunsavedfilesforeditormessage.h" #include "requestdiagnosticsmessage.h" +#include "requesthighlightingmessage.h" +#include "highlightingchangedmessage.h" +#include "highlightingmarkcontainer.h" #include "projectpartsdonotexistmessage.h" #include "sourcelocationcontainer.h" #include "sourcerangecontainer.h" @@ -83,6 +86,9 @@ void Messages::registerMessages() registerMetaType(); registerMetaType(); + registerMetaType(); + registerMetaType(); + registerMetaType(); registerMetaType(); @@ -94,6 +100,7 @@ void Messages::registerMessages() // Containers registerMetaType(); + registerMetaType(); registerMetaType(); registerMetaType(); registerMetaType(); diff --git a/src/libs/clangbackendipc/highlightingchangedmessage.cpp b/src/libs/clangbackendipc/highlightingchangedmessage.cpp new file mode 100644 index 00000000000..b049ebef529 --- /dev/null +++ b/src/libs/clangbackendipc/highlightingchangedmessage.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "highlightingchangedmessage.h" + +#include "container_common.h" + +#include +#include + +#include + +namespace ClangBackEnd { + +HighlightingChangedMessage::HighlightingChangedMessage(const FileContainer &file, + const QVector &highlightingMarks, + const QVector &skippedPreprocessorRanges) + : file_(file), + highlightingMarks_(highlightingMarks), + skippedPreprocessorRanges_(skippedPreprocessorRanges) +{ +} + +const FileContainer &HighlightingChangedMessage::file() const +{ + return file_; +} + +const QVector &HighlightingChangedMessage::highlightingMarks() const +{ + return highlightingMarks_; +} + +const QVector &HighlightingChangedMessage::skippedPreprocessorRanges() const +{ + return skippedPreprocessorRanges_; +} + +QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message) +{ + out << message.file_; + out << message.highlightingMarks_; + out << message.skippedPreprocessorRanges_; + + return out; +} + +QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message) +{ + in >> message.file_; + in >> message.highlightingMarks_; + in >> message.skippedPreprocessorRanges_; + + return in; +} + +bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second) +{ + return first.file_ == second.file_ + && first.highlightingMarks_ == second.highlightingMarks_ + && first.skippedPreprocessorRanges_ == second.skippedPreprocessorRanges_; +} + +bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second) +{ + return first.file_ < second.file_ + && compareContainer(first.highlightingMarks_, second.highlightingMarks_) + && compareContainer(first.skippedPreprocessorRanges_, second.skippedPreprocessorRanges_); +} + +QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message) +{ + debug.nospace() << "HighlightingChangedMessage(" + << message.file_ + << ", " << message.highlightingMarks_.size() + << ", " << message.skippedPreprocessorRanges_.size() + << ")"; + + return debug; +} + +void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os) +{ + *os << "HighlightingChangedMessage("; + PrintTo(message.file(), os); + *os << "," << message.highlightingMarks().size(); + *os << "," << message.skippedPreprocessorRanges().size(); + *os << ")"; +} + +} // namespace ClangBackEnd + diff --git a/src/libs/clangbackendipc/highlightingchangedmessage.h b/src/libs/clangbackendipc/highlightingchangedmessage.h new file mode 100644 index 00000000000..6efabe19eeb --- /dev/null +++ b/src/libs/clangbackendipc/highlightingchangedmessage.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H +#define CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H + +#include "clangbackendipc_global.h" +#include "filecontainer.h" +#include "highlightingmarkcontainer.h" +#include "sourcerangecontainer.h" + +#include + +namespace ClangBackEnd { + +class CMBIPC_EXPORT HighlightingChangedMessage +{ + friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message); + friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message); + friend CMBIPC_EXPORT bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second); + friend CMBIPC_EXPORT bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second); + friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message); + friend void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os); + +public: + HighlightingChangedMessage() = default; + HighlightingChangedMessage(const FileContainer &file, + const QVector &highlightingMarks, + const QVector &skippedPreprocessorRanges); + + const FileContainer &file() const; + const QVector &highlightingMarks() const; + const QVector &skippedPreprocessorRanges() const; + +private: + FileContainer file_; + QVector highlightingMarks_; + QVector skippedPreprocessorRanges_; +}; + +CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingChangedMessage &message); +CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingChangedMessage &message); +CMBIPC_EXPORT bool operator==(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second); +CMBIPC_EXPORT bool operator<(const HighlightingChangedMessage &first, const HighlightingChangedMessage &second); + +CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingChangedMessage &message); +void PrintTo(const HighlightingChangedMessage &message, ::std::ostream* os); + +} // namespace ClangBackEnd + +Q_DECLARE_METATYPE(ClangBackEnd::HighlightingChangedMessage) + +#endif // CLANGBACKEND_HIGHLIGHTINGCHANGEDMESSAGE_H diff --git a/src/libs/clangbackendipc/highlightingmarkcontainer.cpp b/src/libs/clangbackendipc/highlightingmarkcontainer.cpp new file mode 100644 index 00000000000..efa5b04af26 --- /dev/null +++ b/src/libs/clangbackendipc/highlightingmarkcontainer.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "highlightingmarkcontainer.h" + +#include +#include + +#include + +namespace ClangBackEnd { + +HighlightingMarkContainer::HighlightingMarkContainer(uint line, + uint column, + uint length, + HighlightingType type) + : line_(line), + column_(column), + length_(length), + type_(type) +{ +} + +uint HighlightingMarkContainer::line() const +{ + return line_; +} + +uint HighlightingMarkContainer::column() const +{ + return column_; +} + +uint HighlightingMarkContainer::length() const +{ + return length_; +} + +HighlightingType HighlightingMarkContainer::type() const +{ + return type_; +} + +quint32 &HighlightingMarkContainer::typeAsInt() +{ + return reinterpret_cast(type_); +} + +QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container) +{ + out << container.line_; + out << container.column_; + out << container.length_; + out << quint32(container.type_); + + return out; +} + +QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container) +{ + in >> container.line_; + in >> container.column_; + in >> container.length_; + in >> container.typeAsInt(); + + return in; +} + +bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second) +{ + return first.line_ == second.line_ + && first.column_ == second.column_ + && first.length_ == second.length_ + && first.type_ == second.type_; +} + +bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second) +{ + if (first.line() == second.line()) { + if (first.column() == second.column()) { + if (first.length() == second.length()) + return first.type() < second.type(); + return first.length() < second.length(); + } + + return first.column() < second.column(); + } + + return first.line() < second.line(); +} + +#define RETURN_TEXT_FOR_CASE(enumValue) case HighlightingType::enumValue: return #enumValue +static const char *highlightingTypeToCStringLiteral(HighlightingType type) +{ + switch (type) { + RETURN_TEXT_FOR_CASE(Invalid); + RETURN_TEXT_FOR_CASE(Comment); + RETURN_TEXT_FOR_CASE(Keyword); + RETURN_TEXT_FOR_CASE(StringLiteral); + RETURN_TEXT_FOR_CASE(NumberLiteral); + RETURN_TEXT_FOR_CASE(Function); + RETURN_TEXT_FOR_CASE(VirtualFunction); + RETURN_TEXT_FOR_CASE(Type); + RETURN_TEXT_FOR_CASE(LocalVariable); + RETURN_TEXT_FOR_CASE(GlobalVariable); + RETURN_TEXT_FOR_CASE(Field); + RETURN_TEXT_FOR_CASE(Enumeration); + RETURN_TEXT_FOR_CASE(Operator); + RETURN_TEXT_FOR_CASE(Preprocessor); + RETURN_TEXT_FOR_CASE(Label); + RETURN_TEXT_FOR_CASE(OutputArgument); + RETURN_TEXT_FOR_CASE(PreprocessorDefinition); + RETURN_TEXT_FOR_CASE(PreprocessorExpansion); + default: return "UnhandledHighlightingType"; + } +} +#undef RETURN_TEXT_FOR_CASE + +QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container) +{ + debug.nospace() << "HighlightingMarkContainer(" + << container.line() << ", " + << container.column() << ", " + << container.length() << ", " + << highlightingTypeToCStringLiteral(container.type()) << ", " + << ")"; + + return debug; +} + +void PrintTo(HighlightingType highlightingType, std::ostream *os) +{ + *os << highlightingTypeToCStringLiteral(highlightingType); +} + +void PrintTo(const HighlightingMarkContainer& container, ::std::ostream *os) +{ + *os << "HighlightingMarkContainer(" + << container.line() << ", " + << container.column() << ", " + << container.length() << ", "; + PrintTo(container.type(), os); + *os << ")"; +} + +} // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/highlightingmarkcontainer.h b/src/libs/clangbackendipc/highlightingmarkcontainer.h new file mode 100644 index 00000000000..e466cb868ee --- /dev/null +++ b/src/libs/clangbackendipc/highlightingmarkcontainer.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H +#define CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H + +#include "clangbackendipc_global.h" + +#include + +namespace ClangBackEnd { + +class CMBIPC_EXPORT HighlightingMarkContainer +{ + friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container); + friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container); + friend CMBIPC_EXPORT bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second); + friend CMBIPC_EXPORT bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second); + +public: + HighlightingMarkContainer() = default; + HighlightingMarkContainer(uint line, uint column, uint length, HighlightingType type); + + uint line() const; + uint column() const; + uint length() const; + HighlightingType type() const; + +private: + quint32 &typeAsInt(); + +private: + uint line_; + uint column_; + uint length_; + HighlightingType type_; +}; + +CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &container); +CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, HighlightingMarkContainer &container); +CMBIPC_EXPORT bool operator==(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second); +CMBIPC_EXPORT bool operator<(const HighlightingMarkContainer &first, const HighlightingMarkContainer &second); + +CMBIPC_EXPORT QDebug operator<<(QDebug debug, const HighlightingMarkContainer &container); +CMBIPC_EXPORT void PrintTo(HighlightingType highlightingType, ::std::ostream *os); +void PrintTo(const HighlightingMarkContainer &container, ::std::ostream *os); + +} // namespace ClangBackEnd + +Q_DECLARE_METATYPE(ClangBackEnd::HighlightingMarkContainer) + +#endif // CLANGBACKEND_HIGHLIGHTINGMARKCONTAINER_H diff --git a/src/libs/clangbackendipc/ipcclientdispatcher.cpp b/src/libs/clangbackendipc/ipcclientdispatcher.cpp index bd9c7eb7f24..6b22a29f4a1 100644 --- a/src/libs/clangbackendipc/ipcclientdispatcher.cpp +++ b/src/libs/clangbackendipc/ipcclientdispatcher.cpp @@ -80,5 +80,11 @@ void IpcClientDispatcher::diagnosticsChanged(const DiagnosticsChangedMessage &me client->diagnosticsChanged(message); } +void IpcClientDispatcher::highlightingChanged(const HighlightingChangedMessage &message) +{ + for (auto *client : clients) + client->highlightingChanged(message); +} + } // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/ipcclientdispatcher.h b/src/libs/clangbackendipc/ipcclientdispatcher.h index 7d8329e4165..e8445df1f07 100644 --- a/src/libs/clangbackendipc/ipcclientdispatcher.h +++ b/src/libs/clangbackendipc/ipcclientdispatcher.h @@ -49,6 +49,7 @@ public: void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override; void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override; void diagnosticsChanged(const DiagnosticsChangedMessage &message) override; + void highlightingChanged(const HighlightingChangedMessage &message) override; private: QVector clients; diff --git a/src/libs/clangbackendipc/ipcclientinterface.cpp b/src/libs/clangbackendipc/ipcclientinterface.cpp index 28d2410662d..b6447949e61 100644 --- a/src/libs/clangbackendipc/ipcclientinterface.cpp +++ b/src/libs/clangbackendipc/ipcclientinterface.cpp @@ -35,6 +35,7 @@ #include "projectpartsdonotexistmessage.h" #include "translationunitdoesnotexistmessage.h" #include "diagnosticschangedmessage.h" +#include "highlightingchangedmessage.h" #include #include @@ -50,6 +51,7 @@ void IpcClientInterface::dispatch(const QVariant &message) static const int translationUnitDoesNotExistMessage = QMetaType::type("ClangBackEnd::TranslationUnitDoesNotExistMessage"); static const int projectPartsDoNotExistMessage = QMetaType::type("ClangBackEnd::ProjectPartsDoNotExistMessage"); static const int diagnosticsChangedMessage = QMetaType::type("ClangBackEnd::DiagnosticsChangedMessage"); + static const int highlightingChangedMessage = QMetaType::type("ClangBackEnd::HighlightingChangedMessage"); int type = message.userType(); @@ -65,6 +67,8 @@ void IpcClientInterface::dispatch(const QVariant &message) projectPartsDoNotExist(message.value()); else if (type == diagnosticsChangedMessage) diagnosticsChanged(message.value()); + else if (type == highlightingChangedMessage) + highlightingChanged(message.value()); else qWarning() << "Unknown IpcClientMessage"; } diff --git a/src/libs/clangbackendipc/ipcclientinterface.h b/src/libs/clangbackendipc/ipcclientinterface.h index 5600e130763..539371e12db 100644 --- a/src/libs/clangbackendipc/ipcclientinterface.h +++ b/src/libs/clangbackendipc/ipcclientinterface.h @@ -51,6 +51,8 @@ class RequestDiagnosticsMessage; class RegisterUnsavedFilesForEditorMessage; class UnregisterUnsavedFilesForEditorMessage; class UpdateVisibleTranslationUnitsMessage; +class RequestHighlightingMessage; +class HighlightingChangedMessage; class CMBIPC_EXPORT IpcClientInterface : public IpcInterface { @@ -63,6 +65,7 @@ public: virtual void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) = 0; virtual void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) = 0; virtual void diagnosticsChanged(const DiagnosticsChangedMessage &message) = 0; + virtual void highlightingChanged(const HighlightingChangedMessage &message) = 0; }; } // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/ipcclientproxy.cpp b/src/libs/clangbackendipc/ipcclientproxy.cpp index cb058b7bb49..cbfddf85221 100644 --- a/src/libs/clangbackendipc/ipcclientproxy.cpp +++ b/src/libs/clangbackendipc/ipcclientproxy.cpp @@ -35,6 +35,7 @@ #include "cmbechomessage.h" #include "cmbregistertranslationunitsforeditormessage.h" #include "diagnosticschangedmessage.h" +#include "highlightingchangedmessage.h" #include "ipcserverinterface.h" #include "projectpartsdonotexistmessage.h" #include "translationunitdoesnotexistmessage.h" @@ -104,6 +105,11 @@ void IpcClientProxy::diagnosticsChanged(const DiagnosticsChangedMessage &message writeMessageBlock.write(QVariant::fromValue(message)); } +void IpcClientProxy::highlightingChanged(const HighlightingChangedMessage &message) +{ + writeMessageBlock.write(QVariant::fromValue(message)); +} + void IpcClientProxy::readMessages() { for (const QVariant &message : readMessageBlock.readAll()) diff --git a/src/libs/clangbackendipc/ipcclientproxy.h b/src/libs/clangbackendipc/ipcclientproxy.h index 77b53c7cd2d..d239631b9a1 100644 --- a/src/libs/clangbackendipc/ipcclientproxy.h +++ b/src/libs/clangbackendipc/ipcclientproxy.h @@ -63,6 +63,7 @@ public: void translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) override; void projectPartsDoNotExist(const ProjectPartsDoNotExistMessage &message) override; void diagnosticsChanged(const DiagnosticsChangedMessage &message) override; + void highlightingChanged(const HighlightingChangedMessage &message) override; void readMessages(); diff --git a/src/libs/clangbackendipc/ipcserverinterface.cpp b/src/libs/clangbackendipc/ipcserverinterface.cpp index 93717dfa33a..d25fee4525e 100644 --- a/src/libs/clangbackendipc/ipcserverinterface.cpp +++ b/src/libs/clangbackendipc/ipcserverinterface.cpp @@ -37,6 +37,7 @@ #include "cmbunregistertranslationunitsforeditormessage.h" #include "registerunsavedfilesforeditormessage.h" #include "requestdiagnosticsmessage.h" +#include "requesthighlightingmessage.h" #include "unregisterunsavedfilesforeditormessage.h" #include "updatetranslationunitsforeditormessage.h" #include "updatevisibletranslationunitsmessage.h" @@ -58,9 +59,9 @@ void IpcServerInterface::dispatch(const QVariant &message) static const int unregisterUnsavedFilesForEditorMessageType = QMetaType::type("ClangBackEnd::UnregisterUnsavedFilesForEditorMessage"); static const int completeCodeMessageType = QMetaType::type("ClangBackEnd::CompleteCodeMessage"); static const int requestDiagnosticsMessageType = QMetaType::type("ClangBackEnd::RequestDiagnosticsMessage"); + static const int requestHighlightingTypeMessage = QMetaType::type("ClangBackEnd::RequestHighlightingMessage"); static const int updateVisibleTranslationUnitsMessageType = QMetaType::type("ClangBackEnd::UpdateVisibleTranslationUnitsMessage"); - int type = message.userType(); if (type == endMessageType) @@ -83,6 +84,8 @@ void IpcServerInterface::dispatch(const QVariant &message) completeCode(message.value()); else if (type == requestDiagnosticsMessageType) requestDiagnostics(message.value()); + else if (type == requestHighlightingTypeMessage) + requestHighlighting(message.value()); else if (type == updateVisibleTranslationUnitsMessageType) updateVisibleTranslationUnits(message.value()); else diff --git a/src/libs/clangbackendipc/ipcserverinterface.h b/src/libs/clangbackendipc/ipcserverinterface.h index 98d1441c0d5..451bcaab755 100644 --- a/src/libs/clangbackendipc/ipcserverinterface.h +++ b/src/libs/clangbackendipc/ipcserverinterface.h @@ -54,6 +54,7 @@ public: virtual void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) = 0; virtual void completeCode(const CompleteCodeMessage &message) = 0; virtual void requestDiagnostics(const RequestDiagnosticsMessage &message) = 0; + virtual void requestHighlighting(const RequestHighlightingMessage &message) = 0; virtual void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) = 0; void addClient(IpcClientInterface *client); diff --git a/src/libs/clangbackendipc/ipcserverproxy.cpp b/src/libs/clangbackendipc/ipcserverproxy.cpp index fa5777267c8..90419da9589 100644 --- a/src/libs/clangbackendipc/ipcserverproxy.cpp +++ b/src/libs/clangbackendipc/ipcserverproxy.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -120,6 +121,11 @@ void IpcServerProxy::requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMe writeMessageBlock.write(QVariant::fromValue(message)); } +void IpcServerProxy::requestHighlighting(const RequestHighlightingMessage &message) +{ + writeMessageBlock.write(QVariant::fromValue(message)); +} + void IpcServerProxy::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) { writeMessageBlock.write(QVariant::fromValue(message)); diff --git a/src/libs/clangbackendipc/ipcserverproxy.h b/src/libs/clangbackendipc/ipcserverproxy.h index d4c42887f4f..6d6db7e4f2a 100644 --- a/src/libs/clangbackendipc/ipcserverproxy.h +++ b/src/libs/clangbackendipc/ipcserverproxy.h @@ -65,7 +65,9 @@ public: void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override; void completeCode(const CompleteCodeMessage &message) override; void requestDiagnostics(const RequestDiagnosticsMessage &message) override; + void requestHighlighting(const RequestHighlightingMessage &message) override; void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override; + void readMessages(); void resetCounter(); diff --git a/src/libs/clangbackendipc/requesthighlightingmessage.cpp b/src/libs/clangbackendipc/requesthighlightingmessage.cpp new file mode 100644 index 00000000000..8dcc105e1f7 --- /dev/null +++ b/src/libs/clangbackendipc/requesthighlightingmessage.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "requesthighlightingmessage.h" + +#include +#include + +#include + +namespace ClangBackEnd { + +RequestHighlightingMessage::RequestHighlightingMessage(const FileContainer &file) + : fileContainer_(file) +{ +} + +const FileContainer RequestHighlightingMessage::fileContainer() const +{ + return fileContainer_; +} + +QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message) +{ + out << message.fileContainer_; + + return out; +} + +QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message) +{ + in >> message.fileContainer_; + + return in; +} + +bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second) +{ + return first.fileContainer_ == second.fileContainer_; +} + +bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second) +{ + return first.fileContainer_ < second.fileContainer_; +} + +QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message) +{ + debug.nospace() << "RequestHighlightingMessage(" + << message.fileContainer() + << ")"; + + return debug; +} + +void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os) +{ + *os << message.fileContainer().filePath().constData() + << "(" << message.fileContainer().projectPartId().constData() << ")"; +} + +} // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/requesthighlightingmessage.h b/src/libs/clangbackendipc/requesthighlightingmessage.h new file mode 100644 index 00000000000..ff611d52164 --- /dev/null +++ b/src/libs/clangbackendipc/requesthighlightingmessage.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CLANGBACKEND_REQUESTHIGHLIGHTING_H +#define CLANGBACKEND_REQUESTHIGHLIGHTING_H + +#include "filecontainer.h" + +namespace ClangBackEnd { + +class CMBIPC_EXPORT RequestHighlightingMessage +{ + friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message); + friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message); + friend CMBIPC_EXPORT bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second); + friend CMBIPC_EXPORT bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second); + friend CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message); + friend void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os); + +public: + RequestHighlightingMessage() = default; + RequestHighlightingMessage(const FileContainer &fileContainer); + + const FileContainer fileContainer() const; + +private: + FileContainer fileContainer_; +}; + +CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RequestHighlightingMessage &message); +CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, RequestHighlightingMessage &message); +CMBIPC_EXPORT bool operator==(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second); +CMBIPC_EXPORT bool operator<(const RequestHighlightingMessage &first, const RequestHighlightingMessage &second); + +CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RequestHighlightingMessage &message); +void PrintTo(const RequestHighlightingMessage &message, ::std::ostream* os); + +} // namespace ClangBackEnd + +Q_DECLARE_METATYPE(ClangBackEnd::RequestHighlightingMessage) + +#endif // CLANGBACKEND_REQUESTHIGHLIGHTING_H diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 24c3415b0f3..055099e7c6e 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -48,6 +48,7 @@ #include #include +#include #include #include @@ -62,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -174,6 +176,24 @@ void IpcReceiver::diagnosticsChanged(const DiagnosticsChangedMessage &message) } } +void IpcReceiver::highlightingChanged(const HighlightingChangedMessage &message) +{ + qCDebug(log) << "<<< HighlightingChangedMessage with" + << message.highlightingMarks().size() << "items"; + + auto processor = ClangEditorDocumentProcessor::get(message.file().filePath()); + + if (processor && processor->projectPart()) { + const QString highlightingProjectPartId = message.file().projectPartId(); + const QString documentProjectPartId = processor->projectPart()->id(); + if (highlightingProjectPartId == documentProjectPartId) { + processor->updateHighlighting(message.highlightingMarks(), + message.skippedPreprocessorRanges(), + message.file().documentRevision()); + } + } +} + void IpcReceiver::translationUnitDoesNotExist(const TranslationUnitDoesNotExistMessage &message) { QTC_CHECK(!"Got TranslationUnitDoesNotExistMessage"); @@ -203,6 +223,7 @@ public: void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) override; void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) override; + void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) override; private: ClangBackEnd::ConnectionClient &m_connection; @@ -268,6 +289,12 @@ void IpcSender::requestDiagnostics(const RequestDiagnosticsMessage &message) m_connection.serverProxy().requestDiagnostics(message); } +void IpcSender::requestHighlighting(const RequestHighlightingMessage &message) +{ + QTC_CHECK(m_connection.isConnected()); + m_connection.serverProxy().requestHighlighting(message); +} + IpcCommunicator::IpcCommunicator() : m_connection(&m_ipcReceiver) , m_ipcSender(new IpcSender(m_connection)) @@ -446,33 +473,50 @@ void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArra documentRevision}}); } -void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer) +void IpcCommunicator::requestDiagnosticsAndHighlighting(const FileContainer &fileContainer, + DocumentChangedCheck documentChangedCheck) { if (m_sendMode == IgnoreSendRequests) return; - if (documentHasChanged(fileContainer.filePath())) { - updateTranslationUnitsForEditor({fileContainer}); - - const RequestDiagnosticsMessage message(fileContainer); - qCDebug(log) << ">>>" << message; - m_ipcSender->requestDiagnostics(message); - - setLastSentDocumentRevision(fileContainer.filePath(), - fileContainer.documentRevision()); + if (documentChangedCheck == DocumentChangedCheck::RevisionCheck) { + if (documentHasChanged(fileContainer.filePath())) { + updateTranslationUnitsForEditor({fileContainer}); + requestDiagnostics(fileContainer); + requestHighlighting(fileContainer); + setLastSentDocumentRevision(fileContainer.filePath(), + fileContainer.documentRevision()); + } + } else { + requestDiagnostics(fileContainer); + requestHighlighting(fileContainer); } } -void IpcCommunicator::requestDiagnostics(Core::IDocument *document) +void IpcCommunicator::requestDiagnostics(const FileContainer &fileContainer) +{ + const RequestDiagnosticsMessage message(fileContainer); + qCDebug(log) << ">>>" << message; + m_ipcSender->requestDiagnostics(message); +} + +void IpcCommunicator::requestHighlighting(const FileContainer &fileContainer) +{ + const RequestHighlightingMessage message(fileContainer); + qCDebug(log) << ">>>" << message; + m_ipcSender->requestHighlighting(message); +} + +void IpcCommunicator::requestDiagnosticsAndHighlighting(Core::IDocument *document) { const auto textDocument = qobject_cast(document); const auto filePath = textDocument->filePath().toString(); const QString projectPartId = Utils::projectPartIdForFile(filePath); - requestDiagnostics(FileContainer(filePath, - projectPartId, - Utf8StringVector(), - textDocument->document()->revision())); + requestDiagnosticsAndHighlighting(FileContainer(filePath, + projectPartId, + Utf8StringVector(), + textDocument->document()->revision())); } void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position) diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h index 030976bfbe9..8d105cc968a 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h @@ -81,6 +81,7 @@ private: void echo(const ClangBackEnd::EchoMessage &message) override; void codeCompleted(const ClangBackEnd::CodeCompletedMessage &message) override; void diagnosticsChanged(const ClangBackEnd::DiagnosticsChangedMessage &message) override; + void highlightingChanged(const ClangBackEnd::HighlightingChangedMessage &message) override; void translationUnitDoesNotExist(const ClangBackEnd::TranslationUnitDoesNotExistMessage &message) override; void projectPartsDoNotExist(const ClangBackEnd::ProjectPartsDoNotExistMessage &message) override; @@ -105,6 +106,7 @@ public: virtual void unregisterUnsavedFilesForEditor(const ClangBackEnd::UnregisterUnsavedFilesForEditorMessage &message) = 0; virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0; virtual void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) = 0; + virtual void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) = 0; }; class IpcCommunicator : public QObject @@ -116,6 +118,8 @@ public: using FileContainers = QVector; using ProjectPartContainers = QVector; + enum class DocumentChangedCheck { NoCheck, RevisionCheck }; + public: IpcCommunicator(); @@ -140,8 +144,9 @@ public: void updateUnsavedFileFromCppEditorDocument(const QString &filePath); void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision); void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision); - void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer); - void requestDiagnostics(Core::IDocument *document); + void requestDiagnosticsAndHighlighting(const ClangBackEnd::FileContainer &fileContainer, + DocumentChangedCheck documentChangedCheck = DocumentChangedCheck::RevisionCheck); + void requestDiagnosticsAndHighlighting(Core::IDocument *document); void updateChangeContentStartPosition(const QString &filePath, int position); void registerFallbackProjectPart(); @@ -162,6 +167,9 @@ private: void registerCurrentCppEditorDocuments(); void registerCurrentCodeModelUiHeaders(); + void requestHighlighting(const ClangBackEnd::FileContainer &fileContainer); + void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer); + void onBackendRestarted(); void onEditorAboutToClose(Core::IEditor *editor); void onCoreAboutToClose(); diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index 3a73d66790d..b12de496f9f 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -41,6 +41,7 @@ SOURCES += \ cxprettyprinter.cpp \ diagnostic.cpp \ fastindexer.cpp \ + highlightingmarksreporter.cpp \ pchinfo.cpp \ pchmanager.cpp \ raii/scopedclangoptions.cpp \ @@ -86,6 +87,7 @@ HEADERS += \ cxraii.h \ diagnostic.h \ fastindexer.h \ + highlightingmarksreporter.h \ pchinfo.h \ pchmanager.h \ raii/scopedclangoptions.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index 26543eda86b..d0153d39793 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -81,6 +81,8 @@ QtcPlugin { files: [ "cppcreatemarkers.cpp", "cppcreatemarkers.h", + "highlightingmarksreporter.cpp", + "highlightingmarksreporter.h", ] } diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 80b098c9407..bbf917d45dc 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -58,11 +58,6 @@ static void initializeTextMarks() Utils::Theme::ClangCodeModel_Error_TextMarkColor); } -ClangCodeModelPlugin::ClangCodeModelPlugin() -{ - qRegisterMetaType(); -} - bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage) { Q_UNUSED(arguments) diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.h b/src/plugins/clangcodemodel/clangcodemodelplugin.h index 39d4ba6633c..6a767d5b710 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.h +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.h @@ -50,8 +50,6 @@ class ClangCodeModelPlugin: public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ClangCodeModel.json") public: - ClangCodeModelPlugin(); - bool initialize(const QStringList &arguments, QString *errorMessage); void extensionsInitialized(); diff --git a/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri b/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri index 35ba6f84c03..1771e0e0c65 100644 --- a/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri +++ b/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri @@ -5,11 +5,13 @@ SOURCES += $$PWD/completionchunkstotextconverter.cpp \ $$PWD/activationsequencecontextprocessor.cpp \ $$PWD/clangcompletioncontextanalyzer.cpp \ $$PWD/clangdiagnosticfilter.cpp \ - $$PWD/clangfixitoperation.cpp + $$PWD/clangfixitoperation.cpp \ + $$PWD/highlightingmarksreporter.cpp HEADERS += $$PWD/completionchunkstotextconverter.h \ $$PWD/activationsequenceprocessor.h \ $$PWD/activationsequencecontextprocessor.h \ $$PWD/clangcompletioncontextanalyzer.h \ $$PWD/clangdiagnosticfilter.h \ - $$PWD/clangfixitoperation.h + $$PWD/clangfixitoperation.h \ + $$PWD/highlightingmarksreporter.h diff --git a/src/plugins/clangcodemodel/clangeditordocumentparser.cpp b/src/plugins/clangcodemodel/clangeditordocumentparser.cpp index caeefd2267d..4b2daaa7374 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentparser.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentparser.cpp @@ -29,111 +29,22 @@ ****************************************************************************/ #include "clangeditordocumentparser.h" -#include "clangutils.h" -#include "pchinfo.h" -#include "pchmanager.h" - -#include -#include -#include - -#include -#include - -#include - -static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.clangeditordocumentparser") - -namespace { - -QStringList createOptions(const QString &filePath, - const CppTools::ProjectPart::Ptr &part, - bool includeSpellCheck = false) -{ - using namespace ClangCodeModel; - - QStringList options; - if (part.isNull()) - return options; - - if (includeSpellCheck) - options += QLatin1String("-fspell-checking"); - - options += ClangCodeModel::Utils::createClangOptions(part, filePath); - - if (Internal::PchInfo::Ptr pchInfo = Internal::PchManager::instance()->pchInfo(part)) - options.append(ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName())); - - return options; -} - -QString messageLine(const QStringList &options, const QString &fileName) -{ - const QStringList allOptions = QStringList(options) - << QLatin1String("-fsyntax-only") << fileName; - QStringList allOptionsQuoted; - foreach (const QString &option, allOptions) - allOptionsQuoted.append(QLatin1Char('\'') + option + QLatin1Char('\'')); - return ::Utils::HostOsInfo::withExecutableSuffix(QLatin1String("clang")) - + QLatin1Char(' ') + allOptionsQuoted.join(QLatin1Char(' ')); -} - -} // anonymous namespace namespace ClangCodeModel { ClangEditorDocumentParser::ClangEditorDocumentParser(const QString &filePath) : BaseEditorDocumentParser(filePath) - , m_marker(new ClangCodeModel::SemanticMarker) { BaseEditorDocumentParser::Configuration config = configuration(); config.stickToPreviousProjectPart = false; setConfiguration(config); } -void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info) +void ClangEditorDocumentParser::updateHelper(const BaseEditorDocumentParser::InMemoryInfo &) { - QTC_ASSERT(m_marker, return); - - // Determine project part State state_ = state(); state_.projectPart = determineProjectPart(filePath(), configuration(), state_); setState(state_); - emit projectPartDetermined(state_.projectPart); - - // Determine message line arguments - const QStringList options = createOptions(filePath(), state_.projectPart, true); - qCDebug(log, "Reparse options (cmd line equivalent): %s", - messageLine(options, filePath()).toUtf8().constData()); - - // Run - QTime t; t.start(); - QMutexLocker lock(m_marker->mutex()); - m_marker->setFileName(filePath()); - m_marker->setCompilationOptions(options); - const Internal::UnsavedFiles unsavedFiles = Utils::createUnsavedFiles(info.workingCopy, - info.modifiedFiles); - m_marker->reparse(unsavedFiles); - qCDebug(log) << "Reparse took" << t.elapsed() << "ms."; -} - -QList ClangEditorDocumentParser::diagnostics() const -{ - QTC_ASSERT(m_marker, return QList()); - QMutexLocker(m_marker->mutex()); - return m_marker->diagnostics(); -} - -QList ClangEditorDocumentParser::ifdefedOutBlocks() const -{ - QTC_ASSERT(m_marker, return QList()); - QMutexLocker(m_marker->mutex()); - return m_marker->ifdefedOutBlocks(); -} - -SemanticMarker::Ptr ClangEditorDocumentParser::semanticMarker() const -{ - return m_marker; } } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangeditordocumentparser.h b/src/plugins/clangcodemodel/clangeditordocumentparser.h index ef207749c27..7dc54732f32 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentparser.h +++ b/src/plugins/clangcodemodel/clangeditordocumentparser.h @@ -31,12 +31,8 @@ #ifndef CLANGEDITORDOCUMENTPARSER_H #define CLANGEDITORDOCUMENTPARSER_H -#include "semanticmarker.h" - #include -namespace CppTools { class WorkingCopy; } - namespace ClangCodeModel { class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser @@ -46,17 +42,8 @@ class ClangEditorDocumentParser : public CppTools::BaseEditorDocumentParser public: ClangEditorDocumentParser(const QString &filePath); - QList diagnostics() const; - QList ifdefedOutBlocks() const; - SemanticMarker::Ptr semanticMarker() const; - -signals: - void projectPartDetermined(CppTools::ProjectPart::Ptr projectPart); - private: - void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &info) override; - - SemanticMarker::Ptr m_marker; + void updateHelper(const BaseEditorDocumentParser::InMemoryInfo &) override; }; } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 5739960751c..e4f4b7e5bc2 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -36,6 +36,7 @@ #include "clangutils.h" #include "cppcreatemarkers.h" #include "diagnostic.h" +#include "highlightingmarksreporter.h" #include "pchinfo.h" #include @@ -59,22 +60,6 @@ #include -namespace { - -typedef CPlusPlus::Document::DiagnosticMessage CppToolsDiagnostic; - -QList toTextEditorBlocks( - const QList &ranges) -{ - QList result; - result.reserve(ranges.size()); - foreach (const ClangCodeModel::SemanticMarker::Range &range, ranges) - result.append(TextEditor::BlockRange(range.first, range.last)); - return result; -} - -} // anonymous namespace - namespace ClangCodeModel { namespace Internal { @@ -89,26 +74,12 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor( , m_semanticHighlighter(document) , m_builtinProcessor(document, /*enableSemanticHighlighter=*/ false) { - connect(m_parser.data(), &ClangEditorDocumentParser::projectPartDetermined, - this, &ClangEditorDocumentProcessor::onParserDeterminedProjectPart); - // Forwarding the semantic info from the builtin processor enables us to provide all // editor (widget) related features that are not yet implemented by the clang plugin. connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::cppDocumentUpdated, this, &ClangEditorDocumentProcessor::cppDocumentUpdated); connect(&m_builtinProcessor, &CppTools::BuiltinEditorDocumentProcessor::semanticInfoUpdated, this, &ClangEditorDocumentProcessor::semanticInfoUpdated); - - m_semanticHighlighter.setHighlightingRunner( - [this]() -> QFuture { - const int firstLine = 1; - const int lastLine = baseTextDocument()->document()->blockCount(); - - CreateMarkers *createMarkers = CreateMarkers::create(m_parser->semanticMarker(), - baseTextDocument()->filePath().toString(), - firstLine, lastLine); - return createMarkers->start(); - }); } ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor() @@ -125,7 +96,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor() void ClangEditorDocumentProcessor::run() { - requestDiagnostics(); + requestDiagnosticsAndHighlighting(); // Run clang parser disconnect(&m_parserWatcher, &QFutureWatcher::finished, @@ -153,7 +124,7 @@ void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force) void ClangEditorDocumentProcessor::semanticRehighlight() { m_semanticHighlighter.updateFormatMapFromFontSettings(); - m_semanticHighlighter.run(); + requestDiagnosticsAndHighlighting(DocumentChangedCheck::NoCheck); } CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo() @@ -201,6 +172,36 @@ void ClangEditorDocumentProcessor::updateCodeWarnings(const QVector +toTextEditorBlocks(const QVector &ifdefedOutRanges) +{ + QList blockRanges; + blockRanges.reserve(ifdefedOutRanges.size()); + + for (const auto &range : ifdefedOutRanges) + blockRanges.append(TextEditor::BlockRange(range.start().offset(),range.end().offset())); + + return blockRanges; +} + +void ClangEditorDocumentProcessor::updateHighlighting( + const QVector &highlightingMarks, + const QVector &skippedPreprocessorRanges, + uint documentRevision) +{ + if (documentRevision == revision()) { + const auto skippedPreprocessorBlocks = toTextEditorBlocks(skippedPreprocessorRanges); + emit ifdefedOutBlocksUpdated(documentRevision, skippedPreprocessorBlocks); + + m_semanticHighlighter.setHighlightingRunner( + [highlightingMarks]() { + auto *reporter = new HighlightingMarksReporter(highlightingMarks); + return reporter->start(); + }); + m_semanticHighlighter.run(); + } +} + static int currentLine(const TextEditor::AssistInterface &assistInterface) { int line, column; @@ -240,36 +241,24 @@ static bool isProjectPartLoadedOrIsFallback(CppTools::ProjectPart::Ptr projectPa && (projectPart->id().isEmpty() || ClangCodeModel::Utils::isProjectPartLoaded(projectPart)); } -void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor( - CppTools::ProjectPart::Ptr projectPart) +void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor() { - QTC_ASSERT(projectPart, return); + const CppTools::ProjectPart::Ptr projectPart = m_parser->projectPart(); if (isProjectPartLoadedOrIsFallback(projectPart)) { updateTranslationUnitForEditor(projectPart.data()); - requestDiagnostics(projectPart.data()); + requestDiagnosticsAndHighlighting(projectPart.data()); m_projectPart = projectPart; } } -void ClangEditorDocumentProcessor::onParserDeterminedProjectPart( - CppTools::ProjectPart::Ptr projectPart) -{ - updateProjectPartAndTranslationUnitForEditor(projectPart); -} - void ClangEditorDocumentProcessor::onParserFinished() { if (revision() != m_parserRevision) return; - // Emit ifdefed out blocks - const auto ifdefoutBlocks = toTextEditorBlocks(m_parser->ifdefedOutBlocks()); - emit ifdefedOutBlocksUpdated(revision(), ifdefoutBlocks); - - // Run semantic highlighter - m_semanticHighlighter.run(); + updateProjectPartAndTranslationUnitForEditor(); } void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart) @@ -287,25 +276,38 @@ void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::Proj } } -void ClangEditorDocumentProcessor::requestDiagnostics(CppTools::ProjectPart *projectPart) +void ClangEditorDocumentProcessor::requestDiagnosticsAndHighlighting(CppTools::ProjectPart *projectPart) { if (!m_projectPart || projectPart->id() != m_projectPart->id()) { IpcCommunicator &ipcCommunicator = m_modelManagerSupport->ipcCommunicator(); - ipcCommunicator.requestDiagnostics({fileContainer(projectPart)}); + const ClangBackEnd::FileContainer fileContainer_ = fileContainer(projectPart); + ipcCommunicator.requestDiagnosticsAndHighlighting(fileContainer_); } } -void ClangEditorDocumentProcessor::requestDiagnostics() +IpcCommunicator::DocumentChangedCheck +toIpcCommunicatorDocumentChangedCheck(ClangEditorDocumentProcessor::DocumentChangedCheck condition) +{ + return condition == ClangEditorDocumentProcessor::DocumentChangedCheck::RevisionCheck + ? IpcCommunicator::DocumentChangedCheck::RevisionCheck + : IpcCommunicator::DocumentChangedCheck::NoCheck; +} + +void ClangEditorDocumentProcessor::requestDiagnosticsAndHighlighting(DocumentChangedCheck documentChangedCheck) { - // Get diagnostics if (m_projectPart) { auto &ipcCommunicator = m_modelManagerSupport->ipcCommunicator(); - ipcCommunicator.requestDiagnostics({filePath(), - m_projectPart->id(), - baseTextDocument()->plainText(), - true, - revision()}); + + const ClangBackEnd::FileContainer fileContainer(filePath(), + m_projectPart->id(), + baseTextDocument()->plainText(), + true, + revision()); + + const auto documentCheck = toIpcCommunicatorDocumentChangedCheck(documentChangedCheck); + + ipcCommunicator.requestDiagnosticsAndHighlighting(fileContainer, documentCheck); } } diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index ded0258210f..cc696cc8e9a 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -43,6 +43,7 @@ namespace ClangBackEnd { class DiagnosticContainer; +class HighlightingMarkContainer; class FileContainer; } @@ -75,6 +76,9 @@ public: void updateCodeWarnings(const QVector &diagnostics, uint documentRevision); + void updateHighlighting(const QVector &highlightingMarks, + const QVector &skippedPreprocessorRanges, + uint documentRevision); TextEditor::QuickFixOperations extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override; @@ -84,17 +88,17 @@ public: void clearDiagnosticsWithFixIts(); public: + enum class DocumentChangedCheck { NoCheck, RevisionCheck }; static ClangEditorDocumentProcessor *get(const QString &filePath); private slots: - void onParserDeterminedProjectPart(CppTools::ProjectPart::Ptr projectPart); void onParserFinished(); private: - void updateProjectPartAndTranslationUnitForEditor(CppTools::ProjectPart::Ptr projectPart); + void updateProjectPartAndTranslationUnitForEditor(); void updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart); - void requestDiagnostics(CppTools::ProjectPart *projectPart); - void requestDiagnostics(); + void requestDiagnosticsAndHighlighting(CppTools::ProjectPart *projectPart); + void requestDiagnosticsAndHighlighting(DocumentChangedCheck documentChangedCheck = DocumentChangedCheck::RevisionCheck); ClangBackEnd::FileContainer fileContainer(CppTools::ProjectPart *projectPart) const; private: diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 26780648305..1b66c067e94 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -193,7 +193,7 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool if (success) { TextEditor::TextDocument *textDocument = qobject_cast(sender()); connectToTextDocumentContentsChangedForTranslationUnit(textDocument); - m_ipcCommunicator.requestDiagnostics(textDocument); + m_ipcCommunicator.requestDiagnosticsAndHighlighting(textDocument); } } diff --git a/src/plugins/clangcodemodel/highlightingmarksreporter.cpp b/src/plugins/clangcodemodel/highlightingmarksreporter.cpp new file mode 100644 index 00000000000..6b3fc07996d --- /dev/null +++ b/src/plugins/clangcodemodel/highlightingmarksreporter.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "highlightingmarksreporter.h" + +#include + +#include + +namespace { + +CppTools::SemanticHighlighter::Kind toCppToolsSemanticHighlighterKind( + ClangBackEnd::HighlightingType type) +{ + using ClangBackEnd::HighlightingType; + using CppTools::SemanticHighlighter; + + switch (type) { + case HighlightingType::Keyword: + return SemanticHighlighter::PseudoKeywordUse; + case HighlightingType::Function: + return SemanticHighlighter::FunctionUse; + case HighlightingType::VirtualFunction: + return SemanticHighlighter::VirtualMethodUse; + case HighlightingType::Type: + return SemanticHighlighter::TypeUse; + case HighlightingType::LocalVariable: + return SemanticHighlighter::LocalUse; + case HighlightingType::Field: + return SemanticHighlighter::FieldUse; + case HighlightingType::GlobalVariable: + return SemanticHighlighter::Unknown; + case HighlightingType::Enumeration: + return SemanticHighlighter::EnumerationUse; + case HighlightingType::Label: + return SemanticHighlighter::LabelUse; + case HighlightingType::Preprocessor: + return SemanticHighlighter::MacroUse; + default: + return SemanticHighlighter::Unknown; + } + + Q_UNREACHABLE(); +} + +TextEditor::HighlightingResult toHighlightingResult( + const ClangBackEnd::HighlightingMarkContainer &highlightingMark) +{ + const auto highlighterKind = toCppToolsSemanticHighlighterKind(highlightingMark.type()); + + return TextEditor::HighlightingResult(highlightingMark.line(), + highlightingMark.column(), + highlightingMark.length(), + highlighterKind); +} + +} // anonymous + +namespace ClangCodeModel { + +HighlightingMarksReporter::HighlightingMarksReporter( + const QVector &highlightingMarks) + : m_highlightingMarks(highlightingMarks) +{ + m_chunksToReport.reserve(m_chunkSize + 1); +} + +void HighlightingMarksReporter::reportChunkWise( + const TextEditor::HighlightingResult &highlightingResult) +{ + if (m_chunksToReport.size() >= m_chunkSize) { + if (m_flushRequested && highlightingResult.line != m_flushLine) { + reportAndClearCurrentChunks(); + } else if (!m_flushRequested) { + m_flushRequested = true; + m_flushLine = highlightingResult.line; + } + } + + m_chunksToReport.append(highlightingResult); +} + +void HighlightingMarksReporter::reportAndClearCurrentChunks() +{ + m_flushRequested = false; + m_flushLine = 0; + + if (!m_chunksToReport.isEmpty()) { + reportResults(m_chunksToReport); + m_chunksToReport.erase(m_chunksToReport.begin(), m_chunksToReport.end()); + } +} + +void HighlightingMarksReporter::setChunkSize(int chunkSize) +{ + m_chunkSize = chunkSize; +} + +void HighlightingMarksReporter::run() +{ + run_internal(); + reportFinished(); +} + +void HighlightingMarksReporter::run_internal() +{ + if (isCanceled()) + return; + + for (const auto &highlightingMark : m_highlightingMarks) + reportChunkWise(toHighlightingResult(highlightingMark)); + + if (isCanceled()) + return; + + reportAndClearCurrentChunks(); +} + +QFuture HighlightingMarksReporter::start() +{ + this->setRunnable(this); + this->reportStarted(); + QFuture future = this->future(); + QThreadPool::globalInstance()->start(this, QThread::LowestPriority); + return future; +} + +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/highlightingmarksreporter.h b/src/plugins/clangcodemodel/highlightingmarksreporter.h new file mode 100644 index 00000000000..5726ce0b58b --- /dev/null +++ b/src/plugins/clangcodemodel/highlightingmarksreporter.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H +#define CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H + +#include "clang_global.h" + +#include +#include +#include +#include + +#include + +#include + +namespace ClangCodeModel { + +class HighlightingMarksReporter: + public QObject, + public QRunnable, + public QFutureInterface +{ + Q_OBJECT + +public: + HighlightingMarksReporter(const QVector &highlightingMarks); + + void setChunkSize(int chunkSize); + + QFuture start(); + +private: + void run() override; + void run_internal(); + + void reportChunkWise(const TextEditor::HighlightingResult &highlightingResult); + void reportAndClearCurrentChunks(); + +private: + QVector m_highlightingMarks; + QVector m_chunksToReport; + + int m_chunkSize = 100; + + bool m_flushRequested = false; + unsigned m_flushLine = 0; +}; + +} // namespace ClangCodeModel + +#endif // CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 857bf3b4077..01d5cdbbef7 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -380,6 +380,11 @@ QString toString(const RequestDiagnosticsMessage &) return QStringLiteral("RequestDiagnosticsMessage\n"); } +QString toString(const RequestHighlightingMessage &) +{ + return QStringLiteral("RequestHighlightingMessage\n"); +} + class IpcSenderSpy : public IpcSenderInterface { public: @@ -413,6 +418,8 @@ public: void requestDiagnostics(const RequestDiagnosticsMessage &message) override { senderLog.append(toString(message)); } + void requestHighlighting(const RequestHighlightingMessage &message) override + { senderLog.append(toString(message)); } public: QString senderLog; diff --git a/src/plugins/cpptools/cppprojects.h b/src/plugins/cpptools/cppprojects.h index a63f5575875..3d8ddba0bec 100644 --- a/src/plugins/cpptools/cppprojects.h +++ b/src/plugins/cpptools/cppprojects.h @@ -247,6 +247,4 @@ private: } // namespace CppTools -Q_DECLARE_METATYPE(CppTools::ProjectPart::Ptr) - #endif // CPPPROJECTPART_H diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index 31c3ae481f3..a7652caf28d 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -33,7 +33,9 @@ #include "clangfilesystemwatcher.h" #include "codecompleter.h" #include "diagnosticset.h" +#include "highlightinginformations.h" #include "projectpartsdonotexistexception.h" +#include "skippedsourceranges.h" #include "translationunitdoesnotexistexception.h" #include "translationunitfilenotexitexception.h" #include "translationunitisnullexception.h" @@ -48,8 +50,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -62,37 +66,44 @@ namespace ClangBackEnd { namespace { -const int sendDiagnosticsTimerInterval = 300; +const int delayedEditorUpdatesTimerInterval = 300; } ClangIpcServer::ClangIpcServer() : translationUnits(projects, unsavedFiles) { - translationUnits.setSendChangeDiagnosticsCallback([this] (const DiagnosticsChangedMessage &message) - { - client()->diagnosticsChanged(message); - }); + const auto sendEditorUpdates + = [this] (const DiagnosticsChangedMessage &diagnosticsMessage, + const HighlightingChangedMessage &highlightingsMessage) { + client()->diagnosticsChanged(diagnosticsMessage); + client()->highlightingChanged(highlightingsMessage); + }; - QObject::connect(&sendDiagnosticsTimer, + const auto sendDelayedEditorUpdates = [this] () { + try { + auto editorUpdatesSendState = translationUnits.sendDelayedEditorUpdates(); + if (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) + sendDelayedEditorUpdatesTimer.setInterval(0); + else + sendDelayedEditorUpdatesTimer.stop(); + } catch (const std::exception &exception) { + qWarning() << "Error in ClangIpcServer::sendDelayedEditorUpdatesTimer:" << exception.what(); + } + }; + + const auto onFileChanged = [this] (const Utf8String &filePath) { + startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(filePath); + }; + + translationUnits.setSendDelayedEditorUpdatesCallback(sendEditorUpdates); + + QObject::connect(&sendDelayedEditorUpdatesTimer, &QTimer::timeout, - [this] () { - try { - auto diagnostSendState = translationUnits.sendChangedDiagnostics(); - if (diagnostSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics) - sendDiagnosticsTimer.setInterval(0); - else - sendDiagnosticsTimer.stop(); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangIpcServer::sendDiagnosticsTimer:" << exception.what(); - } - }); + sendDelayedEditorUpdates); QObject::connect(translationUnits.clangFileSystemWatcher(), &ClangFileSystemWatcher::fileChanged, - [this] (const Utf8String &filePath) - { - startSendDiagnosticTimerIfFileIsNotATranslationUnit(filePath); - }); + onFileChanged); } void ClangIpcServer::end() @@ -107,7 +118,7 @@ void ClangIpcServer::registerTranslationUnitsForEditor(const ClangBackEnd::Regis try { translationUnits.create(message.fileContainers()); unsavedFiles.createOrUpdate(message.fileContainers()); - sendDiagnosticsTimer.start(0); + sendDelayedEditorUpdatesTimer.start(0); } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); } catch (const std::exception &exception) { @@ -124,7 +135,7 @@ void ClangIpcServer::updateTranslationUnitsForEditor(const UpdateTranslationUnit if (newerFileContainers.size() > 0) { translationUnits.update(newerFileContainers); unsavedFiles.createOrUpdate(newerFileContainers); - sendDiagnosticsTimer.start(sendDiagnosticsTimerInterval); + sendDelayedEditorUpdatesTimer.start(delayedEditorUpdatesTimerInterval); } } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); @@ -182,7 +193,7 @@ void ClangIpcServer::registerUnsavedFilesForEditor(const RegisterUnsavedFilesFor try { unsavedFiles.createOrUpdate(message.fileContainers()); translationUnits.updateTranslationUnitsWithChangedDependencies(message.fileContainers()); - sendDiagnosticsTimer.start(sendDiagnosticsTimerInterval); + sendDelayedEditorUpdatesTimer.start(delayedEditorUpdatesTimerInterval); } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); } catch (const std::exception &exception) { @@ -244,6 +255,26 @@ void ClangIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message } } +void ClangIpcServer::requestHighlighting(const RequestHighlightingMessage &message) +{ + TIME_SCOPE_DURATION("ClangIpcServer::requestHighlighting"); + + try { + auto translationUnit = translationUnits.translationUnit(message.fileContainer().filePath(), + message.fileContainer().projectPartId()); + + client()->highlightingChanged(HighlightingChangedMessage(translationUnit.fileContainer(), + translationUnit.highlightingInformations().toHighlightingMarksContainers(), + translationUnit.skippedSourceRanges().toSourceRangeContainers())); + } catch (const TranslationUnitDoesNotExistException &exception) { + client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistMessage(exception.fileContainer())); + } catch (const ProjectPartDoNotExistException &exception) { + client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); + } catch (const std::exception &exception) { + qWarning() << "Error in ClangIpcServer::requestHighlighting:" << exception.what(); + } +} + void ClangIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) { TIME_SCOPE_DURATION("ClangIpcServer::updateVisibleTranslationUnits"); @@ -261,10 +292,10 @@ const TranslationUnits &ClangIpcServer::translationUnitsForTestOnly() const return translationUnits; } -void ClangIpcServer::startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath) +void ClangIpcServer::startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(const Utf8String &filePath) { if (!translationUnits.hasTranslationUnit(filePath)) - sendDiagnosticsTimer.start(0); + sendDelayedEditorUpdatesTimer.start(0); } } diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.h b/src/tools/clangbackend/ipcsource/clangipcserver.h index 88daf5b4104..5ca9553c85b 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.h +++ b/src/tools/clangbackend/ipcsource/clangipcserver.h @@ -61,18 +61,19 @@ public: void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override; void completeCode(const CompleteCodeMessage &message) override; void requestDiagnostics(const RequestDiagnosticsMessage &message) override; + void requestHighlighting(const RequestHighlightingMessage &message) override; void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override; const TranslationUnits &translationUnitsForTestOnly() const; private: - void startSendDiagnosticTimerIfFileIsNotATranslationUnit(const Utf8String &filePath); + void startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(const Utf8String &filePath); private: ProjectParts projects; UnsavedFiles unsavedFiles; TranslationUnits translationUnits; - QTimer sendDiagnosticsTimer; + QTimer sendDelayedEditorUpdatesTimer; }; } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp index ed9799652a4..a7dd59f27e0 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp +++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp @@ -85,6 +85,7 @@ public: uint documentRevision = 0; bool needsToBeReparsed = false; bool hasNewDiagnostics = true; + bool hasNewHighlightingInformations = true; bool isUsedByCurrentEditor = false; bool isVisibleInEditor = false; }; @@ -239,6 +240,11 @@ bool TranslationUnit::hasNewDiagnostics() const return d->hasNewDiagnostics; } +bool TranslationUnit::hasNewHighlightingInformations() const +{ + return d->hasNewHighlightingInformations; +} + DiagnosticSet TranslationUnit::diagnostics() const { d->hasNewDiagnostics = false; @@ -268,6 +274,7 @@ void TranslationUnit::setDirtyIfDependencyIsMet(const Utf8String &filePath) if (d->dependedFilePaths.contains(filePath) && isMainFileAndExistsOrIsOtherFile(filePath)) { d->needsToBeReparsed = true; d->hasNewDiagnostics = true; + d->hasNewHighlightingInformations = true; } } @@ -302,6 +309,13 @@ Cursor TranslationUnit::cursor() const return clang_getTranslationUnitCursor(cxTranslationUnit()); } +HighlightingInformations TranslationUnit::highlightingInformations() const +{ + d->hasNewHighlightingInformations = false; + + return highlightingInformationsInRange(cursor().sourceRange()); +} + HighlightingInformations TranslationUnit::highlightingInformationsInRange(const SourceRange &range) const { CXToken *cxTokens = 0; diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.h b/src/tools/clangbackend/ipcsource/clangtranslationunit.h index 37c47413611..2e325ceaf62 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunit.h +++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.h @@ -112,6 +112,7 @@ public: bool isNeedingReparse() const; bool hasNewDiagnostics() const; + bool hasNewHighlightingInformations() const; DiagnosticSet diagnostics() const; QVector mainFileDiagnostics() const; @@ -131,6 +132,7 @@ public: Cursor cursorAt(const Utf8String &filePath, uint line, uint column) const; Cursor cursor() const; + HighlightingInformations highlightingInformations() const; HighlightingInformations highlightingInformationsInRange(const SourceRange &range) const; SkippedSourceRanges skippedSourceRanges() const; diff --git a/src/tools/clangbackend/ipcsource/highlightinginformation.cpp b/src/tools/clangbackend/ipcsource/highlightinginformation.cpp index d91ddf26b9d..a570f3cf5cf 100644 --- a/src/tools/clangbackend/ipcsource/highlightinginformation.cpp +++ b/src/tools/clangbackend/ipcsource/highlightinginformation.cpp @@ -28,6 +28,8 @@ ** ****************************************************************************/ +#include + #include "clangstring.h" #include "cursor.h" #include "highlightinginformation.h" @@ -81,6 +83,11 @@ QVector HighlightingInformation::outputFunctionArgument return outputFunctionArguments; } +HighlightingInformation::operator HighlightingMarkContainer() const +{ + return HighlightingMarkContainer(line, column, length, type); +} + namespace { bool isFinalFunction(const Cursor &cursor) @@ -278,7 +285,7 @@ HighlightingType HighlightingInformation::kind(CXToken *cxToken, const Cursor &c Q_UNREACHABLE(); } -void PrintTo(const HighlightingInformation& information, ::std::ostream *os) +void PrintTo(const HighlightingInformation &information, ::std::ostream *os) { *os << "type: "; PrintTo(information.type, os); @@ -287,30 +294,4 @@ void PrintTo(const HighlightingInformation& information, ::std::ostream *os) << " length: " << information.length; } -void PrintTo(HighlightingType highlightingType, std::ostream *os) -{ - switch (highlightingType) { - case HighlightingType::Invalid: *os << "Invalid"; break; - case HighlightingType::Comment: *os << "Comment"; break; - case HighlightingType::Keyword: *os << "Keyword"; break; - case HighlightingType::StringLiteral: *os << "StringLiteral"; break; - case HighlightingType::NumberLiteral: *os << "NumberLiteral"; break; - case HighlightingType::Function: *os << "Function"; break; - case HighlightingType::VirtualFunction: *os << "VirtualFunction"; break; - case HighlightingType::Type: *os << "Type"; break; - case HighlightingType::LocalVariable: *os << "LocalVariable"; break; - case HighlightingType::GlobalVariable: *os << "GlobalVariable"; break; - case HighlightingType::Field: *os << "Field"; break; - case HighlightingType::Enumeration: *os << "Enumeration"; break; - case HighlightingType::Operator: *os << "Operator"; break; - case HighlightingType::Preprocessor: *os << "Preprocessor"; break; - case HighlightingType::Label: *os << "Label"; break; - case HighlightingType::OutputArgument: *os << "OutputArgument"; break; - case HighlightingType::PreprocessorDefinition: *os << "PreprocessorDefinition"; break; - case HighlightingType::PreprocessorExpansion: *os << "PreprocessorExpansion"; break; - } -} - - - } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/ipcsource/highlightinginformation.h b/src/tools/clangbackend/ipcsource/highlightinginformation.h index ee327b62135..418efdda8fc 100644 --- a/src/tools/clangbackend/ipcsource/highlightinginformation.h +++ b/src/tools/clangbackend/ipcsource/highlightinginformation.h @@ -32,6 +32,7 @@ #define CLANGBACKEND_HIGHLIGHTINGINFORMATION_H #include +#include #include "cursor.h" @@ -52,6 +53,8 @@ public: bool hasFunctionArguments() const; QVector outputFunctionArguments() const; + operator HighlightingMarkContainer() const; + private: HighlightingType identifierKind(const Cursor &cursor) const; HighlightingType referencedTypeKind(const Cursor &cursor) const; @@ -71,7 +74,6 @@ private: }; void PrintTo(const HighlightingInformation& highlightingInformation, ::std::ostream *os); -void PrintTo(HighlightingType highlightingType, ::std::ostream *os); inline bool operator==(const HighlightingInformation &first, const HighlightingInformation &second) { diff --git a/src/tools/clangbackend/ipcsource/highlightinginformations.cpp b/src/tools/clangbackend/ipcsource/highlightinginformations.cpp index f7157768fd6..c90ea4a5903 100644 --- a/src/tools/clangbackend/ipcsource/highlightinginformations.cpp +++ b/src/tools/clangbackend/ipcsource/highlightinginformations.cpp @@ -30,6 +30,10 @@ #include "highlightinginformations.h" +#include "highlightingmarkcontainer.h" + +#include + namespace ClangBackEnd { HighlightingInformations::HighlightingInformations(CXTranslationUnit cxTranslationUnit, CXToken *tokens, uint tokensCount) @@ -56,6 +60,20 @@ HighlightingInformations::const_iterator HighlightingInformations::end() const return const_iterator(cxCursor.cend(), cxToken + cxTokenCount, cxTranslationUnit); } +QVector HighlightingInformations::toHighlightingMarksContainers() const +{ + QVector containers; + containers.reserve(size()); + + const auto isValidHighlightMark = [] (const HighlightingInformation &highlightMark) { + return !highlightMark.hasType(HighlightingType::Invalid); + }; + + std::copy_if(begin(), end(), std::back_inserter(containers), isValidHighlightMark); + + return containers; +} + bool HighlightingInformations::isEmpty() const { return cxTokenCount == 0; diff --git a/src/tools/clangbackend/ipcsource/highlightinginformations.h b/src/tools/clangbackend/ipcsource/highlightinginformations.h index 2c7b8ce9bbf..7b3365780e5 100644 --- a/src/tools/clangbackend/ipcsource/highlightinginformations.h +++ b/src/tools/clangbackend/ipcsource/highlightinginformations.h @@ -40,6 +40,7 @@ namespace ClangBackEnd { using uint = unsigned int; +class HighlightingMarkContainer; class HighlightingInformations { @@ -61,6 +62,8 @@ public: const_iterator begin() const; const_iterator end() const; + QVector toHighlightingMarksContainers() const; + private: CXTranslationUnit cxTranslationUnit = nullptr; CXToken *const cxToken = nullptr; diff --git a/src/tools/clangbackend/ipcsource/translationunits.cpp b/src/tools/clangbackend/ipcsource/translationunits.cpp index 07975bf693d..c1daa3bf501 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.cpp +++ b/src/tools/clangbackend/ipcsource/translationunits.cpp @@ -32,8 +32,11 @@ #include #include +#include +#include #include #include +#include #include #include @@ -163,62 +166,73 @@ void TranslationUnits::updateTranslationUnitsWithChangedDependencies(const QVect updateTranslationUnitsWithChangedDependency(fileContainer.filePath()); } -DiagnosticSendState TranslationUnits::sendChangedDiagnostics() +EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdates() { - auto diagnosticSendState = sendChangedDiagnosticsForCurrentEditor(); - if (diagnosticSendState == DiagnosticSendState::NoDiagnosticSend) - diagnosticSendState = sendChangedDiagnosticsForVisibleEditors(); - if (diagnosticSendState == DiagnosticSendState::NoDiagnosticSend) - diagnosticSendState = sendChangedDiagnosticsForAll(); + auto editorUpdatesSendState = sendDelayedEditorUpdatesForCurrentEditor(); + if (editorUpdatesSendState == EditorUpdatesSendState::NoEditorUpdatesSend) + editorUpdatesSendState = sendDelayedEditorUpdatesForVisibleEditors(); + if (editorUpdatesSendState == EditorUpdatesSendState::NoEditorUpdatesSend) + editorUpdatesSendState = sendDelayedEditorUpdatesForAll(); - return diagnosticSendState; + return editorUpdatesSendState; } template -DiagnosticSendState TranslationUnits::sendChangedDiagnostics(Predicate predicate) +EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdates(Predicate predicate) { auto foundTranslationUnit = std::find_if(translationUnits_.begin(), translationUnits_.end(), predicate); if (foundTranslationUnit != translationUnits().end()) { - sendDiagnosticChangedMessage(*foundTranslationUnit); - return DiagnosticSendState::MaybeThereAreMoreDiagnostics; + sendDelayedEditorUpdates(*foundTranslationUnit); + return EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; } - return DiagnosticSendState::NoDiagnosticSend; + return EditorUpdatesSendState::NoEditorUpdatesSend; } -DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForCurrentEditor() +namespace { + +bool translationUnitHasEditorDocumentUpdates(const TranslationUnit &translationUnit) { - auto hasDiagnosticsForCurrentEditor = [] (const TranslationUnit &translationUnit) { - return translationUnit.isUsedByCurrentEditor() && translationUnit.hasNewDiagnostics(); + return translationUnit.hasNewDiagnostics() || translationUnit.hasNewHighlightingInformations(); +} + +} + +EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForCurrentEditor() +{ + auto hasEditorUpdatesForCurrentEditor = [] (const TranslationUnit &translationUnit) { + return translationUnit.isUsedByCurrentEditor() + && translationUnitHasEditorDocumentUpdates(translationUnit); }; - return sendChangedDiagnostics(hasDiagnosticsForCurrentEditor); + return sendDelayedEditorUpdates(hasEditorUpdatesForCurrentEditor); } -DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForVisibleEditors() +EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForVisibleEditors() { - auto hasDiagnosticsForVisibleEditor = [] (const TranslationUnit &translationUnit) { - return translationUnit.isVisibleInEditor() && translationUnit.hasNewDiagnostics(); + auto hasEditorUpdatesForVisibleEditor = [] (const TranslationUnit &translationUnit) { + return translationUnit.isVisibleInEditor() + && translationUnitHasEditorDocumentUpdates(translationUnit); }; - return sendChangedDiagnostics(hasDiagnosticsForVisibleEditor); + return sendDelayedEditorUpdates(hasEditorUpdatesForVisibleEditor); } -DiagnosticSendState TranslationUnits::sendChangedDiagnosticsForAll() +EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForAll() { - auto hasDiagnostics = [] (const TranslationUnit &translationUnit) { - return translationUnit.hasNewDiagnostics(); + auto hasEditorUpdates = [] (const TranslationUnit &translationUnit) { + return translationUnitHasEditorDocumentUpdates(translationUnit); }; - return sendChangedDiagnostics(hasDiagnostics); + return sendDelayedEditorUpdates(hasEditorUpdates); } -void TranslationUnits::setSendChangeDiagnosticsCallback(std::function &&callback) +void TranslationUnits::setSendDelayedEditorUpdatesCallback(DelayedEditorUpdatesCallback &&callback) { - sendDiagnosticsChangedCallback = std::move(callback); + sendDelayedEditorUpdatesCallback = std::move(callback); } QVector TranslationUnits::newerFileContainers(const QVector &fileContainers) const @@ -340,13 +354,18 @@ void TranslationUnits::checkIfTranslationUnitsForFilePathsDoesExists(const QVect } } -void TranslationUnits::sendDiagnosticChangedMessage(const TranslationUnit &translationUnit) +void TranslationUnits::sendDelayedEditorUpdates(const TranslationUnit &translationUnit) { - if (sendDiagnosticsChangedCallback) { - DiagnosticsChangedMessage message(translationUnit.fileContainer(), - translationUnit.mainFileDiagnostics()); + if (sendDelayedEditorUpdatesCallback) { + const auto fileContainer = translationUnit.fileContainer(); + DiagnosticsChangedMessage diagnosticsMessage(fileContainer, + translationUnit.mainFileDiagnostics()); + HighlightingChangedMessage highlightingsMessage(fileContainer, + translationUnit.highlightingInformations().toHighlightingMarksContainers(), + translationUnit.skippedSourceRanges().toSourceRangeContainers()); - sendDiagnosticsChangedCallback(std::move(message)); + sendDelayedEditorUpdatesCallback(std::move(diagnosticsMessage), + std::move(highlightingsMessage)); } } diff --git a/src/tools/clangbackend/ipcsource/translationunits.h b/src/tools/clangbackend/ipcsource/translationunits.h index abc0c4670f8..9493103a9c0 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.h +++ b/src/tools/clangbackend/ipcsource/translationunits.h @@ -46,15 +46,20 @@ namespace ClangBackEnd { class ProjectParts; class UnsavedFiles; class DiagnosticsChangedMessage; +class HighlightingChangedMessage; -enum class DiagnosticSendState +enum class EditorUpdatesSendState { - NoDiagnosticSend, - MaybeThereAreMoreDiagnostics, + NoEditorUpdatesSend, + MaybeThereAreMoreEditorUpdates, }; class TranslationUnits { +public: + using DelayedEditorUpdatesCallback = std::function; + public: TranslationUnits(ProjectParts &projectParts, UnsavedFiles &unsavedFiles); @@ -78,12 +83,13 @@ public: void updateTranslationUnitsWithChangedDependency(const Utf8String &filePath); void updateTranslationUnitsWithChangedDependencies(const QVector &fileContainers); - DiagnosticSendState sendChangedDiagnostics(); - DiagnosticSendState sendChangedDiagnosticsForCurrentEditor(); - DiagnosticSendState sendChangedDiagnosticsForVisibleEditors(); - DiagnosticSendState sendChangedDiagnosticsForAll(); + EditorUpdatesSendState sendDelayedEditorUpdatesForCurrentEditor(); + EditorUpdatesSendState sendDelayedEditorUpdatesForVisibleEditors(); + EditorUpdatesSendState sendDelayedEditorUpdatesForAll(); - void setSendChangeDiagnosticsCallback(std::function &&callback); + EditorUpdatesSendState sendDelayedEditorUpdates(); + + void setSendDelayedEditorUpdatesCallback(DelayedEditorUpdatesCallback &&callback); QVector newerFileContainers(const QVector &fileContainers) const; @@ -102,15 +108,15 @@ private: void checkIfTranslationUnitsDoesNotExists(const QVector &fileContainers) const; void checkIfTranslationUnitsForFilePathsDoesExists(const QVector &fileContainers) const; - void sendDiagnosticChangedMessage(const TranslationUnit &translationUnit); + void sendDelayedEditorUpdates(const TranslationUnit &translationUnit); void removeTranslationUnits(const QVector &fileContainers); template - DiagnosticSendState sendChangedDiagnostics(Predicate predicate); + EditorUpdatesSendState sendDelayedEditorUpdates(Predicate predicate); private: ClangFileSystemWatcher fileSystemWatcher; - std::function sendDiagnosticsChangedCallback; + DelayedEditorUpdatesCallback sendDelayedEditorUpdatesCallback; std::vector translationUnits_; ProjectParts &projectParts; UnsavedFiles &unsavedFiles_; diff --git a/tests/unit/echoserver/echoipcserver.cpp b/tests/unit/echoserver/echoipcserver.cpp index fe1e79180f3..2f8f7903838 100644 --- a/tests/unit/echoserver/echoipcserver.cpp +++ b/tests/unit/echoserver/echoipcserver.cpp @@ -41,6 +41,7 @@ #include "connectionserver.h" #include "registerunsavedfilesforeditormessage.h" #include "requestdiagnosticsmessage.h" +#include "requesthighlightingmessage.h" #include "unregisterunsavedfilesforeditormessage.h" #include "updatetranslationunitsforeditormessage.h" #include "updatevisibletranslationunitsmessage.h" @@ -107,6 +108,11 @@ void EchoIpcServer::requestDiagnostics(const RequestDiagnosticsMessage &message) echoMessage(QVariant::fromValue(message)); } +void EchoIpcServer::requestHighlighting(const RequestHighlightingMessage &message) +{ + echoMessage(QVariant::fromValue(message)); +} + void EchoIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) { echoMessage(QVariant::fromValue(message)); diff --git a/tests/unit/echoserver/echoipcserver.h b/tests/unit/echoserver/echoipcserver.h index f7710f6f3dc..05b0da68bd8 100644 --- a/tests/unit/echoserver/echoipcserver.h +++ b/tests/unit/echoserver/echoipcserver.h @@ -49,6 +49,7 @@ public: void unregisterUnsavedFilesForEditor(const UnregisterUnsavedFilesForEditorMessage &message) override; void completeCode(const CompleteCodeMessage &message) override; void requestDiagnostics(const RequestDiagnosticsMessage &message) override; + void requestHighlighting(const RequestHighlightingMessage &message) override; void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override; private: diff --git a/tests/unit/mockup/texteditor/semantichighlighter.h b/tests/unit/mockup/texteditor/semantichighlighter.h new file mode 100644 index 00000000000..fa9b5d0a66b --- /dev/null +++ b/tests/unit/mockup/texteditor/semantichighlighter.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef TEXTEDITOR_SEMANTICHIGHLIGHTER_H +#define TEXTEDITOR_SEMANTICHIGHLIGHTER_H + +namespace TextEditor { + +class HighlightingResult { +public: + unsigned line; + unsigned column; + unsigned length; + int kind; + + bool isValid() const + { return line != 0; } + + bool isInvalid() const + { return line == 0; } + + HighlightingResult() + : line(0), column(0), length(0), kind(0) + {} + + HighlightingResult(unsigned line, unsigned column, unsigned length, int kind) + : line(line), column(column), length(length), kind(kind) + {} + + bool operator==(const HighlightingResult& other) const + { + return line == other.line + && column == other.column + && length == other.length + && kind == other.kind; + } +}; + +} // namespace TextEditor + +#endif // TEXTEDITOR_SEMANTICHIGHLIGHTER_H diff --git a/tests/unit/unittest/chunksreportedmonitor.cpp b/tests/unit/unittest/chunksreportedmonitor.cpp new file mode 100644 index 00000000000..f304b42b824 --- /dev/null +++ b/tests/unit/unittest/chunksreportedmonitor.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "chunksreportedmonitor.h" + +#include + +namespace ClangBackEnd { + +ChunksReportedMonitor::ChunksReportedMonitor(const QFuture &future) + : m_future(future) +{ + m_futureWatcher.setFuture(future); + connect(&m_futureWatcher, &QFutureWatcher::resultsReadyAt, + this, &ChunksReportedMonitor::onResultsReadyAt); +} + +bool ChunksReportedMonitor::waitUntilFinished(int timeoutInMs) +{ + QSignalSpy spy(&m_futureWatcher, SIGNAL(finished())); + return spy.wait(timeoutInMs); +} + +void ChunksReportedMonitor::onResultsReadyAt(int beginIndex, int endIndex) +{ + Q_UNUSED(beginIndex) + Q_UNUSED(endIndex) + ++m_resultsReadyCounter; +} + +uint ChunksReportedMonitor::resultsReadyCounter() +{ + waitUntilFinished(); + return m_resultsReadyCounter; +} + +} // namespace ClangBackEnd diff --git a/tests/unit/unittest/chunksreportedmonitor.h b/tests/unit/unittest/chunksreportedmonitor.h new file mode 100644 index 00000000000..6725d46ea90 --- /dev/null +++ b/tests/unit/unittest/chunksreportedmonitor.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CLANGBACKEND_CHUNKSREPORTEDMONITOR_H +#define CLANGBACKEND_CHUNKSREPORTEDMONITOR_H + +#include +#include +#include + +#include + +namespace ClangBackEnd { + +class ChunksReportedMonitor : public QObject +{ + Q_OBJECT + +public: + ChunksReportedMonitor(const QFuture &future); + + uint resultsReadyCounter(); + +private: + bool waitUntilFinished(int timeoutInMs = 5000); + void onResultsReadyAt(int beginIndex, int endIndex); + +private: + QFuture m_future; + QFutureWatcher m_futureWatcher; + uint m_resultsReadyCounter = 0; +}; + +} // namespace ClangBackEnd + +#endif // CLANGBACKEND_CHUNKSREPORTEDMONITOR_H diff --git a/tests/unit/unittest/clangipcservertest.cpp b/tests/unit/unittest/clangipcservertest.cpp index 2f0711832b0..a95e42d53df 100644 --- a/tests/unit/unittest/clangipcservertest.cpp +++ b/tests/unit/unittest/clangipcservertest.cpp @@ -31,8 +31,11 @@ #include "mockipclient.h" #include +#include +#include #include #include +#include #include #include @@ -43,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +66,7 @@ using testing::Contains; using testing::Not; using testing::Eq; using testing::PrintToString; +using testing::_; namespace { @@ -78,6 +83,9 @@ using ClangBackEnd::TranslationUnitDoesNotExistMessage; using ClangBackEnd::ProjectPartsDoNotExistMessage; using ClangBackEnd::UpdateTranslationUnitsForEditorMessage; using ClangBackEnd::UpdateVisibleTranslationUnitsMessage; +using ClangBackEnd::RequestHighlightingMessage; +using ClangBackEnd::HighlightingChangedMessage; +using ClangBackEnd::HighlightingMarkContainer; MATCHER_P5(HasDirtyTranslationUnit, filePath, @@ -168,6 +176,18 @@ TEST_F(ClangIpcServer, GetCodeCompletion) clangServer.completeCode(completeCodeMessage); } +TEST_F(ClangIpcServer, RequestHighlighting) +{ + RequestHighlightingMessage requestHighlightingMessage({variableTestFilePath, projectPartId}); + + HighlightingMarkContainer highlightingMarkContainer(1, 6, 8, ClangBackEnd::HighlightingType::Function); + + EXPECT_CALL(mockIpcClient, highlightingChanged(Property(&HighlightingChangedMessage::highlightingMarks, Contains(highlightingMarkContainer)))) + .Times(1); + + clangServer.requestHighlighting(requestHighlightingMessage); +} + TEST_F(ClangIpcServer, GetCodeCompletionDependingOnArgumets) { CompleteCodeMessage completeCodeMessage(variableTestFilePath, diff --git a/tests/unit/unittest/clientserverinprocesstest.cpp b/tests/unit/unittest/clientserverinprocesstest.cpp index 0b5bb27d114..b483fe10994 100644 --- a/tests/unit/unittest/clientserverinprocesstest.cpp +++ b/tests/unit/unittest/clientserverinprocesstest.cpp @@ -47,9 +47,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -197,6 +199,17 @@ TEST_F(ClientServerInProcess, SendRequestDiagnosticsMessage) scheduleServerMessages(); } +TEST_F(ClientServerInProcess, SendRequestHighlightingMessage) +{ + ClangBackEnd::RequestHighlightingMessage message({Utf8StringLiteral("foo.cpp"), + Utf8StringLiteral("projectId")}); + + EXPECT_CALL(mockIpcServer, requestHighlighting(message)) + .Times(1); + + serverProxy.requestHighlighting(message); + scheduleServerMessages(); +} TEST_F(ClientServerInProcess, SendCodeCompletedMessage) { @@ -289,6 +302,21 @@ TEST_F(ClientServerInProcess, SendDiagnosticsChangedMessage) scheduleClientMessages(); } +TEST_F(ClientServerInProcess, SendHighlightingChangedMessage) +{ + ClangBackEnd::HighlightingMarkContainer container(1, 1, 1, ClangBackEnd::HighlightingType::Keyword); + + ClangBackEnd::HighlightingChangedMessage message(fileContainer, + {container}, + QVector()); + + EXPECT_CALL(mockIpcClient, highlightingChanged(message)) + .Times(1); + + clientProxy.highlightingChanged(message); + scheduleClientMessages(); +} + ClientServerInProcess::ClientServerInProcess() : serverProxy(&mockIpcClient, &buffer), clientProxy(&mockIpcServer, &buffer) diff --git a/tests/unit/unittest/clientserveroutsideprocess.cpp b/tests/unit/unittest/clientserveroutsideprocess.cpp index 8db8a12d8e4..0e04376585b 100644 --- a/tests/unit/unittest/clientserveroutsideprocess.cpp +++ b/tests/unit/unittest/clientserveroutsideprocess.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/unit/unittest/highlightinginformationstest.cpp b/tests/unit/unittest/highlightinginformationstest.cpp index 39238d8f7a8..0af449e4d44 100644 --- a/tests/unit/unittest/highlightinginformationstest.cpp +++ b/tests/unit/unittest/highlightinginformationstest.cpp @@ -144,6 +144,14 @@ TEST_F(HighlightingInformations, IteratorBeginEnd) ASSERT_THAT(infos.end(), endIterator); } +TEST_F(HighlightingInformations, ForFullTranslationUnitRange) +{ + const auto infos = translationUnit.highlightingInformations(); + + ASSERT_THAT(infos, AllOf(Contains(IsHighlightingInformation(1u, 1u, 4u, HighlightingType::Keyword)), + Contains(IsHighlightingInformation(277u, 5u, 15u, HighlightingType::Function)))); +} + TEST_F(HighlightingInformations, Size) { const auto range = translationUnit.sourceRange(5, 5, 5, 10); diff --git a/tests/unit/unittest/highlightingmarksreportertest.cpp b/tests/unit/unittest/highlightingmarksreportertest.cpp new file mode 100644 index 00000000000..bc23150d472 --- /dev/null +++ b/tests/unit/unittest/highlightingmarksreportertest.cpp @@ -0,0 +1,190 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://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 http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "gtest-qt-printing.h" + +using ClangBackEnd::Cursor; +using ClangBackEnd::HighlightingInformations; +using ClangBackEnd::HighlightingMarkContainer; +using ClangBackEnd::HighlightingType; +using ClangBackEnd::TranslationUnit; +using ClangBackEnd::UnsavedFiles; +using ClangBackEnd::ProjectPart; +using ClangBackEnd::ProjectParts; +using ClangBackEnd::TranslationUnits; +using ClangBackEnd::ChunksReportedMonitor; + +namespace { + +struct Data { + ProjectParts projects; + UnsavedFiles unsavedFiles; + TranslationUnits translationUnits{projects, unsavedFiles}; + TranslationUnit translationUnit{Utf8StringLiteral(TESTDATA_DIR"/highlightinginformations.cpp"), + ProjectPart(Utf8StringLiteral("projectPartId"), + {Utf8StringLiteral("-std=c++14")}), + {}, + translationUnits}; +}; + +class HighlightingMarksReporter : public ::testing::Test +{ +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + +protected: + static Data *d; +}; + +QVector noHighlightingMarks() +{ + return QVector(); +} + +QVector generateHighlightingMarks(uint count) +{ + auto container = QVector(); + + for (uint i = 0; i < count; ++i) { + const uint line = i + 1; + container.append(HighlightingMarkContainer(line, 1, 1, HighlightingType::Type)); + } + + return container; +} + +TEST_F(HighlightingMarksReporter, StartAndFinish) +{ + auto reporter = new ClangCodeModel::HighlightingMarksReporter(noHighlightingMarks()); + + auto future = reporter->start(); + + future.waitForFinished(); + ASSERT_THAT(future.isFinished(), true); +} + +TEST_F(HighlightingMarksReporter, ReportNothingIfNothingToReport) +{ + auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(0)); + + auto future = reporter->start(); + + ChunksReportedMonitor monitor(future); + ASSERT_THAT(monitor.resultsReadyCounter(), 0L); +} + +TEST_F(HighlightingMarksReporter, ReportSingleResultAsOneChunk) +{ + auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(1)); + reporter->setChunkSize(1); + + auto future = reporter->start(); + + ChunksReportedMonitor monitor(future); + ASSERT_THAT(monitor.resultsReadyCounter(), 1L); +} + +TEST_F(HighlightingMarksReporter, ReportRestIfChunkSizeNotReached) +{ + auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(1)); + const int notReachedChunkSize = 100; + reporter->setChunkSize(notReachedChunkSize); + + auto future = reporter->start(); + + ChunksReportedMonitor monitor(future); + ASSERT_THAT(monitor.resultsReadyCounter(), 1L); +} + +TEST_F(HighlightingMarksReporter, ReportChunksWithoutRest) +{ + auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(4)); + reporter->setChunkSize(1); + + auto future = reporter->start(); + + ChunksReportedMonitor monitor(future); + ASSERT_THAT(monitor.resultsReadyCounter(), 2L); +} + +TEST_F(HighlightingMarksReporter, ReportSingleChunkAndRest) +{ + auto reporter = new ClangCodeModel::HighlightingMarksReporter(generateHighlightingMarks(5)); + reporter->setChunkSize(2); + + auto future = reporter->start(); + + ChunksReportedMonitor monitor(future); + ASSERT_THAT(monitor.resultsReadyCounter(), 2L); +} + +TEST_F(HighlightingMarksReporter, ReportCompleteLines) +{ + QVector highlightingMarks { + HighlightingMarkContainer(1, 1, 1, HighlightingType::Type), + HighlightingMarkContainer(1, 2, 1, HighlightingType::Type), + HighlightingMarkContainer(2, 1, 1, HighlightingType::Type), + }; + auto reporter = new ClangCodeModel::HighlightingMarksReporter(highlightingMarks); + reporter->setChunkSize(1); + + auto future = reporter->start(); + + ChunksReportedMonitor monitor(future); + ASSERT_THAT(monitor.resultsReadyCounter(), 2L); +} + +Data *HighlightingMarksReporter::d; + +void HighlightingMarksReporter::SetUpTestCase() +{ + d = new Data; +} + +void HighlightingMarksReporter::TearDownTestCase() +{ + delete d; + d = nullptr; +} + +} // anonymous diff --git a/tests/unit/unittest/mockipclient.h b/tests/unit/unittest/mockipclient.h index 75c24dc9e3f..b05d9e16d1d 100644 --- a/tests/unit/unittest/mockipclient.h +++ b/tests/unit/unittest/mockipclient.h @@ -52,6 +52,8 @@ public: void(const ClangBackEnd::ProjectPartsDoNotExistMessage &message)); MOCK_METHOD1(diagnosticsChanged, void(const ClangBackEnd::DiagnosticsChangedMessage &message)); + MOCK_METHOD1(highlightingChanged, + void(const ClangBackEnd::HighlightingChangedMessage &message)); }; #endif // MOCKIPCLIENT_H diff --git a/tests/unit/unittest/mockipcserver.h b/tests/unit/unittest/mockipcserver.h index 83f9870b4d6..90b6f342704 100644 --- a/tests/unit/unittest/mockipcserver.h +++ b/tests/unit/unittest/mockipcserver.h @@ -60,6 +60,8 @@ public: void(const ClangBackEnd::CompleteCodeMessage &message)); MOCK_METHOD1(requestDiagnostics, void(const ClangBackEnd::RequestDiagnosticsMessage &message)); + MOCK_METHOD1(requestHighlighting, + void(const ClangBackEnd::RequestHighlightingMessage &message)); MOCK_METHOD1(updateVisibleTranslationUnits, void(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message)); }; diff --git a/tests/unit/unittest/mocksenddiagnosticscallback.h b/tests/unit/unittest/mocksendeditorupdatescallback.h similarity index 82% rename from tests/unit/unittest/mocksenddiagnosticscallback.h rename to tests/unit/unittest/mocksendeditorupdatescallback.h index ecb24fcbc99..7e13281a544 100644 --- a/tests/unit/unittest/mocksenddiagnosticscallback.h +++ b/tests/unit/unittest/mocksendeditorupdatescallback.h @@ -27,27 +27,27 @@ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ -#ifndef MOCKSENDDIAGNOSTICSCALLBACK_H -#define MOCKSENDDIAGNOSTICSCALLBACK_H +#ifndef MOCKSENDEDITORUPDATESCALLBACK_H +#define MOCKSENDEDITORUPDATESCALLBACK_H #include #include #include #include "gtest-qt-printing.h" -class SendDiagnosticCallback +class SendEditorUpdatesCallback { public: - virtual ~SendDiagnosticCallback() = default; + virtual ~SendEditorUpdatesCallback() = default; - virtual void sendDiagnostic() = 0; + virtual void sendEditorUpdates() = 0; }; -class MockSendDiagnosticCallback : public SendDiagnosticCallback +class MockSendEditorUpdatesCallback : public SendEditorUpdatesCallback { public: - MOCK_METHOD0(sendDiagnostic, + MOCK_METHOD0(sendEditorUpdates, void()); }; -#endif // MOCKSENDDIAGNOSTICSCALLBACK_H +#endif // MOCKSENDEDITORUPDATESCALLBACK_H diff --git a/tests/unit/unittest/readandwritemessageblocktest.cpp b/tests/unit/unittest/readandwritemessageblocktest.cpp index 78f1f8d4869..f319d1cabb6 100644 --- a/tests/unit/unittest/readandwritemessageblocktest.cpp +++ b/tests/unit/unittest/readandwritemessageblocktest.cpp @@ -37,7 +37,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -189,6 +192,15 @@ TEST_F(ReadAndWriteMessageBlock, CompareDiagnosticsChangedMessage) {container})); } +TEST_F(ReadAndWriteMessageBlock, CompareHighlightingChangedMessage) +{ + ClangBackEnd::HighlightingMarkContainer container(1, 1, 1, ClangBackEnd::HighlightingType::Keyword); + + CompareMessage(ClangBackEnd::HighlightingChangedMessage(fileContainer, + {container}, + QVector())); +} + TEST_F(ReadAndWriteMessageBlock, CompareRegisterUnsavedFilesForEditorMessage) { CompareMessage(ClangBackEnd::RegisterUnsavedFilesForEditorMessage({fileContainer})); @@ -204,6 +216,11 @@ TEST_F(ReadAndWriteMessageBlock, CompareRequestDiagnosticsMessage) CompareMessage(ClangBackEnd::RequestDiagnosticsMessage(fileContainer)); } +TEST_F(ReadAndWriteMessageBlock, CompareRequestHighlightingMessage) +{ + CompareMessage(ClangBackEnd::RequestHighlightingMessage(fileContainer)); +} + TEST_F(ReadAndWriteMessageBlock, GetInvalidMessageForAPartialBuffer) { writeCodeCompletedMessage(); diff --git a/tests/unit/unittest/translationunitstest.cpp b/tests/unit/unittest/translationunitstest.cpp index 9c84b4973ed..87dfc886ead 100644 --- a/tests/unit/unittest/translationunitstest.cpp +++ b/tests/unit/unittest/translationunitstest.cpp @@ -30,6 +30,8 @@ #include #include +#include +#include #include #include #include @@ -45,7 +47,7 @@ #include -#include "mocksenddiagnosticscallback.h" +#include "mocksendeditorupdatescallback.h" #include #include @@ -56,7 +58,8 @@ using ClangBackEnd::TranslationUnit; using ClangBackEnd::UnsavedFiles; using ClangBackEnd::ProjectPart; using ClangBackEnd::DiagnosticsChangedMessage; -using ClangBackEnd::DiagnosticSendState; +using ClangBackEnd::HighlightingChangedMessage; +using ClangBackEnd::EditorUpdatesSendState; using testing::IsNull; using testing::NotNull; @@ -84,15 +87,15 @@ class TranslationUnits : public ::testing::Test { protected: void SetUp() override; - void sendAllDiagnostics(); - void sendAllCurrentEditorDiagnostics(); - void sendAllVisibleEditorsDiagnostics(); + void sendAllEditorUpdates(); + void sendAllEditorUpdatesForCurrentEditor(); + void sendAllEditorUpdatesForVisibleEditors(); protected: ClangBackEnd::ProjectParts projects; ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles}; - MockSendDiagnosticCallback mockSendDiagnosticCallback; + MockSendEditorUpdatesCallback mockSendEditorUpdatesCallback; const Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"); const Utf8String headerPath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"); const Utf8String nonExistingFilePath = Utf8StringLiteral("foo.cpp"); @@ -208,6 +211,32 @@ TEST_F(TranslationUnits, RemoveFileAndCheckForDiagnostics) ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewDiagnostics()); } +TEST_F(TranslationUnits, UpdateUnsavedFileAndCheckForHighlightingInformations) +{ + ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u); + translationUnits.create({fileContainer, headerContainer}); + translationUnits.translationUnit(filePath, projectPartId).highlightingInformations(); + + translationUnits.update({headerContainerWithUnsavedContent}); + + ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewHighlightingInformations()); +} + +TEST_F(TranslationUnits, RemoveFileAndCheckForHighlightingInformations) +{ + ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer headerContainer(headerPath, projectPartId, Utf8StringVector(), 74u); + ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, projectPartId, Utf8String(), true, 75u); + translationUnits.create({fileContainer, headerContainer}); + translationUnits.translationUnit(filePath, projectPartId).highlightingInformations(); + + translationUnits.remove({headerContainerWithUnsavedContent}); + + ASSERT_TRUE(translationUnits.translationUnit(filePath, projectPartId).hasNewHighlightingInformations()); +} + TEST_F(TranslationUnits, DontGetNewerFileContainerIfRevisionIsTheSame) { ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u); @@ -345,75 +374,77 @@ TEST_F(TranslationUnits, IsNotVisibleEditorAfterBeingVisible) ASSERT_FALSE(translationUnit.isVisibleInEditor()); } -TEST_F(TranslationUnits, DoNotSendDiagnosticsIfThereIsNothingToSend) +TEST_F(TranslationUnits, DoNotSendEditorUpdatesIfThereIsNothingToSend) { - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); - sendAllDiagnostics(); + sendAllEditorUpdates(); } -TEST_F(TranslationUnits, SendDiagnosticsAfterTranslationUnitCreation) +TEST_F(TranslationUnits, SendEditorUpdatessAfterTranslationUnitCreation) { translationUnits.create({fileContainer, headerContainer}); - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(2); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(2); - sendAllDiagnostics(); + sendAllEditorUpdates(); } -TEST_F(TranslationUnits, DoNotSendDiagnosticsAfterGettingDiagnostics) +TEST_F(TranslationUnits, DoNotSendEditorUpdatesAfterGettingEditorUpdates) { translationUnits.create({fileContainer, headerContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); - translationUnit.diagnostics(); + translationUnit.diagnostics(); // Reset + translationUnit.highlightingInformations(); // Reset - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1); - sendAllDiagnostics(); + sendAllEditorUpdates(); } -TEST_F(TranslationUnits, SendDiagnosticsForCurrentEditor) +TEST_F(TranslationUnits, SendEditorUpdatesForCurrentEditor) { translationUnits.create({fileContainer, headerContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); translationUnit.setIsUsedByCurrentEditor(true); - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1); - sendAllCurrentEditorDiagnostics(); + sendAllEditorUpdatesForCurrentEditor(); } -TEST_F(TranslationUnits, DoNotSendDiagnosticsForCurrentEditorIfThereIsNoCurrentEditor) +TEST_F(TranslationUnits, DoNotSendEditorUpdatesForCurrentEditorIfThereIsNoCurrentEditor) { translationUnits.create({fileContainer, headerContainer}); - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); - sendAllCurrentEditorDiagnostics(); + sendAllEditorUpdatesForCurrentEditor(); } -TEST_F(TranslationUnits, DoNotSendDiagnosticsForCurrentEditorAfterGettingDiagnostics) +TEST_F(TranslationUnits, DoNotSendEditorUpdatesForCurrentEditorAfterGettingEditorUpdates) { translationUnits.create({fileContainer, headerContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); translationUnit.setIsUsedByCurrentEditor(true); - translationUnit.diagnostics(); + translationUnit.diagnostics(); // Reset + translationUnit.highlightingInformations(); // Reset - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); - sendAllCurrentEditorDiagnostics(); + sendAllEditorUpdatesForCurrentEditor(); } -TEST_F(TranslationUnits, DoNotSendDiagnosticsForVisibleEditorIfThereAreNoVisibleEditors) +TEST_F(TranslationUnits, DoNotSendEditorUpdatesForVisibleEditorIfThereAreNoVisibleEditors) { translationUnits.create({fileContainer, headerContainer}); - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(0); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); - translationUnits.sendChangedDiagnosticsForVisibleEditors(); + translationUnits.sendDelayedEditorUpdatesForVisibleEditors(); } -TEST_F(TranslationUnits, SendDiagnosticsForVisibleEditors) +TEST_F(TranslationUnits, SendEditorUpdatesForVisibleEditors) { translationUnits.create({fileContainer, headerContainer}); auto fileTranslationUnit = translationUnits.translationUnit(fileContainer); @@ -421,55 +452,58 @@ TEST_F(TranslationUnits, SendDiagnosticsForVisibleEditors) auto headerTranslationUnit = translationUnits.translationUnit(headerContainer); headerTranslationUnit.setIsVisibleInEditor(true); - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(2); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(2); - sendAllVisibleEditorsDiagnostics(); + sendAllEditorUpdatesForVisibleEditors(); } -TEST_F(TranslationUnits, SendOnlyOneDiagnosticsForVisibleEditor) +TEST_F(TranslationUnits, SendOnlyOneEditorUpdateForVisibleEditor) { translationUnits.create({fileContainer, headerContainer}); auto fileTranslationUnit = translationUnits.translationUnit(fileContainer); fileTranslationUnit.setIsVisibleInEditor(true); auto headerTranslationUnit = translationUnits.translationUnit(headerContainer); headerTranslationUnit.setIsVisibleInEditor(true); - headerTranslationUnit.diagnostics(); + headerTranslationUnit.diagnostics(); // Reset + headerTranslationUnit.highlightingInformations(); // Reset - EXPECT_CALL(mockSendDiagnosticCallback, sendDiagnostic()).Times(1); + EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1); - sendAllVisibleEditorsDiagnostics(); + sendAllEditorUpdatesForVisibleEditors(); } void TranslationUnits::SetUp() { projects.createOrUpdate({ClangBackEnd::ProjectPartContainer(projectPartId)}); - auto callback = [&] (const DiagnosticsChangedMessage &) { mockSendDiagnosticCallback.sendDiagnostic(); }; - translationUnits.setSendChangeDiagnosticsCallback(callback); + auto callback = [&] (const DiagnosticsChangedMessage &, const HighlightingChangedMessage &) { + mockSendEditorUpdatesCallback.sendEditorUpdates(); + }; + translationUnits.setSendDelayedEditorUpdatesCallback(callback); } -void TranslationUnits::sendAllDiagnostics() +void TranslationUnits::sendAllEditorUpdates() { - auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics; + auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; - while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics) - diagnosticSendState = translationUnits.sendChangedDiagnostics(); + while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) + editorUpdatesSendState = translationUnits.sendDelayedEditorUpdates(); } -void TranslationUnits::sendAllCurrentEditorDiagnostics() +void TranslationUnits::sendAllEditorUpdatesForCurrentEditor() { - auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics; + auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; - while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics) - diagnosticSendState = translationUnits.sendChangedDiagnosticsForCurrentEditor(); + while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) + editorUpdatesSendState = translationUnits.sendDelayedEditorUpdatesForCurrentEditor(); } -void TranslationUnits::sendAllVisibleEditorsDiagnostics() +void TranslationUnits::sendAllEditorUpdatesForVisibleEditors() { - auto diagnosticSendState = DiagnosticSendState::MaybeThereAreMoreDiagnostics; + auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; - while (diagnosticSendState == DiagnosticSendState::MaybeThereAreMoreDiagnostics) - diagnosticSendState = translationUnits.sendChangedDiagnosticsForVisibleEditors(); + while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) + editorUpdatesSendState = translationUnits.sendDelayedEditorUpdatesForVisibleEditors(); } } diff --git a/tests/unit/unittest/translationunittest.cpp b/tests/unit/unittest/translationunittest.cpp index 12b0137a6e1..24bdcdac101 100644 --- a/tests/unit/unittest/translationunittest.cpp +++ b/tests/unit/unittest/translationunittest.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -194,6 +195,15 @@ TEST_F(TranslationUnit, DependedFilePaths) Contains(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h")))); } +TEST_F(TranslationUnit, DeletedFileShouldNotNeedReparsing) +{ + auto translationUnit = createTemporaryTranslationUnit(); + + translationUnit.setDirtyIfDependencyIsMet(translationUnit.filePath()); + + ASSERT_FALSE(translationUnit.isNeedingReparse()); +} + TEST_F(TranslationUnit, NeedsNoReparseAfterCreation) { translationUnit.cxTranslationUnit(); @@ -201,13 +211,6 @@ TEST_F(TranslationUnit, NeedsNoReparseAfterCreation) ASSERT_FALSE(translationUnit.isNeedingReparse()); } -TEST_F(TranslationUnit, HasNewDiagnosticsAfterCreation) -{ - translationUnit.cxTranslationUnit(); - - ASSERT_TRUE(translationUnit.hasNewDiagnostics()); -} - TEST_F(TranslationUnit, NeedsReparseAfterChangeOfMainFile) { translationUnit.cxTranslationUnit(); @@ -217,15 +220,6 @@ TEST_F(TranslationUnit, NeedsReparseAfterChangeOfMainFile) ASSERT_TRUE(translationUnit.isNeedingReparse()); } -TEST_F(TranslationUnit, HasNewDiagnosticsAfterChangeOfMainFile) -{ - translationUnit.cxTranslationUnit(); - - translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath); - - ASSERT_TRUE(translationUnit.hasNewDiagnostics()); -} - TEST_F(TranslationUnit, NoNeedForReparsingForIndependendFile) { translationUnit.cxTranslationUnit(); @@ -244,15 +238,6 @@ TEST_F(TranslationUnit, NeedsReparsingForDependendFile) ASSERT_TRUE(translationUnit.isNeedingReparse()); } -TEST_F(TranslationUnit, NeedsReparsingForMainFile) -{ - translationUnit.cxTranslationUnit(); - - translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath); - - ASSERT_TRUE(translationUnit.isNeedingReparse()); -} - TEST_F(TranslationUnit, NeedsNoReparsingAfterReparsing) { translationUnit.cxTranslationUnit(); @@ -263,6 +248,22 @@ TEST_F(TranslationUnit, NeedsNoReparsingAfterReparsing) ASSERT_FALSE(translationUnit.isNeedingReparse()); } +TEST_F(TranslationUnit, HasNewDiagnosticsAfterCreation) +{ + translationUnit.cxTranslationUnit(); + + ASSERT_TRUE(translationUnit.hasNewDiagnostics()); +} + +TEST_F(TranslationUnit, HasNewDiagnosticsAfterChangeOfMainFile) +{ + translationUnit.cxTranslationUnit(); + + translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath); + + ASSERT_TRUE(translationUnit.hasNewDiagnostics()); +} + TEST_F(TranslationUnit, HasNoNewDiagnosticsForIndependendFile) { translationUnit.cxTranslationUnit(); @@ -282,32 +283,59 @@ TEST_F(TranslationUnit, HasNewDiagnosticsForDependendFile) ASSERT_TRUE(translationUnit.hasNewDiagnostics()); } -TEST_F(TranslationUnit, HasNewDiagnosticsForMainFile) -{ - translationUnit.cxTranslationUnit(); - - translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath); - - ASSERT_TRUE(translationUnit.hasNewDiagnostics()); -} - TEST_F(TranslationUnit, HasNoNewDiagnosticsAfterGettingDiagnostics) { translationUnit.cxTranslationUnit(); translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath); - translationUnit.diagnostics(); + translationUnit.diagnostics(); // Reset hasNewDiagnostics ASSERT_FALSE(translationUnit.hasNewDiagnostics()); } -TEST_F(TranslationUnit, DeletedFileShouldBeNotSetDirty) +TEST_F(TranslationUnit, HasNewHighlightingInformationsAfterCreation) { - auto translationUnit = createTemporaryTranslationUnit(); + translationUnit.cxTranslationUnit(); - translationUnit.setDirtyIfDependencyIsMet(translationUnit.filePath()); + ASSERT_TRUE(translationUnit.hasNewHighlightingInformations()); +} - ASSERT_FALSE(translationUnit.isNeedingReparse()); +TEST_F(TranslationUnit, HasNewHighlightingInformationsForMainFile) +{ + translationUnit.cxTranslationUnit(); + + translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath); + + ASSERT_TRUE(translationUnit.hasNewHighlightingInformations()); +} + +TEST_F(TranslationUnit, HasNoNewHighlightingInformationsForIndependendFile) +{ + translationUnit.cxTranslationUnit(); + translationUnit.highlightingInformations(); + + translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/otherfiles.h")); + + ASSERT_FALSE(translationUnit.hasNewHighlightingInformations()); +} + +TEST_F(TranslationUnit, HasNewHighlightingInformationsForDependendFile) +{ + translationUnit.cxTranslationUnit(); + + translationUnit.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h")); + + ASSERT_TRUE(translationUnit.hasNewHighlightingInformations()); +} + +TEST_F(TranslationUnit, HasNoNewHighlightingInformationsAfterGettingHighlightingInformations) +{ + translationUnit.cxTranslationUnit(); + translationUnit.setDirtyIfDependencyIsMet(translationUnitFilePath); + + translationUnit.highlightingInformations(); + + ASSERT_FALSE(translationUnit.hasNewHighlightingInformations()); } ::TranslationUnit TranslationUnit::createTemporaryTranslationUnit() diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index b2d209d4dca..4c18b07cafb 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -56,7 +56,9 @@ SOURCES += \ senddocumenttrackertest.cpp \ cursortest.cpp \ highlightinginformationstest.cpp \ - skippedsourcerangestest.cpp + skippedsourcerangestest.cpp \ + highlightingmarksreportertest.cpp \ + chunksreportedmonitor.cpp HEADERS += \ gtest-qt-printing.h \ @@ -64,6 +66,7 @@ HEADERS += \ mockipcserver.h \ spydummy.h \ matcher-diagnosticcontainer.h \ - mocksenddiagnosticscallback.h + chunksreportedmonitor.h \ + mocksendeditorupdatescallback.h OTHER_FILES += $$files(data/*) From 6cab8e6f4ae3713752d70b844ca92dacefebb4cd Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Thu, 26 Nov 2015 16:31:41 +0100 Subject: [PATCH 10/47] Clang: Tests on MSVC2013: Disable warning 'unreferenced formal parameter' Change-Id: Id3889a2529e5d816617806ade20323504e019384 Reviewed-by: Marco Bubke --- tests/unit/unittest/unittest.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 4c18b07cafb..de135d251eb 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -15,6 +15,7 @@ DEFINES += \ CLANGBACKEND_TESTS \ DONT_CHECK_MESSAGE_COUNTER \ TESTDATA_DIR=\"R\\\"xxx($$PWD/data)xxx\\\"\" +win32-msvc*:QMAKE_CXXFLAGS_WARN_ON -= -w34100 # 'unreferenced formal parameter' in MATCHER_* functions win32:DEFINES += ECHOSERVER=\"R\\\"xxx($$OUT_PWD/../echo)xxx\\\"\" unix: DEFINES += ECHOSERVER=\"R\\\"xxx($$OUT_PWD/../echoserver/echo)xxx\\\"\" From f7ab95247bafd33941b17b3618e70f56ce9b529a Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Thu, 26 Nov 2015 13:44:32 +0100 Subject: [PATCH 11/47] Bookmark: Remove unneeded includes of QDebug Change-Id: I7c7a1d1b8fe94072255247721fd6f4f4b9ddb114 Reviewed-by: Erik Verbruggen --- src/plugins/bookmarks/bookmark.cpp | 1 - src/plugins/bookmarks/bookmarksplugin.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/plugins/bookmarks/bookmark.cpp b/src/plugins/bookmarks/bookmark.cpp index 70c0352d11c..7951bf30cbb 100644 --- a/src/plugins/bookmarks/bookmark.cpp +++ b/src/plugins/bookmarks/bookmark.cpp @@ -32,7 +32,6 @@ #include "bookmarkmanager.h" #include "bookmarks_global.h" -#include #include #include diff --git a/src/plugins/bookmarks/bookmarksplugin.cpp b/src/plugins/bookmarks/bookmarksplugin.cpp index a8014e84863..dc38b49c8b4 100644 --- a/src/plugins/bookmarks/bookmarksplugin.cpp +++ b/src/plugins/bookmarks/bookmarksplugin.cpp @@ -46,7 +46,6 @@ #include #include -#include #include From ce2a891c48da5d4b3acc1a46e26091617319f388 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 26 Nov 2015 17:56:55 +0100 Subject: [PATCH 12/47] Tests: Fix sdktool test Change-Id: Idc21354d3f546c1aaff7d1481c80190c6c1c366c Reviewed-by: Tobias Hunger Reviewed-by: Orgad Shaneh --- tests/auto/sdktool/sdktool.pro | 2 ++ tests/auto/sdktool/sdktool.qbs | 2 ++ tests/auto/sdktool/tst_sdktool.cpp | 6 +----- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/auto/sdktool/sdktool.pro b/tests/auto/sdktool/sdktool.pro index cc5fb2d28cc..d333b897287 100644 --- a/tests/auto/sdktool/sdktool.pro +++ b/tests/auto/sdktool/sdktool.pro @@ -1,3 +1,5 @@ include(../qttest.pri) +DEFINES += "SDKTOOL_DIR=\\\"$$IDE_LIBEXEC_PATH\\\"" + SOURCES += tst_sdktool.cpp diff --git a/tests/auto/sdktool/sdktool.qbs b/tests/auto/sdktool/sdktool.qbs index 1fd08fc2586..ca201b4b8e4 100644 --- a/tests/auto/sdktool/sdktool.qbs +++ b/tests/auto/sdktool/sdktool.qbs @@ -7,4 +7,6 @@ QtcAutotest { name: "Test sources" files: "tst_sdktool.cpp" } + + cpp.defines: base.concat(['SDKTOOL_DIR="' + qbs.installRoot + '/' + project.ide_libexec_path + '"']) } diff --git a/tests/auto/sdktool/tst_sdktool.cpp b/tests/auto/sdktool/tst_sdktool.cpp index 8cc01357d4c..c3a3fe9b8e4 100644 --- a/tests/auto/sdktool/tst_sdktool.cpp +++ b/tests/auto/sdktool/tst_sdktool.cpp @@ -43,11 +43,7 @@ private slots: void SdktoolTest::testSdktool() { - QDir rootDir = QCoreApplication::applicationDirPath(); - rootDir.cdUp(); - rootDir.cdUp(); - rootDir.cdUp(); - rootDir.cd(QLatin1String("bin")); + QDir rootDir(SDKTOOL_DIR); QProcess process; process.start(rootDir.absoluteFilePath(QLatin1String("sdktool")), QStringList() << QLatin1String("-test")); From a610c6740b804688b1e9bfe009d28b17212eb45c Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 25 Nov 2015 16:33:01 +0100 Subject: [PATCH 13/47] Clang: Fix names for visibility changes in translation units Change-Id: Iafee06b8f39610f4245ad86eec2b6d442acc61e2 Reviewed-by: Nikolai Kosjar --- .../clangbackend/ipcsource/clangipcserver.cpp | 4 ++-- .../clangbackend/ipcsource/translationunits.cpp | 4 ++-- .../clangbackend/ipcsource/translationunits.h | 4 ++-- tests/unit/unittest/translationunitstest.cpp | 16 ++++++++-------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index a7652caf28d..eeae3d7ffb5 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -280,8 +280,8 @@ void ClangIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslatio TIME_SCOPE_DURATION("ClangIpcServer::updateVisibleTranslationUnits"); try { - translationUnits.setCurrentEditor(message.currentEditorFilePath()); - translationUnits.setVisibleEditors(message.visibleEditorFilePaths()); + translationUnits.setUsedByCurrentEditor(message.currentEditorFilePath()); + translationUnits.setVisibleInEditors(message.visibleEditorFilePaths()); } catch (const std::exception &exception) { qWarning() << "Error in ClangIpcServer::updateVisibleTranslationUnits:" << exception.what(); } diff --git a/src/tools/clangbackend/ipcsource/translationunits.cpp b/src/tools/clangbackend/ipcsource/translationunits.cpp index c1daa3bf501..459679fc7a2 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.cpp +++ b/src/tools/clangbackend/ipcsource/translationunits.cpp @@ -100,13 +100,13 @@ void TranslationUnits::remove(const QVector &fileContainers) updateTranslationUnitsWithChangedDependencies(fileContainers); } -void TranslationUnits::setCurrentEditor(const Utf8String &filePath) +void TranslationUnits::setUsedByCurrentEditor(const Utf8String &filePath) { for (TranslationUnit &translationUnit : translationUnits_) translationUnit.setIsUsedByCurrentEditor(translationUnit.filePath() == filePath); } -void TranslationUnits::setVisibleEditors(const Utf8StringVector &filePaths) +void TranslationUnits::setVisibleInEditors(const Utf8StringVector &filePaths) { for (TranslationUnit &translationUnit : translationUnits_) translationUnit.setIsVisibleInEditor(filePaths.contains(translationUnit.filePath())); diff --git a/src/tools/clangbackend/ipcsource/translationunits.h b/src/tools/clangbackend/ipcsource/translationunits.h index 9493103a9c0..aca120dad00 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.h +++ b/src/tools/clangbackend/ipcsource/translationunits.h @@ -67,8 +67,8 @@ public: void update(const QVector &fileContainers); void remove(const QVector &fileContainers); - void setCurrentEditor(const Utf8String &filePath); - void setVisibleEditors(const Utf8StringVector &filePaths); + void setUsedByCurrentEditor(const Utf8String &filePath); + void setVisibleInEditors(const Utf8StringVector &filePaths); const TranslationUnit &translationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const; const TranslationUnit &translationUnit(const FileContainer &fileContainer) const; diff --git a/tests/unit/unittest/translationunitstest.cpp b/tests/unit/unittest/translationunitstest.cpp index 87dfc886ead..d502a51351e 100644 --- a/tests/unit/unittest/translationunitstest.cpp +++ b/tests/unit/unittest/translationunitstest.cpp @@ -317,7 +317,7 @@ TEST_F(TranslationUnits, isUsedByCurrentEditor) translationUnits.create({fileContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); - translationUnits.setCurrentEditor(filePath); + translationUnits.setUsedByCurrentEditor(filePath); ASSERT_TRUE(translationUnit.isUsedByCurrentEditor()); } @@ -327,7 +327,7 @@ TEST_F(TranslationUnits, IsNotCurrentEditor) translationUnits.create({fileContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); - translationUnits.setCurrentEditor(headerPath); + translationUnits.setUsedByCurrentEditor(headerPath); ASSERT_FALSE(translationUnit.isUsedByCurrentEditor()); } @@ -336,9 +336,9 @@ TEST_F(TranslationUnits, IsNotCurrentEditorAfterBeingCurrent) { translationUnits.create({fileContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); - translationUnits.setCurrentEditor(filePath); + translationUnits.setUsedByCurrentEditor(filePath); - translationUnits.setCurrentEditor(headerPath); + translationUnits.setUsedByCurrentEditor(headerPath); ASSERT_FALSE(translationUnit.isUsedByCurrentEditor()); } @@ -348,7 +348,7 @@ TEST_F(TranslationUnits, IsVisibleEditor) translationUnits.create({fileContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); - translationUnits.setVisibleEditors({filePath}); + translationUnits.setVisibleInEditors({filePath}); ASSERT_TRUE(translationUnit.isVisibleInEditor()); } @@ -358,7 +358,7 @@ TEST_F(TranslationUnits, IsNotVisibleEditor) translationUnits.create({fileContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); - translationUnits.setVisibleEditors({headerPath}); + translationUnits.setVisibleInEditors({headerPath}); ASSERT_FALSE(translationUnit.isVisibleInEditor()); } @@ -367,9 +367,9 @@ TEST_F(TranslationUnits, IsNotVisibleEditorAfterBeingVisible) { translationUnits.create({fileContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); - translationUnits.setVisibleEditors({filePath}); + translationUnits.setVisibleInEditors({filePath}); - translationUnits.setVisibleEditors({headerPath}); + translationUnits.setVisibleInEditors({headerPath}); ASSERT_FALSE(translationUnit.isVisibleInEditor()); } From ff1e2150e459baaea3ab4f267db9d436a54d794c Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 23 Nov 2015 10:20:43 +0100 Subject: [PATCH 14/47] QmlProfiler: Fix bogus disconnect() calls Change-Id: I8caa5a2a45682e7472b9ebac9050c1a9a2a6f932 Reviewed-by: Joerg Bornemann --- .../qmlprofiler/qmlprofilerclientmanager.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp index 753a389d33c..49856a52fa2 100644 --- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp @@ -191,14 +191,16 @@ void QmlProfilerClientManager::disconnectClientSignals() disconnect(d->qmlclientplugin.data(), SIGNAL(complete(qint64)), this, SLOT(qmlComplete(qint64))); disconnect(d->qmlclientplugin.data(), - SIGNAL(rangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation, - qint64,qint64,qint64,qint64,qint64)), + SIGNAL(rangedEvent(QmlDebug::Message,QmlDebug::RangeType,int,qint64,qint64, + QString,QmlDebug::QmlEventLocation,qint64,qint64,qint64, + qint64,qint64)), d->modelManager, - SLOT(addQmlEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation, - qint64,qint64,qint64,qint64,qint64))); - disconnect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64)), + SLOT(addQmlEvent(QmlDebug::Message,QmlDebug::RangeType,int,qint64,qint64, + QString,QmlDebug::QmlEventLocation,qint64,qint64,qint64,qint64, + qint64))); + disconnect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64,QList)), d->modelManager->traceTime(), SLOT(increaseEndTime(qint64))); - disconnect(d->qmlclientplugin.data(), SIGNAL(traceStarted(qint64)), + disconnect(d->qmlclientplugin.data(), SIGNAL(traceStarted(qint64,QList)), d->modelManager->traceTime(), SLOT(decreaseStartTime(qint64))); disconnect(d->qmlclientplugin.data(), SIGNAL(enabledChanged()), d->qmlclientplugin.data(), SLOT(sendRecordingStatus())); From e2097fe8ec6a719071a2dfff577c2de0bd073ec3 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 30 Nov 2015 08:12:53 +0100 Subject: [PATCH 15/47] Tests: Fix compile for OSX... ...as the define points to a path containing a whitespace which confuses moc this must be escaped. Change-Id: If5fe0e7b3eeb0f4a46df4df3eb8236c94587ea88 Reviewed-by: Jake Petroules --- tests/auto/sdktool/sdktool.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/sdktool/sdktool.pro b/tests/auto/sdktool/sdktool.pro index d333b897287..b83c78847f9 100644 --- a/tests/auto/sdktool/sdktool.pro +++ b/tests/auto/sdktool/sdktool.pro @@ -1,5 +1,5 @@ include(../qttest.pri) -DEFINES += "SDKTOOL_DIR=\\\"$$IDE_LIBEXEC_PATH\\\"" +DEFINES += "SDKTOOL_DIR=\\\"$$replace(IDE_LIBEXEC_PATH, " ", "\\ ")\\\"" SOURCES += tst_sdktool.cpp From 1e58db55b3342b45aa1edc94b75438a378266747 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 24 Nov 2015 11:10:00 +0100 Subject: [PATCH 16/47] QML Debugger: Add an explicit override for bool to DebuggerCommand This makes sure we construct QJsonValues from bools, rather than casting them to ints. Change-Id: Ibc3e5322460e5bec153d80024219ba7935268d68 Task-number: QTCREATORBUG-15395 Reviewed-by: Ulf Hermann --- src/plugins/debugger/debuggerprotocol.cpp | 5 +++++ src/plugins/debugger/debuggerprotocol.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 35c2d220f35..23162320368 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -843,6 +843,11 @@ void DebuggerCommand::arg(const char *value) args = arr; } +void DebuggerCommand::arg(const char *name, bool value) +{ + args = addToJsonObject(args, name, value); +} + void DebuggerCommand::arg(const char *name, const QJsonValue &value) { args = addToJsonObject(args, name, value); diff --git a/src/plugins/debugger/debuggerprotocol.h b/src/plugins/debugger/debuggerprotocol.h index f85746a006a..d7849a5b927 100644 --- a/src/plugins/debugger/debuggerprotocol.h +++ b/src/plugins/debugger/debuggerprotocol.h @@ -58,6 +58,7 @@ public: DebuggerCommand(const QByteArray &f, int fl, const Callback &cb) : function(f), callback(cb), flags(fl) {} void arg(const char *value); + void arg(const char *name, bool value); void arg(const char *name, int value); void arg(const char *name, qlonglong value); void arg(const char *name, qulonglong value); From b9adbffe6fffe940547a5add209474bfea07167a Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 26 Nov 2015 10:48:28 +0100 Subject: [PATCH 17/47] Debugger: Proactively try to connect to QML port in mixed engine Just like with the QML-only engine we might not get the output for a variety of reasons. As we've specified the port on the command line, it's likely that the application will start listening at some point, though. Change-Id: Ifda69ba15c659cf95e708d35bed34cfb9b3c40ec Task-number: QTCREATORBUG-15409 Reviewed-by: Christian Stenger --- src/plugins/debugger/qml/qmlengine.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index c4b6fcf7c77..c76b23e53ac 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -355,10 +355,8 @@ void QmlEngine::tryToConnect(quint16 port) if (state() == EngineRunRequested) { if (isSlaveEngine()) { // Probably cpp is being debugged and hence we did not get the output yet. - if (!masterEngine()->isDying()) { - d->noDebugOutputTimer.setInterval(4000); - d->noDebugOutputTimer.start(); - } + if (!masterEngine()->isDying()) + beginConnection(port); else appStartupFailed(tr("No application output received in time")); } else { From 6a1fc699fde55e55b462045fea8b590006b72ee4 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 27 Nov 2015 14:59:56 +0100 Subject: [PATCH 18/47] Clang: Tests: Use google test dir from qmake variable ...so that we can compile the tests without environment variables: qmake LLVM_INSTALL_DIR=/the/path1 GOOGLETEST_DIR=/the/path2 Change-Id: I40633988d325720397dea28bd13b957a31712a9d Reviewed-by: Christian Stenger --- tests/unit/unittest/gmock_dependency.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/unittest/gmock_dependency.pri b/tests/unit/unittest/gmock_dependency.pri index e70edb9e356..a771dc39b74 100644 --- a/tests/unit/unittest/gmock_dependency.pri +++ b/tests/unit/unittest/gmock_dependency.pri @@ -1,4 +1,4 @@ -GOOGLETEST_DIR = $$(GOOGLETEST_DIR) +isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR) isEmpty(GOOGLETEST_DIR):linux-* { GTEST_SRC_DIR = /usr/include/gmock From daf936967986ed05e7a0fdcc261d88ee181b2422 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 27 Nov 2015 16:02:38 +0100 Subject: [PATCH 19/47] Clang: Remove dead code Change-Id: Ia36e96424580d9b34000cf4a9b38eab98f9c449c Reviewed-by: Marco Bubke --- src/plugins/clangcodemodel/clangcodemodel.pro | 43 +- src/plugins/clangcodemodel/clangcodemodel.qbs | 191 +-- .../clangcodemodel/clangcodemodelplugin.cpp | 34 +- .../clangcodemodel/clangcodemodelplugin.h | 9 - .../clangcompletionassistinterface.cpp | 2 +- .../clangcompletionassistinterface.h | 6 +- .../clangeditordocumentprocessor.cpp | 2 - src/plugins/clangcodemodel/clangindexer.cpp | 172 --- src/plugins/clangcodemodel/clangindexer.h | 99 -- src/plugins/clangcodemodel/clangsymbol.cpp | 118 -- src/plugins/clangcodemodel/clangsymbol.h | 78 - src/plugins/clangcodemodel/clangutils.h | 8 +- src/plugins/clangcodemodel/constants.h | 25 +- .../clangcodemodel/cppcreatemarkers.cpp | 135 -- src/plugins/clangcodemodel/cppcreatemarkers.h | 94 -- .../clangcodemodel/cxprettyprinter.cpp | 551 ------- src/plugins/clangcodemodel/cxprettyprinter.h | 76 - src/plugins/clangcodemodel/cxraii.h | 146 -- .../clangcodemodel/dependencygraph.cpp | 209 --- src/plugins/clangcodemodel/dependencygraph.h | 236 --- src/plugins/clangcodemodel/diagnostic.cpp | 64 - src/plugins/clangcodemodel/diagnostic.h | 83 -- src/plugins/clangcodemodel/fastindexer.cpp | 37 - src/plugins/clangcodemodel/fastindexer.h | 50 - src/plugins/clangcodemodel/index.cpp | 491 ------- src/plugins/clangcodemodel/index.h | 88 -- src/plugins/clangcodemodel/indexer.cpp | 1284 ----------------- src/plugins/clangcodemodel/indexer.h | 104 -- src/plugins/clangcodemodel/pchmanager.cpp | 66 +- src/plugins/clangcodemodel/semanticmarker.cpp | 531 ------- src/plugins/clangcodemodel/semanticmarker.h | 95 -- src/plugins/clangcodemodel/sourcelocation.cpp | 80 - src/plugins/clangcodemodel/sourcelocation.h | 70 - src/plugins/clangcodemodel/sourcemarker.cpp | 42 - src/plugins/clangcodemodel/sourcemarker.h | 98 -- .../test/clangcodecompletion_test.cpp | 4 +- src/plugins/clangcodemodel/unit.cpp | 26 +- src/plugins/clangcodemodel/unit.h | 15 +- src/plugins/clangcodemodel/unsavedfiledata.h | 4 +- src/plugins/clangcodemodel/utils.cpp | 90 -- src/plugins/clangcodemodel/utils.h | 66 - src/plugins/clangcodemodel/utils_p.cpp | 125 -- src/plugins/clangcodemodel/utils_p.h | 66 - 43 files changed, 181 insertions(+), 5632 deletions(-) delete mode 100644 src/plugins/clangcodemodel/clangindexer.cpp delete mode 100644 src/plugins/clangcodemodel/clangindexer.h delete mode 100644 src/plugins/clangcodemodel/clangsymbol.cpp delete mode 100644 src/plugins/clangcodemodel/clangsymbol.h delete mode 100644 src/plugins/clangcodemodel/cppcreatemarkers.cpp delete mode 100644 src/plugins/clangcodemodel/cppcreatemarkers.h delete mode 100644 src/plugins/clangcodemodel/cxprettyprinter.cpp delete mode 100644 src/plugins/clangcodemodel/cxprettyprinter.h delete mode 100644 src/plugins/clangcodemodel/cxraii.h delete mode 100644 src/plugins/clangcodemodel/dependencygraph.cpp delete mode 100644 src/plugins/clangcodemodel/dependencygraph.h delete mode 100644 src/plugins/clangcodemodel/diagnostic.cpp delete mode 100644 src/plugins/clangcodemodel/diagnostic.h delete mode 100644 src/plugins/clangcodemodel/fastindexer.cpp delete mode 100644 src/plugins/clangcodemodel/fastindexer.h delete mode 100644 src/plugins/clangcodemodel/index.cpp delete mode 100644 src/plugins/clangcodemodel/index.h delete mode 100644 src/plugins/clangcodemodel/indexer.cpp delete mode 100644 src/plugins/clangcodemodel/indexer.h delete mode 100644 src/plugins/clangcodemodel/semanticmarker.cpp delete mode 100644 src/plugins/clangcodemodel/semanticmarker.h delete mode 100644 src/plugins/clangcodemodel/sourcelocation.cpp delete mode 100644 src/plugins/clangcodemodel/sourcelocation.h delete mode 100644 src/plugins/clangcodemodel/sourcemarker.cpp delete mode 100644 src/plugins/clangcodemodel/sourcemarker.h delete mode 100644 src/plugins/clangcodemodel/utils.cpp delete mode 100644 src/plugins/clangcodemodel/utils.h delete mode 100644 src/plugins/clangcodemodel/utils_p.cpp delete mode 100644 src/plugins/clangcodemodel/utils_p.h diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index b12de496f9f..9b5ac7ddbfd 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -5,7 +5,7 @@ LIBS += $$LLVM_LIBS INCLUDEPATH += $$LLVM_INCLUDEPATH DEFINES += CLANGCODEMODEL_LIBRARY -# The following defines are used to determine the clang include path for intrinsics +# The following defines are used to determine the clang include path for intrinsics. DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\" DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\"" @@ -33,26 +33,15 @@ SOURCES += \ clangmodelmanagersupport.cpp \ clangprojectsettings.cpp \ clangprojectsettingspropertiespage.cpp \ - clangsymbol.cpp \ clangtextmark.cpp \ clangutils.cpp \ completionchunkstotextconverter.cpp \ - cppcreatemarkers.cpp \ - cxprettyprinter.cpp \ - diagnostic.cpp \ - fastindexer.cpp \ highlightingmarksreporter.cpp \ pchinfo.cpp \ pchmanager.cpp \ raii/scopedclangoptions.cpp \ - semanticmarker.cpp \ - sourcelocation.cpp \ - sourcemarker.cpp \ unit.cpp \ - unsavedfiledata.cpp \ - utils.cpp \ - utils_p.cpp - + unsavedfiledata.cpp HEADERS += \ activationsequencecontextprocessor.h \ @@ -77,42 +66,16 @@ HEADERS += \ clangmodelmanagersupport.h \ clangprojectsettings.h \ clangprojectsettingspropertiespage.h \ - clangsymbol.h \ clangtextmark.h \ clangutils.h \ completionchunkstotextconverter.h \ constants.h \ - cppcreatemarkers.h \ - cxprettyprinter.h \ - cxraii.h \ - diagnostic.h \ - fastindexer.h \ highlightingmarksreporter.h \ pchinfo.h \ pchmanager.h \ raii/scopedclangoptions.h \ - semanticmarker.h \ - sourcelocation.h \ - sourcemarker.h \ unit.h \ - unsavedfiledata.h \ - utils.h \ - utils_p.h - - -contains(DEFINES, CLANG_INDEXING) { - HEADERS += \ - clangindexer.h \ - index.h \ - indexer.h -# dependencygraph.h \ - - SOURCES += \ - clangindexer.cpp \ - index.cpp \ - indexer.cpp -# dependencygraph.cpp \ -} + unsavedfiledata.h FORMS += clangprojectsettingspropertiespage.ui diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index d0153d39793..e6d06a752bd 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -20,10 +20,6 @@ QtcPlugin { "QmakeProjectManager", ] - property bool clangCompletion: true - property bool clangHighlighting: true - property bool clangIndexing: false - property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader) property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader) property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader) @@ -39,67 +35,77 @@ QtcPlugin { cpp.defines: { var defines = base; + // The following defines are used to determine the clang include path for intrinsics. defines.push('CLANG_VERSION="' + llvmVersion + '"'); defines.push('CLANG_RESOURCE_DIR="' + llvmLibDir + '/clang/' + llvmVersion + '/include"'); - if (clangCompletion) - defines.push("CLANG_COMPLETION"); - if (clangHighlighting) - defines.push("CLANG_HIGHLIGHTING"); - if (clangIndexing) - defines.push("CLANG_INDEXING"); return defines; } - Group { - name: "Completion support" - condition: product.clangCompletion - files: [ - "activationsequencecontextprocessor.cpp", - "activationsequencecontextprocessor.h", - "activationsequenceprocessor.cpp", - "activationsequenceprocessor.h", - "clangassistproposal.cpp", - "clangassistproposal.h", - "clangassistproposalitem.cpp", - "clangassistproposalitem.h", - "clangassistproposalmodel.cpp", - "clangassistproposalmodel.h", - "clangcompletionassistinterface.cpp", - "clangcompletionassistinterface.h", - "clangcompletionassistprocessor.cpp", - "clangcompletionassistprocessor.h", - "clangcompletionassistprovider.cpp", - "clangcompletionassistprovider.h", - "clangfunctionhintmodel.cpp", - "clangfunctionhintmodel.h", - ] - } - - Group { - name: "Highlighting support" - condition: product.clangHighlighting - files: [ - "cppcreatemarkers.cpp", - "cppcreatemarkers.h", - "highlightingmarksreporter.cpp", - "highlightingmarksreporter.h", - ] - } - - Group { - name: "Indexing support" - condition: product.clangIndexing - files: [ - "clangindexer.cpp", - "clangindexer.h", - "index.cpp", - "index.h", - "indexer.cpp", - "indexer.h", - // "dependencygraph.h", - // "dependencygraph.cpp" - ] - } + files: [ + "activationsequencecontextprocessor.cpp", + "activationsequencecontextprocessor.h", + "activationsequenceprocessor.cpp", + "activationsequenceprocessor.h", + "clangassistproposal.cpp", + "clangassistproposal.h", + "clangassistproposalitem.cpp", + "clangassistproposalitem.h", + "clangassistproposalmodel.cpp", + "clangassistproposalmodel.h", + "clangbackendipcintegration.cpp", + "clangbackendipcintegration.h", + "clangcodemodelplugin.cpp", + "clangcodemodelplugin.h", + "clangcompletionassistinterface.cpp", + "clangcompletionassistinterface.h", + "clangcompletionassistprocessor.cpp", + "clangcompletionassistprocessor.h", + "clangcompletionassistprovider.cpp", + "clangcompletionassistprovider.h", + "clangcompletioncontextanalyzer.cpp", + "clangcompletioncontextanalyzer.h", + "clangdiagnosticfilter.cpp", + "clangdiagnosticfilter.h", + "clangdiagnosticmanager.cpp", + "clangdiagnosticmanager.h", + "clangeditordocumentparser.cpp", + "clangeditordocumentparser.h", + "clangeditordocumentprocessor.cpp", + "clangeditordocumentprocessor.h", + "clangfixitoperation.cpp", + "clangfixitoperation.h", + "clangfixitoperationsextractor.cpp", + "clangfixitoperationsextractor.h", + "clangfunctionhintmodel.cpp", + "clangfunctionhintmodel.h", + "clang_global.h", + "clangmodelmanagersupport.cpp", + "clangmodelmanagersupport.h", + "clangprojectsettings.cpp", + "clangprojectsettings.h", + "clangprojectsettingspropertiespage.cpp", + "clangprojectsettingspropertiespage.h", + "clangprojectsettingspropertiespage.ui", + "clangtextmark.cpp", + "clangtextmark.h", + "clangutils.cpp", + "clangutils.h", + "completionchunkstotextconverter.cpp", + "completionchunkstotextconverter.h", + "constants.h", + "highlightingmarksreporter.cpp", + "highlightingmarksreporter.h", + "pchinfo.cpp", + "pchinfo.h", + "pchmanager.cpp", + "pchmanager.h", + "raii/scopedclangoptions.cpp", + "raii/scopedclangoptions.h", + "unit.cpp", + "unit.h", + "unsavedfiledata.cpp", + "unsavedfiledata.h", + ] Group { name: "Tests" @@ -119,69 +125,4 @@ QtcPlugin { files: [ "*" ] excludeFiles: "clangtestdata.qrc" } - - files: [ - "clang_global.h", - "clangcompletioncontextanalyzer.cpp", - "clangcompletioncontextanalyzer.h", - "clangeditordocumentparser.cpp", - "clangeditordocumentparser.h", - "clangeditordocumentprocessor.cpp", - "clangeditordocumentprocessor.h", - "clangdiagnosticfilter.cpp", - "clangdiagnosticfilter.h", - "clangdiagnosticmanager.cpp", - "clangdiagnosticmanager.h", - "clangfixitoperation.cpp", - "clangfixitoperation.h", - "clangfixitoperationsextractor.cpp", - "clangfixitoperationsextractor.h", - "clangmodelmanagersupport.cpp", - "clangmodelmanagersupport.h", - "clangcodemodelplugin.cpp", - "clangcodemodelplugin.h", - "clangprojectsettings.cpp", - "clangprojectsettings.h", - "clangprojectsettingspropertiespage.cpp", - "clangprojectsettingspropertiespage.h", - "clangprojectsettingspropertiespage.ui", - "clangsymbol.cpp", - "clangsymbol.h", - "clangtextmark.cpp", - "clangtextmark.h", - "clangutils.cpp", - "clangutils.h", - "clangbackendipcintegration.cpp", - "clangbackendipcintegration.h", - "completionchunkstotextconverter.cpp", - "completionchunkstotextconverter.h", - "constants.h", - "cxprettyprinter.cpp", - "cxprettyprinter.h", - "cxraii.h", - "diagnostic.cpp", - "diagnostic.h", - "fastindexer.cpp", - "fastindexer.h", - "pchinfo.cpp", - "pchinfo.h", - "pchmanager.cpp", - "pchmanager.h", - "semanticmarker.cpp", - "semanticmarker.h", - "sourcelocation.cpp", - "sourcelocation.h", - "sourcemarker.cpp", - "sourcemarker.h", - "unit.cpp", - "unit.h", - "unsavedfiledata.cpp", - "unsavedfiledata.h", - "utils.cpp", - "utils.h", - "utils_p.cpp", - "utils_p.h", - "raii/scopedclangoptions.cpp", - "raii/scopedclangoptions.h", - ] } diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index bbf917d45dc..35229a68dc0 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -33,7 +33,6 @@ #include "clangprojectsettingspropertiespage.h" #include "constants.h" #include "pchmanager.h" -#include "utils.h" #ifdef WITH_TESTS # include "test/clangcodecompletion_test.h" @@ -47,10 +46,14 @@ #include +#include + namespace ClangCodeModel { namespace Internal { -static void initializeTextMarks() +namespace { + +void initializeTextMarks() { TextEditor::TextMark::setCategoryColor(Core::Id(Constants::CLANG_WARNING), Utils::Theme::ClangCodeModel_Warning_TextMarkColor); @@ -58,6 +61,25 @@ static void initializeTextMarks() Utils::Theme::ClangCodeModel_Error_TextMarkColor); } +static bool clangInitialised = false; +static QMutex initialisationMutex; + +void initializeClang() +{ + if (clangInitialised) + return; + + QMutexLocker locker(&initialisationMutex); + if (clangInitialised) + return; + + clang_toggleCrashRecovery(1); + clang_enableStackTraces(); + clangInitialised = true; +} + +} // anonymous namespace + bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage) { Q_UNUSED(arguments) @@ -73,18 +95,12 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err // Initialize Clang ClangCodeModel::Internal::initializeClang(); - // Set up Indexer - auto cppModelManager = CppTools::CppModelManager::instance(); -#ifdef CLANG_INDEXING - m_indexer.reset(new ClangIndexer); - cppModelManager->setIndexingSupport(m_indexer->indexingSupport()); -#endif // CLANG_INDEXING - // Set up PchManager PchManager *pchManager = new PchManager(this); ProjectExplorer::SessionManager *sessionManager = ProjectExplorer::SessionManager::instance(); connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject, pchManager, &PchManager::onAboutToRemoveProject); + auto cppModelManager = CppTools::CppModelManager::instance(); connect(cppModelManager, &CppTools::CppModelManager::projectPartsUpdated, pchManager, &PchManager::onProjectPartsUpdated); diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.h b/src/plugins/clangcodemodel/clangcodemodelplugin.h index 6a767d5b710..bba0f439c44 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.h +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.h @@ -33,14 +33,8 @@ #include "clangmodelmanagersupport.h" -#ifdef CLANG_INDEXING -# include "clangindexer.h" -#endif // CLANG_INDEXING - #include -#include - namespace ClangCodeModel { namespace Internal { @@ -55,9 +49,6 @@ public: private: ModelManagerSupportProviderClang m_modelManagerSupportProvider; -#ifdef CLANG_INDEXING - QScopedPointer m_indexer; -#endif // CLANG_INDEXING #ifdef WITH_TESTS QList createTestObjects() const; diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp index ec46846ccba..0c1f9dff1f9 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp @@ -94,7 +94,7 @@ IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const return m_ipcCommunicator; } -const UnsavedFiles &ClangCompletionAssistInterface::unsavedFiles() const +const Utils::UnsavedFiles &ClangCompletionAssistInterface::unsavedFiles() const { return m_unsavedFiles; } diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.h b/src/plugins/clangcodemodel/clangcompletionassistinterface.h index 21a9e8d4ab3..58f429d06e1 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.h +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.h @@ -33,7 +33,7 @@ #include "clangbackendipcintegration.h" #include "pchinfo.h" -#include "utils.h" +#include "clangutils.h" #include @@ -55,7 +55,7 @@ public: const CPlusPlus::LanguageFeatures &features); IpcCommunicator &ipcCommunicator() const; - const UnsavedFiles &unsavedFiles() const; + const Utils::UnsavedFiles &unsavedFiles() const; bool objcEnabled() const; const CppTools::ProjectPart::HeaderPaths &headerPaths() const; CPlusPlus::LanguageFeatures languageFeatures() const; @@ -65,7 +65,7 @@ public: private: IpcCommunicator &m_ipcCommunicator; - UnsavedFiles m_unsavedFiles; + Utils::UnsavedFiles m_unsavedFiles; QStringList m_options; CppTools::ProjectPart::HeaderPaths m_headerPaths; Internal::PchInfo::Ptr m_savedPchPointer; diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index e4f4b7e5bc2..a0c3514f156 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -34,8 +34,6 @@ #include "clangfixitoperationsextractor.h" #include "clangmodelmanagersupport.h" #include "clangutils.h" -#include "cppcreatemarkers.h" -#include "diagnostic.h" #include "highlightingmarksreporter.h" #include "pchinfo.h" diff --git a/src/plugins/clangcodemodel/clangindexer.cpp b/src/plugins/clangcodemodel/clangindexer.cpp deleted file mode 100644 index c8d171ba562..00000000000 --- a/src/plugins/clangcodemodel/clangindexer.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "clangindexer.h" -#include "clangutils.h" -#include "indexer.h" - -#include -#include -#include -#include - -#include - -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; - -ClangIndexingSupport::ClangIndexingSupport(ClangIndexer *indexer) - : m_indexer(indexer) -{ -} - -ClangIndexingSupport::~ClangIndexingSupport() -{ -} - -QFuture ClangIndexingSupport::refreshSourceFiles( - const QSet &sourceFiles, - CppTools::CppModelManager::ProgressNotificationMode mode) -{ - Q_UNUSED(mode); - - return m_indexer->refreshSourceFiles(sourceFiles); -} - -CppTools::SymbolSearcher *ClangIndexingSupport::createSymbolSearcher(CppTools::SymbolSearcher::Parameters parameters, QSet fileNames) -{ - Q_UNUSED(parameters); - Q_UNUSED(fileNames) -// return new ClangSymbolSearcher(m_indexer, parameters, fileNames); - return 0; -} - -ClangIndexer::ClangIndexer() - : QObject(0) - , m_indexingSupport(new ClangIndexingSupport(this)) - , m_isLoadingSession(false) - , m_clangIndexer(new Indexer(this)) -{ - connect(m_clangIndexer, SIGNAL(indexingStarted(QFuture,Internal::ProgressNotificationMode)), - this, SLOT(onIndexingStarted(QFuture,Internal::ProgressNotificationMode))); - - QObject *session = ProjectExplorer::SessionManager::instance(); - - connect(session, SIGNAL(aboutToLoadSession(QString)), - this, SLOT(onAboutToLoadSession(QString))); - connect(session, SIGNAL(sessionLoaded(QString)), - this, SLOT(onSessionLoaded(QString))); - connect(session, SIGNAL(aboutToSaveSession()), - this, SLOT(onAboutToSaveSession())); -} - -ClangIndexer::~ClangIndexer() -{ - m_clangIndexer->cancel(true); -} - -CppTools::CppIndexingSupport *ClangIndexer::indexingSupport() -{ - return m_indexingSupport.data(); -} - -QFuture ClangIndexer::refreshSourceFiles(const QSet &sourceFiles) -{ - typedef CppTools::ProjectPart ProjectPart; - CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); - - if (m_clangIndexer->isBusy()) - m_clangIndexer->cancel(true); - - foreach (const QString &file, sourceFiles) { - if (m_clangIndexer->isTracking(file)) - continue; // we get notified separately about open files. - const QList &parts = modelManager->projectPart(file); - if (!parts.isEmpty()) - m_clangIndexer->addFile(file, parts.at(0)); - else - m_clangIndexer->addFile(file, ProjectPart::Ptr()); - } - - if (!m_isLoadingSession) - m_clangIndexer->regenerate(); - - return QFuture(); -} - -void ClangIndexer::match(ClangSymbolSearcher *searcher) const -{ - m_clangIndexer->match(searcher); -} - -void ClangIndexer::onAboutToLoadSession(const QString &sessionName) -{ - m_isLoadingSession = true; - - if (sessionName == QLatin1String("default")) - return; - - QString path = Core::ICore::instance()->userResourcePath() + QLatin1String("/codemodel/"); - if (QFile::exists(path) || QDir().mkpath(path)) - m_clangIndexer->initialize(path + sessionName + QLatin1String(".qci")); -} - -void ClangIndexer::onSessionLoaded(QString) -{ - m_isLoadingSession = false; - m_clangIndexer->regenerate(); -} - -void ClangIndexer::onAboutToSaveSession() -{ - m_clangIndexer->finalize(); -} - -void ClangIndexer::indexNow(Unit::Ptr unit) -{ - typedef CppTools::ProjectPart ProjectPart; - - QString file = unit->fileName(); - CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance(); - const QList &parts = mmi->projectPart(file); - ProjectPart::Ptr part; - if (!parts.isEmpty()) - part = parts.at(0); - if (!m_isLoadingSession) - m_clangIndexer->runQuickIndexing(unit, part); -} - -void ClangIndexer::onIndexingStarted(QFuture indexingFuture) -{ - Core::ProgressManager::addTask(indexingFuture, QCoreApplication::translate( - "ClangCodeModel::Internal::ClangIndexer", - "Parsing C/C++/ObjC Files"), - "ClangCodeMode.Task.Indexing"); -} diff --git a/src/plugins/clangcodemodel/clangindexer.h b/src/plugins/clangcodemodel/clangindexer.h deleted file mode 100644 index 08899a4ff4e..00000000000 --- a/src/plugins/clangcodemodel/clangindexer.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANGINDEXER_H -#define CLANGINDEXER_H - -#include "fastindexer.h" - -#include - -#include - -namespace ClangCodeModel { - -class Indexer; - -namespace Internal { - -typedef CppTools::CppModelManager::ProgressNotificationMode ProgressNotificationMode; -class ClangIndexer; -class ClangSymbolSearcher; - -class ClangIndexingSupport: public CppTools::CppIndexingSupport -{ -public: - ClangIndexingSupport(ClangIndexer *indexer); - virtual ~ClangIndexingSupport(); - - virtual QFuture refreshSourceFiles( - const QSet &sourceFiles, - ProgressNotificationMode mode); - virtual CppTools::SymbolSearcher *createSymbolSearcher( - CppTools::SymbolSearcher::Parameters parameters, QSet fileNames); - -private: - ClangIndexer *m_indexer; -}; - -class ClangIndexer: public QObject, public FastIndexer -{ - Q_OBJECT - -public: - ClangIndexer(); - ~ClangIndexer(); - - CppTools::CppIndexingSupport *indexingSupport(); - - QFuture refreshSourceFiles(const QSet &sourceFiles); - - void match(ClangSymbolSearcher *searcher) const; - - void indexNow(Unit::Ptr unit); - -public slots: - void onAboutToLoadSession(const QString &sessionName); - void onSessionLoaded(QString); - void onAboutToSaveSession(); - -private slots: - void onIndexingStarted(QFuture indexingFuture); - -private: - QScopedPointer m_indexingSupport; - bool m_isLoadingSession; - Indexer *m_clangIndexer; -}; - -} // namespace Internal -} // namespace ClangCodeModel - -#endif // CLANGINDEXER_H diff --git a/src/plugins/clangcodemodel/clangsymbol.cpp b/src/plugins/clangcodemodel/clangsymbol.cpp deleted file mode 100644 index a4c9a024f46..00000000000 --- a/src/plugins/clangcodemodel/clangsymbol.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "clangsymbol.h" - -#include - -using namespace ClangCodeModel; - -Symbol::Symbol() - : m_kind(Unknown) -{} - -Symbol::Symbol(const QString &name, - const QString &qualification, - Kind type, - const SourceLocation &location) - : m_name(name) - , m_qualification(qualification) - , m_location(location) - , m_kind(type) -{} - -QIcon Symbol::iconForSymbol() const -{ - CPlusPlus::Icons icons; - switch (m_kind) { - case Enum: - return icons.iconForType(CPlusPlus::Icons::EnumIconType); - case Class: - return icons.iconForType(CPlusPlus::Icons::ClassIconType); - case Method: - case Function: - case Declaration: - case Constructor: - case Destructor: - return icons.iconForType(CPlusPlus::Icons::FuncPublicIconType); - default: - return icons.iconForType(CPlusPlus::Icons::UnknownIconType); - } -} - -namespace ClangCodeModel { - -QDataStream &operator<<(QDataStream &stream, const Symbol &symbol) -{ - stream << symbol.m_name - << symbol.m_qualification - << symbol.m_location.fileName() - << (quint32)symbol.m_location.line() - << (quint16)symbol.m_location.column() - << (quint32)symbol.m_location.offset() - << (qint8)symbol.m_kind; - - return stream; -} - -QDataStream &operator>>(QDataStream &stream, Symbol &symbol) -{ - QString fileName; - quint32 line; - quint16 column; - quint32 offset; - quint8 kind; - stream >> symbol.m_name - >> symbol.m_qualification - >> fileName - >> line - >> column - >> offset - >> kind; - symbol.m_location = SourceLocation(fileName, line, column, offset); - symbol.m_kind = Symbol::Kind(kind); - - return stream; -} - -bool operator==(const Symbol &a, const Symbol &b) -{ - return a.m_name == b.m_name - && a.m_qualification == b.m_qualification - && a.m_location == b.m_location - && a.m_kind == b.m_kind; -} - -bool operator!=(const Symbol &a, const Symbol &b) -{ - return !(a == b); -} - -} // ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangsymbol.h b/src/plugins/clangcodemodel/clangsymbol.h deleted file mode 100644 index 9dafa0cd7b1..00000000000 --- a/src/plugins/clangcodemodel/clangsymbol.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef INDEXEDSYMBOLINFO_H -#define INDEXEDSYMBOLINFO_H - -#include "sourcelocation.h" - -#include -#include -#include - -namespace ClangCodeModel { - -class Symbol -{ -public: - enum Kind { - Enum, - Class, - Method, // A member-function. - Function, // A free-function (global or within a namespace). - Declaration, - Constructor, - Destructor, - Unknown - }; - - Symbol(); - Symbol(const QString &name, - const QString &qualification, - Kind type, - const SourceLocation &location); - - QString m_name; - QString m_qualification; - SourceLocation m_location; - Kind m_kind; - - QIcon iconForSymbol() const; -}; - -QDataStream &operator<<(QDataStream &stream, const Symbol &symbol); -QDataStream &operator>>(QDataStream &stream, Symbol &symbol); - -bool operator==(const Symbol &a, const Symbol &b); -bool operator!=(const Symbol &a, const Symbol &b); - -} // Clang - -#endif // INDEXEDSYMBOLINFO_H diff --git a/src/plugins/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h index 11d8e9db115..b8e524e749b 100644 --- a/src/plugins/clangcodemodel/clangutils.h +++ b/src/plugins/clangcodemodel/clangutils.h @@ -32,7 +32,6 @@ #define CPPTOOLS_CLANGUTILS_H #include "clang_global.h" -#include "utils.h" #include @@ -41,11 +40,12 @@ namespace ClangCodeModel { namespace Utils { +typedef QMap UnsavedFiles; + Q_DECLARE_LOGGING_CATEGORY(verboseRunLog) -ClangCodeModel::Internal::UnsavedFiles createUnsavedFiles( - const CppTools::WorkingCopy &workingCopy, - const ::Utils::FileNameList &modifiedFiles); +UnsavedFiles createUnsavedFiles(const CppTools::WorkingCopy &workingCopy, + const ::Utils::FileNameList &modifiedFiles); QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart, CppTools::ProjectFile::Kind fileKind); diff --git a/src/plugins/clangcodemodel/constants.h b/src/plugins/clangcodemodel/constants.h index 7b8a4e829c4..40192c06400 100644 --- a/src/plugins/clangcodemodel/constants.h +++ b/src/plugins/clangcodemodel/constants.h @@ -31,35 +31,14 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -#include - namespace ClangCodeModel { namespace Constants { -static const QLatin1Char kLParen('('); -static const QLatin1Char kRParen(')'); -static const QLatin1Char kLBrace('{'); -static const QLatin1Char kRBrace('}'); -static const QLatin1Char kLBracket('['); -static const QLatin1Char kRBracket(']'); -static const QLatin1Char kLABracket('<'); -static const QLatin1Char kRABracket('>'); -static const QLatin1Char kSemiColon(';'); -static const QLatin1Char kPound('#'); -static const QLatin1Char kColon(':'); -static const QLatin1Char kExclamation('!'); -static const QLatin1Char kSpace(' '); -static const QLatin1Char kSlash('/'); -static const QLatin1Char kStar('*'); -static const QLatin1Char kDoubleQuote('"'); -static const QLatin1Char kNewLine('\n'); -static const QLatin1Char kHorizontalTab('\t'); - const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeModel.ClangCodeModel"; const char CLANG_ERROR[] = "Clang.Error"; const char CLANG_WARNING[] = "Clang.Warning"; -} -} +} // namespace Constants +} // namespace ClangCodeModel #endif // CONSTANTS_H diff --git a/src/plugins/clangcodemodel/cppcreatemarkers.cpp b/src/plugins/clangcodemodel/cppcreatemarkers.cpp deleted file mode 100644 index a7518b355c3..00000000000 --- a/src/plugins/clangcodemodel/cppcreatemarkers.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "clangutils.h" -#include "cppcreatemarkers.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include - -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; -using namespace CppTools; - -static Q_LOGGING_CATEGORY(log, "qtc.clangcodemodel.createmarkers") - -CreateMarkers *CreateMarkers::create(SemanticMarker::Ptr semanticMarker, - const QString &fileName, - unsigned firstLine, unsigned lastLine) -{ - if (semanticMarker.isNull()) - return 0; - else - return new CreateMarkers(semanticMarker, fileName, firstLine, lastLine); -} - -CreateMarkers::CreateMarkers(SemanticMarker::Ptr semanticMarker, - const QString &fileName, - unsigned firstLine, unsigned lastLine) - : m_marker(semanticMarker) - , m_fileName(fileName) - , m_firstLine(firstLine) - , m_lastLine(lastLine) -{ - Q_ASSERT(!semanticMarker.isNull()); - - m_flushRequested = false; - m_flushLine = 0; -} - -CreateMarkers::~CreateMarkers() -{ } - -void CreateMarkers::run() -{ - QMutexLocker lock(m_marker->mutex()); - - ::Utils::ExecuteOnDestruction reportFinishedOnDestruction([this]() { reportFinished(); }); - - if (isCanceled()) - return; - - qCDebug(log) << "Creating markers from" << m_firstLine << "to" << m_lastLine - << "of" << m_fileName; - QTime t; t.start(); - - m_usages.clear(); - - if (isCanceled()) - return; - - const QList markers - = m_marker->sourceMarkersInRange(m_firstLine, m_lastLine); - foreach (const ClangCodeModel::SourceMarker &m, markers) - addUse(SourceMarker(m.location().line(), m.location().column(), m.length(), m.kind())); - - if (isCanceled()) - return; - - flush(); - - qCDebug(log) << "Creating markers took" << t.elapsed() << "ms in total."; -} - -void CreateMarkers::addUse(const SourceMarker &marker) -{ -// if (! enclosingFunctionDefinition()) { - if (m_usages.size() >= 100) { - if (m_flushRequested && marker.line != m_flushLine) - flush(); - else if (! m_flushRequested) { - m_flushRequested = true; - m_flushLine = marker.line; - } - } -// } - - m_usages.append(marker); -} - -void CreateMarkers::flush() -{ - m_flushRequested = false; - m_flushLine = 0; - - if (m_usages.isEmpty()) - return; - - reportResults(m_usages); - m_usages.clear(); -} diff --git a/src/plugins/clangcodemodel/cppcreatemarkers.h b/src/plugins/clangcodemodel/cppcreatemarkers.h deleted file mode 100644 index 3210e1fc966..00000000000 --- a/src/plugins/clangcodemodel/cppcreatemarkers.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CPPCREATEMARKERS_H -#define CPPCREATEMARKERS_H - -#include "fastindexer.h" -#include "sourcemarker.h" -#include "semanticmarker.h" -#include "pchinfo.h" - -#include - -#include -#include - -namespace ClangCodeModel { - -class CreateMarkers: - public QObject, - public QRunnable, - public QFutureInterface -{ - Q_OBJECT - Q_DISABLE_COPY(CreateMarkers) - -public: - virtual ~CreateMarkers(); - - virtual void run(); - - typedef TextEditor::HighlightingResult SourceMarker; - - typedef QFuture Future; - - Future start() - { - this->setRunnable(this); - this->reportStarted(); - Future future = this->future(); - QThreadPool::globalInstance()->start(this, QThread::LowestPriority); - return future; - } - - static CreateMarkers *create(ClangCodeModel::SemanticMarker::Ptr semanticMarker, - const QString &fileName, unsigned firstLine, unsigned lastLine); - - void addUse(const SourceMarker &marker); - void flush(); - -protected: - CreateMarkers(ClangCodeModel::SemanticMarker::Ptr semanticMarker, - const QString &fileName, unsigned firstLine, unsigned lastLine); - -private: - ClangCodeModel::SemanticMarker::Ptr m_marker; - QString m_fileName; - unsigned m_firstLine; - unsigned m_lastLine; - QVector m_usages; - bool m_flushRequested; - unsigned m_flushLine; -}; - -} // namespace ClangCodeModel - -#endif // CPPCREATEMARKERS_H diff --git a/src/plugins/clangcodemodel/cxprettyprinter.cpp b/src/plugins/clangcodemodel/cxprettyprinter.cpp deleted file mode 100644 index 0d57f011743..00000000000 --- a/src/plugins/clangcodemodel/cxprettyprinter.cpp +++ /dev/null @@ -1,551 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "cxprettyprinter.h" -#include "utils_p.h" -#include "cxraii.h" -#include - -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; - -CXPrettyPrinter::CXPrettyPrinter() - : m_indent(0) -{ -} - -QString CXPrettyPrinter::toString(CXCompletionChunkKind kind) const -{ - switch (kind) { - case CXCompletionChunk_Optional: - return QLatin1String("Optional"); - case CXCompletionChunk_TypedText: - return QLatin1String("TypedText"); - case CXCompletionChunk_Text: - return QLatin1String("Text"); - case CXCompletionChunk_Placeholder: - return QLatin1String("Placeholder"); - case CXCompletionChunk_Informative: - return QLatin1String("Informative"); - case CXCompletionChunk_CurrentParameter: - return QLatin1String("CurrentParameter"); - case CXCompletionChunk_LeftParen: - return QLatin1String("LeftParen"); - case CXCompletionChunk_RightParen: - return QLatin1String("RightParen"); - case CXCompletionChunk_LeftBracket: - return QLatin1String("LeftBracket"); - case CXCompletionChunk_RightBracket: - return QLatin1String("RightBracket"); - case CXCompletionChunk_LeftBrace: - return QLatin1String("LeftBrace"); - case CXCompletionChunk_RightBrace: - return QLatin1String("RightBrace"); - case CXCompletionChunk_LeftAngle: - return QLatin1String("LeftAngle"); - case CXCompletionChunk_RightAngle: - return QLatin1String("RightAngle"); - case CXCompletionChunk_Comma: - return QLatin1String("Comma"); - case CXCompletionChunk_ResultType: - return QLatin1String("ResultType"); - case CXCompletionChunk_Colon: - return QLatin1String("Colon"); - case CXCompletionChunk_SemiColon: - return QLatin1String("SemiColon"); - case CXCompletionChunk_Equal: - return QLatin1String("Equal"); - case CXCompletionChunk_HorizontalSpace: - return QLatin1String("HorizontalSpace"); - case CXCompletionChunk_VerticalSpace: - return QLatin1String("VerticalSpace"); - default: - return QLatin1String(""); - } -} - -QString CXPrettyPrinter::toString(CXAvailabilityKind kind) const -{ - switch (kind) { - case CXAvailability_Available: - return QLatin1String("Available"); - case CXAvailability_Deprecated: - return QLatin1String("Deprecated"); - case CXAvailability_NotAccessible: - return QLatin1String("NotAccessible"); - case CXAvailability_NotAvailable: - return QLatin1String("NotAvailable"); - default: - return QLatin1String(""); - } -} - -QString CXPrettyPrinter::toString(CXCursorKind kind) const -{ - return getQString(clang_getCursorKindSpelling(kind)); -} - -QString CXPrettyPrinter::toString(CXDiagnosticSeverity severity) const -{ - switch (severity) - { - case CXDiagnostic_Ignored: - return QLatin1String("Ignored"); - case CXDiagnostic_Note: - return QLatin1String("Note"); - case CXDiagnostic_Warning: - return QLatin1String("Warning"); - case CXDiagnostic_Error: - return QLatin1String("Error"); - case CXDiagnostic_Fatal: - return QLatin1String("Fatal"); - default: - return QLatin1String(""); - } -} - -QString CXPrettyPrinter::jsonForCompletionMeta(CXCodeCompleteResults *results) -{ - QString json; - m_printed.swap(json); - m_indent = 0; - - m_printed += QLatin1String("CXCodeCompleteResults {"); - m_indent += 4; - - CXCursorKind containerKind = clang_codeCompleteGetContainerKind(results, NULL); - writeLineEnd(); - m_printed += QLatin1String("'container CursorKind': "); - m_printed += toString(containerKind); - m_printed += QLatin1Char(','); - - QString containerUSR(Internal::getQString(clang_codeCompleteGetContainerUSR(results))); - if (!containerUSR.isEmpty()) { - writeLineEnd(); - m_printed += QLatin1String("'container USR': "); - m_printed += containerUSR; - m_printed += QLatin1Char(','); - } - - QString objCSelector(Internal::getQString(clang_codeCompleteGetObjCSelector(results))); - if (!objCSelector.isEmpty()) { - writeLineEnd(); - m_printed += QLatin1String("'Objective-C selector': "); - m_printed += objCSelector; - m_printed += QLatin1Char(','); - } - - writeLineEnd(); - m_printed += QLatin1String("'contexts': ["); - m_indent += 4; - writeCompletionContexts(results); - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char(']'); - - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char('}'); - - m_printed.swap(json); - return json; -} - -QString CXPrettyPrinter::jsonForCompletionString(const CXCompletionString &string) -{ - QString json; - m_printed.swap(json); - m_indent = 0; - - m_printed += QLatin1String("CXCompletionString: "); - writeCompletionStringJson(string); - - m_printed.swap(json); - return json; -} - -QString CXPrettyPrinter::jsonForCompletion(const CXCompletionResult &result) -{ - QString json; - m_printed.swap(json); - m_indent = 4; - - m_printed += QLatin1String("CXCompletionResult: {\n" - " CompletionString: "); - writeCompletionStringJson(result.CompletionString); - m_printed += QLatin1Char('\n'); - - m_printed += QLatin1String(" CursorKind: "); - m_printed += toString(result.CursorKind); - m_printed += QLatin1String(";\n}"); - - m_printed.swap(json); - return json; -} - -/** - * @brief CXPrettyPrinter::jsonForDiagnsotic - * @param diagnostic - * @return - * - * List of used clang-c API calls: - * CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D); - * CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic); - * CXString clang_getDiagnosticOption(CXDiagnostic Diag, - * CXString *Disable); - * unsigned clang_getDiagnosticCategory(CXDiagnostic); - * CXString clang_getDiagnosticCategoryText(CXDiagnostic); - * unsigned clang_getDiagnosticNumRanges(CXDiagnostic); - * CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic, - * unsigned Range); - * unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic); - * CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, - * unsigned FixIt, - * CXSourceRange *ReplacementRange); - */ -QString CXPrettyPrinter::jsonForDiagnsotic(const CXDiagnostic &diagnostic) -{ - QString json; - m_printed.swap(json); - m_indent = 0; - - m_printed += QLatin1String("CXDiagnostic: "); - writeDiagnosticJson(diagnostic); - - m_printed.swap(json); - return json; -} - -void CXPrettyPrinter::writeCompletionContexts(CXCodeCompleteResults *results) -{ - quint64 contexts = clang_codeCompleteGetContexts(results); - QStringList lines; - - if (contexts & CXCompletionContext_AnyType) - lines << QLatin1String("'any type'"); - if (contexts & CXCompletionContext_AnyValue) - lines << QLatin1String("'any value'"); - if (contexts & CXCompletionContext_ObjCObjectValue) - lines << QLatin1String("'Objective-C object'"); - if (contexts & CXCompletionContext_ObjCSelectorValue) - lines << QLatin1String("'Objective-C selector'"); - if (contexts & CXCompletionContext_CXXClassTypeValue) - lines << QLatin1String("'C++ class'"); - if (contexts & CXCompletionContext_DotMemberAccess) - lines << QLatin1String("'. member access'"); - if (contexts & CXCompletionContext_ArrowMemberAccess) - lines << QLatin1String("'-> member access'"); - if (contexts & CXCompletionContext_ObjCPropertyAccess) - lines << QLatin1String("'. Objective-C property access'"); - if (contexts & CXCompletionContext_EnumTag) - lines << QLatin1String("'enum tag'"); - if (contexts & CXCompletionContext_UnionTag) - lines << QLatin1String("'union tag'"); - if (contexts & CXCompletionContext_StructTag) - lines << QLatin1String("'struct tag'"); - if (contexts & CXCompletionContext_ClassTag) - lines << QLatin1String("'C++ class tag'"); - if (contexts & CXCompletionContext_Namespace) - lines << QLatin1String("'namespace tag'"); - if (contexts & CXCompletionContext_NestedNameSpecifier) - lines << QLatin1String("'C++ nested name specifier'"); - if (contexts & CXCompletionContext_ObjCInterface) - lines << QLatin1String("'Objective-C interface'"); - if (contexts & CXCompletionContext_ObjCProtocol) - lines << QLatin1String("'Objective-C protocol'"); - if (contexts & CXCompletionContext_ObjCCategory) - lines << QLatin1String("'Objective-C category'"); - if (contexts & CXCompletionContext_ObjCInstanceMessage) - lines << QLatin1String("'Objective-C instance message'"); - if (contexts & CXCompletionContext_ObjCClassMessage) - lines << QLatin1String("'Objective-C class message'"); - if (contexts & CXCompletionContext_ObjCSelectorName) - lines << QLatin1String("'Objective-C selector name'"); - if (contexts & CXCompletionContext_MacroName) - lines << QLatin1String("'macro name'"); - if (contexts & CXCompletionContext_NaturalLanguage) - lines << QLatin1String("'natural language'"); - - foreach (const QString &line, lines) { - writeLineEnd(); - m_printed += line + QLatin1Char(','); - } -} - -void CXPrettyPrinter::writeCompletionStringJson(const CXCompletionString &string) -{ - m_printed += QLatin1Char('{'); - writeLineEnd(); - - // availability - m_printed += QLatin1String("availability: "); - m_printed += toString(clang_getCompletionAvailability(string)); - m_printed += QLatin1Char(';'); - writeLineEnd(); - - // priority - m_printed += QLatin1String("priority: "); - m_printed += QString::number(clang_getCompletionPriority(string)); - m_printed += QLatin1Char(';'); - writeLineEnd(); - - // parent - m_printed += QLatin1String("parent: \'"); - m_printed += getQString(clang_getCompletionParent(string, NULL)); - m_printed += QLatin1String("\';"); - writeLineEnd(); - - // chunks - m_printed += QLatin1String("chunks: ["); - m_indent += 4; - unsigned numChunks = clang_getNumCompletionChunks(string); - for (unsigned i = 0; i < numChunks; ++i) { - writeLineEnd(); - writeCompletionChunkJson(string, i); - } - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char(']'); - writeLineEnd(); - - // annotation - m_printed += QLatin1String("annotations: ["); - m_indent += 4; - unsigned numAnns = clang_getCompletionNumAnnotations(string); - for (unsigned i = 0; i < numAnns; ++i) { - writeLineEnd(); - writeCompletionAnnotationJson(string, i); - } - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char(']'); - writeLineEnd(); - - m_printed += QLatin1Char('}'); -} - -void CXPrettyPrinter::writeCompletionChunkJson(const CXCompletionString &string, unsigned i) -{ - QString text = getQString(clang_getCompletionChunkText(string, i)); - QString kind = toString(clang_getCompletionChunkKind(string, i)); - CXCompletionString optional = clang_getCompletionChunkCompletionString(string, i); - - m_printed += kind; - m_printed += QLatin1String(": "); - if (!text.isEmpty()) { - m_printed += QLatin1Char('\''); - m_printed += text; - m_printed += QLatin1Char('\''); - } - if (optional != NULL) { - if (!text.isEmpty()) - m_printed += QLatin1String(", "); - m_indent += 4; - writeCompletionStringJson(optional); - m_indent -= 4; - } -} - -void CXPrettyPrinter::writeCompletionAnnotationJson(const CXCompletionString &string, unsigned i) -{ - m_printed += QLatin1Char('\''); - m_printed += getQString(clang_getCompletionAnnotation(string, i)); - m_printed += QLatin1Char('\''); -} - -void CXPrettyPrinter::writeDiagnosticJson(const CXDiagnostic &diag) -{ - m_printed += QLatin1Char('{'); - m_indent += 4; - writeLineEnd(); - - // message - m_printed += QLatin1Char('\''); - m_printed += getQString(clang_formatDiagnostic(diag, /*options*/ 0)); - m_printed += QLatin1Char('\''); - writeLineEnd(); - - // severity - m_printed += QLatin1String("severity: "); - m_printed += toString(clang_getDiagnosticSeverity(diag)); - writeLineEnd(); - - // location - m_printed += QLatin1String("location: "); - writeLocationJson(clang_getDiagnosticLocation(diag)); - writeLineEnd(); - - // fix-its - unsigned numFixIts = clang_getDiagnosticNumFixIts(diag); - if (numFixIts > 0) { - m_printed += QLatin1String("FixIts: ["); - writeLineEnd(); - for (unsigned i = 0; i < numFixIts; ++i) { - writeFixItJson(diag, i); - writeLineEnd(); - } - m_printed += QLatin1Char(']'); - writeLineEnd(); - } - - // clang CLI options - CXString cxDisabler; - QString enabler = getQString(clang_getDiagnosticOption(diag, &cxDisabler)); - QString disabler = getQString(cxDisabler); - if (!enabler.isEmpty()) { - m_printed += QLatin1String("enabledBy: \'"); - m_printed += enabler; - m_printed += QLatin1String("';"); - writeLineEnd(); - } - if (!disabler.isEmpty()) { - m_printed += QLatin1String("disabledBy: \'"); - m_printed += disabler; - m_printed += QLatin1String("';"); - writeLineEnd(); - } - - // diagnostic category - m_printed += QLatin1String("category: \'"); - m_printed += getQString(clang_getDiagnosticCategoryText(diag)); - m_printed += QLatin1String("';"); - - // ranges - unsigned numRanges = clang_getDiagnosticNumRanges(diag); - if (numRanges > 0) { - writeLineEnd(); - m_printed += QLatin1String("ranges: ["); - m_indent += 4; - for (unsigned i = 0; i < numRanges; ++i) { - writeLineEnd(); - writeRangeJson(clang_getDiagnosticRange(diag, i)); - } - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char(']'); - } - - // children - CXDiagnosticSet set(clang_getChildDiagnostics(diag)); - unsigned numChildren = clang_getNumDiagnosticsInSet(set); - if (numChildren > 0) { - writeLineEnd(); - m_printed += QLatin1String("children: ["); - m_indent += 4; - for (unsigned i = 0; i < numChildren; ++i) { - writeLineEnd(); - ScopedCXDiagnostic child(clang_getDiagnosticInSet(set, i)); - writeDiagnosticJson(child); - } - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char(']'); - } - - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char('}'); -} - -void CXPrettyPrinter::writeFixItJson(const CXDiagnostic &diag, unsigned i) -{ - CXSourceRange range; // half-open range [a, b) - QString text = getQString(clang_getDiagnosticFixIt(diag, i, &range)); - - m_printed += QLatin1String("{ newText: "); - m_printed += QLatin1String("\'"); - m_printed += text; - m_printed += QLatin1String("\', range: "); - writeRangeJson(range); - m_printed += QLatin1Char('}'); -} - -void CXPrettyPrinter::writeRangeJson(const CXSourceRange &range) -{ - SourceLocation start = getSpellingLocation(clang_getRangeStart(range)); - SourceLocation end = getSpellingLocation(clang_getRangeEnd(range)); - - m_printed += QLatin1Char('{'); - m_indent += 4; - writeLineEnd(); - - m_printed += QLatin1String("file: \'"); - m_printed += start.fileName(); - m_printed += QLatin1String("\',"); - writeLineEnd(); - - m_printed += QLatin1String("from: {"); - m_printed += QString::number(start.line()); - m_printed += QLatin1String(", "); - m_printed += QString::number(start.column()); - m_printed += QLatin1String("},"); - - m_printed += QLatin1String("to: {"); - m_printed += QString::number(end.line()); - m_printed += QLatin1String(", "); - m_printed += QString::number(end.column()); - m_printed += QLatin1Char('}'); - - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char('}'); -} - -void CXPrettyPrinter::writeLocationJson(const CXSourceLocation &location) -{ - SourceLocation loc = getSpellingLocation(location); - m_printed += QLatin1Char('{'); - m_indent += 4; - writeLineEnd(); - - m_printed += QLatin1String("file: \'"); - m_printed += loc.fileName(); - m_printed += QLatin1String("\',"); - writeLineEnd(); - - m_printed += QLatin1String("line: "); - m_printed += QString::number(loc.line()); - m_printed += QLatin1Char(','); - writeLineEnd(); - - m_printed += QLatin1String("column: "); - m_printed += QString::number(loc.column()); - - m_indent -= 4; - writeLineEnd(); - m_printed += QLatin1Char('}'); -} - -void CXPrettyPrinter::writeLineEnd() -{ - m_printed += QLatin1Char('\n'); - for (int i = 0; i < m_indent; ++i) - m_printed += QLatin1Char(' '); -} diff --git a/src/plugins/clangcodemodel/cxprettyprinter.h b/src/plugins/clangcodemodel/cxprettyprinter.h deleted file mode 100644 index 40f61be9f92..00000000000 --- a/src/plugins/clangcodemodel/cxprettyprinter.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CXPRETTYPRINTER_H -#define CXPRETTYPRINTER_H - -#include -#include - -namespace ClangCodeModel { -namespace Internal { - -class CXPrettyPrinter -{ -public: - CXPrettyPrinter(); - - QString toString(CXCompletionChunkKind kind) const; - QString toString(CXAvailabilityKind kind) const; - QString toString(CXCursorKind kind) const; - QString toString(CXDiagnosticSeverity severity) const; - - QString jsonForCompletionMeta(CXCodeCompleteResults *results); - QString jsonForCompletionString(const CXCompletionString &string); - QString jsonForCompletion(const CXCompletionResult &result); - QString jsonForDiagnsotic(const CXDiagnostic &diagnostic); - -private: - int m_indent; - QString m_printed; - - void writeCompletionContexts(CXCodeCompleteResults *results); - void writeCompletionStringJson(const CXCompletionString &string); - void writeCompletionChunkJson(const CXCompletionString &string, unsigned i); - void writeCompletionAnnotationJson(const CXCompletionString &string, unsigned i); - - void writeDiagnosticJson(const CXDiagnostic &diag); - void writeFixItJson(const CXDiagnostic &diag, unsigned i); - - void writeRangeJson(const CXSourceRange &range); - void writeLocationJson(const CXSourceLocation &location); - - void writeLineEnd(); -}; - -} // namespace Internal -} // namespace ClangCodeModel - -#endif // CXPRETTYPRINTER_H diff --git a/src/plugins/clangcodemodel/cxraii.h b/src/plugins/clangcodemodel/cxraii.h deleted file mode 100644 index f21bb454fd0..00000000000 --- a/src/plugins/clangcodemodel/cxraii.h +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CXRAII_H -#define CXRAII_H - -#include - -// Simple RAII types for their CX correspondings - -namespace ClangCodeModel { -namespace Internal { - -template -struct ScopedCXType -{ -protected: - typedef void (*DisposeFunction)(CXType_T); - - ScopedCXType(DisposeFunction f) - : m_cx(0), m_disposeFunction(f) - {} - ScopedCXType(const CXType_T &cx, DisposeFunction f) - : m_cx(cx) , m_disposeFunction(f) - {} - -public: - ~ScopedCXType() - { - dispose(); - } - - operator CXType_T() const { return m_cx; } - bool operator!() const { return !m_cx; } - bool isNull() const { return !m_cx; } - void reset(const CXType_T &cx) - { - dispose(); - m_cx = cx; - } - -private: - ScopedCXType(const ScopedCXType &); - const ScopedCXType &operator=(const ScopedCXType &); - - void dispose() - { - if (m_cx) - m_disposeFunction(m_cx); - } - - CXType_T m_cx; - DisposeFunction m_disposeFunction; -}; - -struct ScopedCXIndex : ScopedCXType -{ - ScopedCXIndex() - : ScopedCXType(&clang_disposeIndex) - {} - ScopedCXIndex(const CXIndex &index) - : ScopedCXType(index, &clang_disposeIndex) - {} -}; - -struct ScopedCXTranslationUnit : ScopedCXType -{ - ScopedCXTranslationUnit() - : ScopedCXType(&clang_disposeTranslationUnit) - {} - ScopedCXTranslationUnit(const CXTranslationUnit &unit) - : ScopedCXType(unit, &clang_disposeTranslationUnit) - {} -}; - -struct ScopedCXDiagnostic : ScopedCXType -{ - ScopedCXDiagnostic() - : ScopedCXType(&clang_disposeDiagnostic) - {} - ScopedCXDiagnostic(const CXDiagnostic &diagnostic) - : ScopedCXType(diagnostic, &clang_disposeDiagnostic) - {} -}; - -struct ScopedCXDiagnosticSet : ScopedCXType -{ - ScopedCXDiagnosticSet() - : ScopedCXType(&clang_disposeDiagnosticSet) - {} - ScopedCXDiagnosticSet(const CXDiagnostic &diagnostic) - : ScopedCXType(diagnostic, &clang_disposeDiagnosticSet) - {} -}; - -struct ScopedCXCodeCompleteResults : ScopedCXType -{ - ScopedCXCodeCompleteResults() - : ScopedCXType(&clang_disposeCodeCompleteResults) - {} - ScopedCXCodeCompleteResults(CXCodeCompleteResults *results) - : ScopedCXType(results, &clang_disposeCodeCompleteResults) - {} - - unsigned size() const - { - return static_cast(*this)->NumResults; - } - - const CXCompletionResult &completionAt(unsigned i) - { - return static_cast(*this)->Results[i]; - } -}; - -} // Internal -} // ClangCodeModel - -#endif // CXRAII_H diff --git a/src/plugins/clangcodemodel/dependencygraph.cpp b/src/plugins/clangcodemodel/dependencygraph.cpp deleted file mode 100644 index 6d33ab7b5b0..00000000000 --- a/src/plugins/clangcodemodel/dependencygraph.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "dependencygraph.h" - -#include - -using namespace ClangCodeModel; -using namespace Internal; - -DependencyGraph::DependencyGraph() -{ - m_includeTracker.setResolutionMode(IncludeTracker::EveryMatchResolution); -} - -DependencyGraph::~DependencyGraph() -{ - discard(); -} - -void DependencyGraph::cancel() -{ - if (m_computeWatcher.isRunning()) { - m_computeWatcher.cancel(); - m_computeWatcher.waitForFinished(); - } -} - -void DependencyGraph::addFile(const QString &fileName, const QStringList &compilationOptions) -{ - cancel(); - - m_files.append(qMakePair(fileName, compilationOptions)); -} - -QFuture DependencyGraph::compute() -{ - QFuture future = QtConcurrent::run(this, &DependencyGraph::computeCore); - m_computeWatcher.setFuture(future); - return future; -} - -void DependencyGraph::computeCore() -{ - for (int i = 0; i < m_files.size(); ++i) { - if (m_computeWatcher.isCanceled()) - break; - - const QPair &p = m_files.at(i); - const QString ¤tFile = p.first; - const QStringList &options = p.second; - const QPair &v = findVertex(currentFile); - if (!v.first) - processIncludes(insertVertex(currentFile), options); - } - - emit dependencyGraphAvailable(); -} - -void DependencyGraph::processIncludes(NodeRefSetIt currentIt, - const QStringList &compilationOptions) -{ - const QString ¤tFile = currentIt.key(); - const QStringList &includes = m_includeTracker.directIncludes(currentFile, compilationOptions); - foreach (const QString &include, includes) { - if (m_computeWatcher.isCanceled()) - return; - - QPair v = findVertex(include); - if (!v.first) { - v.second = insertVertex(include); - processIncludes(v.second, compilationOptions); - } - insertEdge(currentIt, v.second); - } -} - -namespace { - -struct SimpleVisitor -{ - bool acceptFile(const QString &fileName) - { - m_allFiles.append(fileName); - return false; - } - - QStringList m_allFiles; -}; - -} - -QStringList DependencyGraph::collectDependencies(const QString &referenceFile, - DependencyRole role) const -{ - SimpleVisitor visitor; - collectDependencies(referenceFile, role, &visitor); - - return visitor.m_allFiles; -} - -bool DependencyGraph::hasDependency(const QString &referenceFile, DependencyRole role) const -{ - QPair v = findVertex(referenceFile); - if (!v.first) - return false; - - NodeListIt nodeIt = v.second.value(); - - if (role == FilesDirectlyIncludedBy || role == FilesIncludedBy) - return nodeIt->m_out != 0; - - return nodeIt->m_in != 0; -} - -void DependencyGraph::discard() -{ - cancel(); - - for (NodeListIt it = m_nodes.begin(); it != m_nodes.end(); ++it) { - deleteAdjacencies(it->m_out); - deleteAdjacencies(it->m_in); - } - m_nodes.clear(); - m_nodesRefs.clear(); - m_files.clear(); -} - - -DependencyGraph::Node::Node(const QString &fileName) - : m_fileName(fileName) - , m_out(0) - , m_in(0) -{} - -DependencyGraph::AdjacencyNode::AdjacencyNode(NodeListIt it) - : m_next(0) - , m_nodeIt(it) -{} - -QPair DependencyGraph::findVertex(const QString &s) const -{ - bool found = false; - NodeRefSetIt it = const_cast(m_nodesRefs).find(s); - if (it != m_nodesRefs.end()) - found = true; - return qMakePair(found, it); -} - -DependencyGraph::NodeRefSetIt DependencyGraph::insertVertex(const QString &s) -{ - Q_ASSERT(m_nodesRefs.find(s) == m_nodesRefs.end()); - - m_nodes.append(Node(s)); - return m_nodesRefs.insert(s, m_nodes.end() - 1); -} - -void DependencyGraph::insertEdge(DependencyGraph::NodeRefSetIt fromIt, - DependencyGraph::NodeRefSetIt toIt) -{ - NodeListIt nodeFromIt = fromIt.value(); - NodeListIt nodeToIt = toIt.value(); - - createAdjacency(&nodeFromIt->m_out, new AdjacencyNode(nodeToIt)); - createAdjacency(&nodeToIt->m_in, new AdjacencyNode(nodeFromIt)); -} - -void DependencyGraph::deleteAdjacencies(AdjacencyNode *node) -{ - while (node) { - AdjacencyNode *next = node->m_next; - delete node; - node = next; - } -} - -void DependencyGraph::createAdjacency(AdjacencyNode **node, AdjacencyNode *newNode) -{ - if (*node) - newNode->m_next = *node; - *node = newNode; -} diff --git a/src/plugins/clangcodemodel/dependencygraph.h b/src/plugins/clangcodemodel/dependencygraph.h deleted file mode 100644 index 26bd75538ab..00000000000 --- a/src/plugins/clangcodemodel/dependencygraph.h +++ /dev/null @@ -1,236 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef DEPENDENCYGRAPH_H -#define DEPENDENCYGRAPH_H - -#include "includetracker.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ClangCodeModel { -namespace Internal { - -class DependencyGraph : public QObject -{ - Q_OBJECT - Q_DISABLE_COPY(DependencyGraph) - -public: - DependencyGraph(); - ~DependencyGraph(); - - void addFile(const QString &fileName, const QStringList &compilationOptions); - - QFuture compute(); - - enum DependencyRole - { - FilesDirectlyIncludedBy, // Only direct inclusions - FilesIncludedBy, // Both direct and indirect inclusions - FilesWhichDirectlyInclude, // This one is directly included from... - FilesWhichInclude // This one is directly or indirectly included from... - }; - - /* - * You should use this version if you simply want all the dependencies, no matter what. - */ - QStringList collectDependencies(const QString &referenceFile, DependencyRole role) const; - - /* - * You should use this version if you might be interested on a particular dependency - * and don't want to continue the search once you have found it. In this case you need - * supply a visitor. Currently the visitor concept simply requires that a type Visitor_T - * models a function that will receive a file string s and indicate whether or not to - * continue: - * - * Visitor_T().acceptFile(s) must be a valid expression. - * - */ - template - void collectDependencies(const QString &referenceFile, - DependencyRole role, - Visitor_T *visitor) const; - - bool hasDependency(const QString &referenceFile, DependencyRole role) const; - - void discard(); - -signals: - void dependencyGraphAvailable(); - -private: - QList > m_files; - IncludeTracker m_includeTracker; - QFutureWatcher m_computeWatcher; - - void cancel(); - void computeCore(); - - // The dependency graph is represent as an adjacency list. The vertices contains - // a list of *out* edges and a list of *in* edges. Each vertex corresponds to a file. - // Its out edges correspond to the files which get directly included by this one, while - // its in edges correspond to files that directly include this one. - // - // For better space efficiency, the adjacency nodes doen't explicitly store the file - // names themselves, but rather an iterator to the corresponding vertex. In addition, - // for speed efficiency we keep track of a hash table that contains iterators to the - // actual vertex storage container, which actually contains the strings for the file - // names. The vertex container itself is a linked list, it has the semantics we need, - // in particular regarding iterator invalidation. - - struct AdjacencyNode; - struct Node - { - Node(const QString &fileName); - - QString m_fileName; - AdjacencyNode *m_out; - AdjacencyNode *m_in; - }; - - typedef QLinkedList NodeList; - typedef NodeList::iterator NodeListIt; - typedef QHash NodeRefSet; - typedef NodeRefSet::iterator NodeRefSetIt; - - struct AdjacencyNode - { - AdjacencyNode(NodeListIt it); - - AdjacencyNode *m_next; - NodeListIt m_nodeIt; - }; - - - void processIncludes(NodeRefSetIt currentFileIt, - const QStringList &compilationOptions); - - template - void collectFilesBFS(NodeListIt nodeIt, DependencyRole role, Visitor_T *visitor) const; - - - // Core graph operations and data - - QPair findVertex(const QString &s) const; - NodeRefSetIt insertVertex(const QString &s); - void insertEdge(NodeRefSetIt fromIt, NodeRefSetIt toIt); - - void deleteAdjacencies(AdjacencyNode *node); - void createAdjacency(AdjacencyNode **node, AdjacencyNode *newNode); - - NodeList m_nodes; - NodeRefSet m_nodesRefs; -}; - -template -void DependencyGraph::collectDependencies(const QString &referenceFile, - DependencyRole role, - Visitor_T *visitor) const -{ - if (m_computeWatcher.isRunning()) - return; - - QPair v = findVertex(referenceFile); - if (!v.first) - return; - - NodeListIt nodeIt = v.second.value(); - - if (role == FilesDirectlyIncludedBy || role == FilesWhichDirectlyInclude) { - AdjacencyNode *adj; - if (role == FilesDirectlyIncludedBy) - adj = nodeIt->m_out; - else - adj = nodeIt->m_in; - - for (; adj; adj = adj->m_next) { - NodeListIt dependentIt = adj->m_nodeIt; - if (visitor->acceptFile(dependentIt->m_fileName)) - return; - } - } else { - collectFilesBFS(nodeIt, role, visitor); - } -} - -template -void DependencyGraph::collectFilesBFS(NodeListIt nodeIt, - DependencyRole role, - Visitor_T *visitor) const -{ - Q_ASSERT(role == FilesIncludedBy || role == FilesWhichInclude); - - if (m_computeWatcher.isRunning()) - return; - - QQueue q; - q.enqueue(nodeIt); - - QSet visited; - visited.insert(nodeIt->m_fileName); - - while (!q.isEmpty()) { - NodeListIt currentIt = q.dequeue(); - AdjacencyNode *adj; - if (role == FilesIncludedBy) - adj = currentIt->m_out; - else - adj = currentIt->m_in; - while (adj) { - NodeListIt adjNodeIt = adj->m_nodeIt; - adj = adj->m_next; - - const QString &adjFileName = adjNodeIt->m_fileName; - if (visited.contains(adjFileName)) - continue; - - if (visitor->acceptFile(adjFileName)) - return; - - visited.insert(adjFileName); - q.enqueue(adjNodeIt); - } - } -} - - -} // Internal -} // ClangCodeModel - -#endif // DEPENDENCYGRAPH_H diff --git a/src/plugins/clangcodemodel/diagnostic.cpp b/src/plugins/clangcodemodel/diagnostic.cpp deleted file mode 100644 index d9646ad1804..00000000000 --- a/src/plugins/clangcodemodel/diagnostic.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "diagnostic.h" - -#include -#include - -using namespace ClangCodeModel; - -Diagnostic::Diagnostic() - : m_severity(Unknown) - , m_length(0) -{} - -Diagnostic::Diagnostic(Severity severity, const SourceLocation &location, unsigned length, const QString &spelling) - : m_severity(severity) - , m_loc(location) - , m_length(length) - , m_spelling(spelling) -{} - -const QString Diagnostic::severityAsString() const -{ - if (m_severity == Unknown) - return QString(); - - static QStringList strs = QStringList() - << QCoreApplication::translate("ClangCodeModel::Diagnostic", "ignored") - << QCoreApplication::translate("ClangCodeModel::Diagnostic", "note") - << QCoreApplication::translate("ClangCodeModel::Diagnostic", "warning") - << QCoreApplication::translate("ClangCodeModel::Diagnostic", "error") - << QCoreApplication::translate("ClangCodeModel::Diagnostic", "fatal") - ; - - return strs.at(m_severity); -} diff --git a/src/plugins/clangcodemodel/diagnostic.h b/src/plugins/clangcodemodel/diagnostic.h deleted file mode 100644 index d34f2ea36ec..00000000000 --- a/src/plugins/clangcodemodel/diagnostic.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANG_DIAGNOSTIC_H -#define CLANG_DIAGNOSTIC_H - -#include "clang_global.h" -#include "sourcelocation.h" - -#include - -namespace ClangCodeModel { - -class CLANG_EXPORT Diagnostic -{ -public: - enum Severity { - Unknown = -1, - Ignored = 0, - Note = 1, - Warning = 2, - Error = 3, - Fatal = 4 - }; - -public: - Diagnostic(); - Diagnostic(Severity severity, const SourceLocation &location, unsigned length, const QString &spelling); - - Severity severity() const - { return m_severity; } - - const QString severityAsString() const; - - const SourceLocation &location() const - { return m_loc; } - - unsigned length() const - { return m_length; } - - const QString &spelling() const - { return m_spelling; } - -private: - Severity m_severity; - SourceLocation m_loc; - unsigned m_length; - QString m_spelling; -}; - -} // namespace ClangCodeModel - -Q_DECLARE_METATYPE(ClangCodeModel::Diagnostic) -Q_DECLARE_METATYPE(QList) - -#endif // CLANG_DIAGNOSTIC_H diff --git a/src/plugins/clangcodemodel/fastindexer.cpp b/src/plugins/clangcodemodel/fastindexer.cpp deleted file mode 100644 index 6bc669551c6..00000000000 --- a/src/plugins/clangcodemodel/fastindexer.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "fastindexer.h" - -using namespace ClangCodeModel::Internal; - -FastIndexer::~FastIndexer() -{ -} diff --git a/src/plugins/clangcodemodel/fastindexer.h b/src/plugins/clangcodemodel/fastindexer.h deleted file mode 100644 index 1c63a4435f9..00000000000 --- a/src/plugins/clangcodemodel/fastindexer.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef FASTINDEXER_H -#define FASTINDEXER_H - -#include "unit.h" - -namespace ClangCodeModel { -namespace Internal { - -class FastIndexer -{ -public: - virtual ~FastIndexer() = 0; - - virtual void indexNow(Unit::Ptr unit) = 0; -}; - -} // Internal namespace -} // ClangCodeModel namespace - -#endif // FASTINDEXER_H diff --git a/src/plugins/clangcodemodel/index.cpp b/src/plugins/clangcodemodel/index.cpp deleted file mode 100644 index f94cd165aa2..00000000000 --- a/src/plugins/clangcodemodel/index.cpp +++ /dev/null @@ -1,491 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "index.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ClangCodeModel { -namespace Internal { - -class ClangSymbolSearcher; - -class IndexPrivate -{ -public: - IndexPrivate(); - - void insertSymbol(const Symbol &symbol, const QDateTime &timeStamp); - QList symbols(const QString &fileName) const; - QList symbols(const QString &fileName, Symbol::Kind kind) const; - QList symbols(const QString &fileName, Symbol::Kind kind, const QString &uqName) const; - QList symbols(const QString &fileName, const QString &uqName) const; - QList symbols(Symbol::Kind kind) const; - - void match(ClangSymbolSearcher *searcher) const; - - void insertFile(const QString &fileName, const QDateTime &timeStamp); - void removeFile(const QString &fileName); - void removeFiles(const QStringList &fileNames); - bool containsFile(const QString &fileName) const; - QStringList files() const; - - void clear(); - - bool isEmpty() const; - - void trackTimeStamp(const Symbol &symbol, const QDateTime &timeStamp); - void trackTimeStamp(const QString &fileName, const QDateTime &timeStamp); - - bool validate(const QString &fileName) const; - - QByteArray serialize() const; - void deserialize(const QByteArray &data); - -private: - typedef QLinkedList SymbolCont; - typedef SymbolCont::iterator SymbolIt; - - typedef QHash > NameIndex; - typedef QHash KindIndex; - typedef QHash FileIndex; - - typedef QList::iterator SymbolIndexIt; - typedef NameIndex::iterator NameIndexIt; - typedef KindIndex::iterator KindIndexIt; - typedef FileIndex::iterator FileIndexIt; - typedef FileIndex::const_iterator FileIndexCIt; - - void insertSymbol(const Symbol &symbol); - void removeSymbol(SymbolIndexIt it); - - QPair findEquivalentSymbol(const Symbol &symbol); - void updateEquivalentSymbol(SymbolIndexIt it, const Symbol &symbol); - - void createIndexes(SymbolIt it); - QList removeIndexes(const QString &fileName); - - static QList symbolsFromIterators(const QList &symbolList); - - // @TODO: Sharing of compilation options... - - mutable QMutex m_mutex; - SymbolCont m_container; - FileIndex m_files; - QHash m_timeStamps; -}; - -} // namespace Internal -} // namespace ClangCodeModel - -using namespace ClangCodeModel; -using namespace Internal; - -IndexPrivate::IndexPrivate() - : m_mutex(QMutex::Recursive) -{ -} - -void IndexPrivate::createIndexes(SymbolIt it) -{ - m_files[it->m_location.fileName()][it->m_kind][it->m_name].append(it); -} - -QList::iterator> IndexPrivate::removeIndexes(const QString &fileName) -{ - QList iterators; - KindIndex kindIndex = m_files.take(fileName); - KindIndexIt it = kindIndex.begin(); - KindIndexIt eit = kindIndex.end(); - for (; it != eit; ++it) { - NameIndex nameIndex = *it; - NameIndexIt nit = nameIndex.begin(); - NameIndexIt neit = nameIndex.end(); - for (; nit != neit; ++nit) - iterators.append(*nit); - } - return iterators; -} - -void IndexPrivate::insertSymbol(const Symbol &symbol) -{ - QMutexLocker locker(&m_mutex); - - SymbolIt it = m_container.insert(m_container.begin(), symbol); - createIndexes(it); -} - -void IndexPrivate::insertSymbol(const Symbol &symbol, const QDateTime &timeStamp) -{ - const QPair &find = findEquivalentSymbol(symbol); - if (find.first) - updateEquivalentSymbol(find.second, symbol); - else - insertSymbol(symbol); - - trackTimeStamp(symbol, timeStamp); -} - -QPair IndexPrivate::findEquivalentSymbol(const Symbol &symbol) -{ - // Despite the loop below finding a symbol should be efficient, since we already filter - // the file name, the kind, and the qualified name through the indexing mechanism. In many - // cases it will iterate only once. - QList &byName = m_files[symbol.m_location.fileName()][symbol.m_kind][symbol.m_name]; - for (SymbolIndexIt it = byName.begin(); it != byName.end(); ++it) { - const Symbol &candidateSymbol = *(*it); - // @TODO: Overloads, template specializations - if (candidateSymbol.m_qualification == symbol.m_qualification) - return qMakePair(true, it); - } - - return qMakePair(false, QList::iterator()); -} - -void IndexPrivate::updateEquivalentSymbol(SymbolIndexIt it, const Symbol &symbol) -{ - SymbolIt symbolIt = *it; - - Q_ASSERT(symbolIt->m_kind == symbol.m_kind); - Q_ASSERT(symbolIt->m_qualification == symbol.m_qualification); - Q_ASSERT(symbolIt->m_name == symbol.m_name); - Q_ASSERT(symbolIt->m_location.fileName() == symbol.m_location.fileName()); - - symbolIt->m_location = symbol.m_location; -} - -void IndexPrivate::removeSymbol(SymbolIndexIt it) -{ - SymbolIt symbolIt = *it; - - m_container.erase(symbolIt); - - KindIndex &kindIndex = m_files[symbolIt->m_location.fileName()]; - NameIndex &nameIndex = kindIndex[symbolIt->m_kind]; - QList &byName = nameIndex[symbolIt->m_name]; - byName.erase(it); - if (byName.isEmpty()) { - nameIndex.remove(symbolIt->m_name); - if (nameIndex.isEmpty()) { - kindIndex.remove(symbolIt->m_kind); - if (kindIndex.isEmpty()) - m_files.remove(symbolIt->m_location.fileName()); - } - } -} - -QList IndexPrivate::symbols(const QString &fileName) const -{ - QMutexLocker locker(&m_mutex); - - QList all; - const QList &byKind = m_files.value(fileName).values(); - foreach (const NameIndex &nameIndex, byKind) { - const QList > &byName = nameIndex.values(); - foreach (const QList &symbols, byName) - all.append(symbolsFromIterators(symbols)); - } - return all; -} - -QList IndexPrivate::symbols(const QString &fileName, Symbol::Kind kind) const -{ - QMutexLocker locker(&m_mutex); - - QList all; - const QList > &byName = m_files.value(fileName).value(kind).values(); - foreach (const QList &symbols, byName) - all.append(symbolsFromIterators(symbols)); - return all; -} - -QList IndexPrivate::symbols(const QString &fileName, - Symbol::Kind kind, - const QString &uqName) const -{ - QMutexLocker locker(&m_mutex); - - return symbolsFromIterators(m_files.value(fileName).value(kind).value(uqName)); -} - -QList IndexPrivate::symbols(Symbol::Kind kind) const -{ - QMutexLocker locker(&m_mutex); - - QList all; - FileIndexCIt it = m_files.begin(); - FileIndexCIt eit = m_files.end(); - for (; it != eit; ++it) - all.append(symbols(it.key(), kind)); - return all; -} - -void IndexPrivate::match(ClangSymbolSearcher *searcher) const -{ - QMutexLocker locker(&m_mutex); - Q_UNUSED(searcher); -// searcher->search(m_container); -} - -QList IndexPrivate::symbolsFromIterators(const QList &symbolList) -{ - QList all; - foreach (SymbolIt symbolIt, symbolList) - all.append(*symbolIt); - return all; -} - -void IndexPrivate::trackTimeStamp(const Symbol &symbol, const QDateTime &timeStamp) -{ - QMutexLocker locker(&m_mutex); - - trackTimeStamp(symbol.m_location.fileName(), timeStamp); -} - -void IndexPrivate::trackTimeStamp(const QString &fileName, const QDateTime &timeStamp) -{ - QMutexLocker locker(&m_mutex); - - // We keep track of time stamps on a per file basis (most recent one). - m_timeStamps[fileName] = timeStamp; -} - -bool IndexPrivate::validate(const QString &fileName) const -{ - QMutexLocker locker(&m_mutex); - - const QDateTime &timeStamp = m_timeStamps.value(fileName); - if (!timeStamp.isValid()) - return false; - - QFileInfo fileInfo(fileName); - if (fileInfo.lastModified() > timeStamp) - return false; - - return true; -} - -void IndexPrivate::insertFile(const QString &fileName, const QDateTime &timeStamp) -{ - QMutexLocker locker(&m_mutex); - - trackTimeStamp(fileName, timeStamp); -} - -QStringList IndexPrivate::files() const -{ - QMutexLocker locker(&m_mutex); - - return m_timeStamps.keys(); -} - -bool IndexPrivate::containsFile(const QString &fileName) const -{ - QMutexLocker locker(&m_mutex); - - return m_timeStamps.contains(fileName); -} - -void IndexPrivate::removeFile(const QString &fileName) -{ - QMutexLocker locker(&m_mutex); - - const QList &iterators = removeIndexes(fileName); - foreach (SymbolIt it, iterators) - m_container.erase(it); - - m_timeStamps.remove(fileName); -} - -void IndexPrivate::removeFiles(const QStringList &fileNames) -{ - QMutexLocker locker(&m_mutex); - - foreach (const QString &fileName, fileNames) - removeFile(fileName); -} - -void IndexPrivate::clear() -{ - QMutexLocker locker(&m_mutex); - - m_container.clear(); - m_files.clear(); - m_timeStamps.clear(); -} - -bool IndexPrivate::isEmpty() const -{ - QMutexLocker locker(&m_mutex); - - return m_timeStamps.isEmpty(); -} - -QByteArray IndexPrivate::serialize() const -{ - QMutexLocker locker(&m_mutex); - - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - - stream << (quint32)0x0A0BFFEE; - stream << (quint16)1; - stream.setVersion(QDataStream::Qt_4_7); - stream << m_container; - stream << m_timeStamps; - - return data; -} - -void IndexPrivate::deserialize(const QByteArray &data) -{ - QMutexLocker locker(&m_mutex); - - clear(); - - // @TODO: Version compatibility handling. - - QDataStream stream(data); - - quint32 header; - stream >> header; - if (header != 0x0A0BFFEE) - return; - - quint16 indexVersion; - stream >> indexVersion; - if (indexVersion != 1) - return; - - stream.setVersion(QDataStream::Qt_4_7); - - SymbolCont symbols; - stream >> symbols; - stream >> m_timeStamps; - - // @TODO: Overload the related functions with batch versions. - foreach (const Symbol &symbol, symbols) - insertSymbol(symbol); -} - - -Index::Index() - : d(new IndexPrivate) -{} - -Index::~Index() -{} - -void Index::insertSymbol(const Symbol &symbol, const QDateTime &timeStamp) -{ - d->insertSymbol(symbol, timeStamp); -} - -QList Index::symbols(const QString &fileName) const -{ - return d->symbols(fileName); -} - -QList Index::symbols(const QString &fileName, Symbol::Kind kind) const -{ - return d->symbols(fileName, kind); -} - -QList Index::symbols(const QString &fileName, Symbol::Kind kind, const QString &uqName) const -{ - return d->symbols(fileName, kind, uqName); -} - -QList Index::symbols(Symbol::Kind kind) const -{ - return d->symbols(kind); -} - -void Index::match(ClangSymbolSearcher *searcher) const -{ - d->match(searcher); -} - -void Index::insertFile(const QString &fileName, const QDateTime &timeStamp) -{ - d->insertFile(fileName, timeStamp); -} - -QStringList Index::files() const -{ - return d->files(); -} - -bool Index::containsFile(const QString &fileName) const -{ - return d->containsFile(fileName); -} - -void Index::removeFile(const QString &fileName) -{ - d->removeFile(fileName); -} - -void Index::removeFiles(const QStringList &fileNames) -{ - d->removeFiles(fileNames); -} - -void Index::clear() -{ - d->clear(); -} - -bool Index::isEmpty() const -{ - return d->isEmpty(); -} - -bool Index::validate(const QString &fileName) const -{ - return d->validate(fileName); -} - -QByteArray Index::serialize() const -{ - return d->serialize(); -} - -void Index::deserialize(const QByteArray &data) -{ - d->deserialize(data); -} diff --git a/src/plugins/clangcodemodel/index.h b/src/plugins/clangcodemodel/index.h deleted file mode 100644 index 357d136c6b8..00000000000 --- a/src/plugins/clangcodemodel/index.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef INDEX_H -#define INDEX_H - -#include "clangsymbol.h" - -#include -#include -#include -#include -#include -#include - -namespace ClangCodeModel { - -class Symbol; - -namespace Internal { - -class ClangSymbolSearcher; -class IndexPrivate; - -class Index -{ -public: - Index(); - ~Index(); - - void insertSymbol(const Symbol &symbol, const QDateTime &timeStamp); - QList symbols(const QString &fileName) const; - QList symbols(const QString &fileName, Symbol::Kind kind) const; - QList symbols(const QString &fileName, Symbol::Kind kind, const QString &uqName) const; - QList symbols(Symbol::Kind kind) const; - - void match(ClangSymbolSearcher *searcher) const; - - void insertFile(const QString &fileName, const QDateTime &timeStamp); - void removeFile(const QString &fileName); - void removeFiles(const QStringList &fileNames); - bool containsFile(const QString &fileName) const; - QStringList files() const; - - bool validate(const QString &fileName) const; - - void clear(); - - bool isEmpty() const; - - QByteArray serialize() const; - void deserialize(const QByteArray &data); - -private: - QScopedPointer d; -}; - -} // Internal -} // ClangCodeModel - -#endif // INDEX_H diff --git a/src/plugins/clangcodemodel/indexer.cpp b/src/plugins/clangcodemodel/indexer.cpp deleted file mode 100644 index f44c51d4c1e..00000000000 --- a/src/plugins/clangcodemodel/indexer.cpp +++ /dev/null @@ -1,1284 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "clangutils.h" -#include "indexer.h" -#include "index.h" -#include "cxraii.h" -#include "sourcelocation.h" -#include "utils_p.h" -#include "pchmanager.h" -#include "raii/scopedclangoptions.h" - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace Utils; -using namespace ClangCodeModel; -using namespace Internal; - -namespace ClangCodeModel { - -// The indexing result, containing the symbols found, reported by the indexer processor. -struct IndexingResult -{ - typedef CppTools::ProjectPart ProjectPart; - - IndexingResult() - : m_unit(Unit::create()) - {} - - IndexingResult(const QVector &symbol, - const QSet &processedFiles, - const Unit::Ptr &unit, - const ProjectPart::Ptr &projectPart) - : m_symbolsInfo(symbol) - , m_processedFiles(processedFiles) - , m_unit(unit) - , m_projectPart(projectPart) - {} - - QVector m_symbolsInfo; - QSet m_processedFiles; - Unit::Ptr m_unit; - ProjectPart::Ptr m_projectPart; -}; - -class LibClangIndexer; - -class IndexerPrivate : public QObject -{ - Q_OBJECT - -public: - typedef CppTools::ProjectPart ProjectPart; - -public: - IndexerPrivate(Indexer *indexer); - ~IndexerPrivate() - { cancel(true); } - - // This enumeration is used to index a vector. So be careful when changing. - enum FileType { - ImplementationFile = 0, - HeaderFile, - TotalFileTypes - }; - - struct FileData - { - FileData() : m_upToDate(false) {} - FileData(const QString &fileName, - const ProjectPart::Ptr &projectPart, - bool upToDate = false) - : m_fileName(fileName) - , m_projectPart(projectPart) - , m_upToDate(upToDate) - , m_managementOptions(CXTranslationUnit_DetailedPreprocessingRecord - | CXTranslationUnit_Incomplete) - {} - - QString m_fileName; - ProjectPart::Ptr m_projectPart; - bool m_upToDate; - unsigned m_managementOptions; - }; - - void synchronize(const QVector &results); - void finished(LibClangIndexer *indexer); - bool noIndexersRunning() const; - -private: - mutable QMutex m_mutex; - - void indexingFinished(); - void cancelIndexing(); - int runningIndexerCount() const; - -public slots: - void dependencyGraphComputed(); - void restoredSymbolsAnalysed(); - -public: - enum IndexingMode { - RelaxedIndexing, // Index symbols from any file. - ConstrainedIndexing // Index symbols only from the requested files. - }; - - void startLoading(); - void concludeLoading(); - - void computeDependencyGraph(); - void analyzeRestoredSymbols(); - - void runQuickIndexing(const Unit::Ptr &unit, const ProjectPart::Ptr &part); - void run(); - void run(const QStringList &fileNames); - void runCore(const QHash &headers, - const QHash &impls, - IndexingMode mode); - void watchIndexingThreads(QFutureInterface &future); - bool isBusy() const; - void cancel(bool wait); - void reset(); - - bool addFile(const QString &fileName, - ProjectPart::Ptr projectPart); - void addOrUpdateFileData(const QString &fileName, - ProjectPart::Ptr projectPart, - bool upToDate); - QStringList allFiles() const; - bool isTrackingFile(const QString &fileName, FileType type) const; - static FileType identifyFileType(const QString &fileName); - static void populateFileNames(QStringList *all, const QList &data); - QStringList compilationOptions(const QString &fileName) const; - - bool deserealizeSymbols(); - void serializeSymbols() const; - - QList symbols(Symbol::Kind kind) const; - QList symbols(const QString &fileName, const Symbol::Kind kind) const; - void match(ClangSymbolSearcher *searcher) const; - - Indexer *m_q; - QVector > m_files; - Index m_index; - bool m_hasQueuedFullRun; - QSet m_queuedFilesRun; - QString m_storagePath; - bool m_isLoaded; -// DependencyGraph m_dependencyGraph; - QScopedPointer >m_loadingWatcher; - QScopedPointer >m_indexingWatcher; - QThreadPool m_indexingPool; - QSet m_runningIndexers; -}; - -} // ClangCodeModel - -Q_DECLARE_METATYPE(IndexingResult) - -namespace { - -struct ScopepTimer -{ - ScopepTimer(int id = 0) : m_id(id) { m_t.start(); } - ~ScopepTimer() { qDebug() << "\t#Timer" << m_id << ":" << m_t.elapsed() << "ms"; } - int m_id; - QTime m_t; -}; - -} // Anonymous - -namespace ClangCodeModel { - -class LibClangIndexer: public QRunnable -{ -protected: - typedef CppTools::ProjectPart ProjectPart; - -public: - LibClangIndexer(IndexerPrivate *indexer) - : m_indexer(indexer) - , m_isCanceled(false) - {} - - virtual ~LibClangIndexer() - {} - - void cancel() - { m_isCanceled = true; } - -protected: - void propagateResults(const ProjectPart::Ptr &projectPart) - { - if (!isCanceled()) { - QVector indexingResults; - indexingResults.reserve(m_allFiles.size()); - - foreach (const QString &fn, m_allFiles.keys()) { - QVector symbols; unfoldSymbols(symbols, fn); - QSet processedFiles = QSet::fromList(m_allFiles.keys()); - Unit::Ptr unit = Unit::create(fn); - IndexingResult indexingResult(symbols, processedFiles, unit, projectPart); - indexingResults.append(indexingResult); - - // TODO: includes need to be propagated to the dependency table. - } - m_indexer->synchronize(indexingResults); - } - - qDeleteAll(m_allFiles.values()); - m_allFiles.clear(); - qDeleteAll(m_allSymbols); - m_allSymbols.clear(); - } - -protected: - static inline LibClangIndexer *indexer(CXClientData d) - { return static_cast(d); } - - static int abortQuery(CXClientData client_data, void *reserved) { - Q_UNUSED(reserved); - - return indexer(client_data)->isCanceled(); - } - - static void diagnostic(CXClientData client_data, CXDiagnosticSet diagSet, void *reserved) { - Q_UNUSED(client_data); - Q_UNUSED(diagSet); - Q_UNUSED(reserved); - } - - static CXIdxClientFile enteredMainFile(CXClientData client_data, CXFile file, void *reserved) { - Q_UNUSED(client_data); - Q_UNUSED(reserved); - - const QString fileName = getQString(clang_getFileName(file)); -// qDebug() << "enteredMainFile:" << fileName; - LibClangIndexer *lci = indexer(client_data); - File *f = lci->file(fileName); - f->setMainFile(); - - return f; - } - - static CXIdxClientFile includedFile(CXClientData client_data, const CXIdxIncludedFileInfo *info) { - Q_UNUSED(client_data); - - File *includingFile = 0; - clang_indexLoc_getFileLocation(info->hashLoc, reinterpret_cast(&includingFile), 0, 0, 0, 0); - - const QString fileName = getQString(clang_getFileName(info->file)); - File *f = indexer(client_data)->file(fileName); - - if (includingFile) - includingFile->addInclude(f); - - return f; - } - - static CXIdxClientFile importedASTFile(CXClientData client_data, const CXIdxImportedASTFileInfo *info) { - const QString fileName = getQString(clang_getFileName(info->file)); - -// qDebug() << "importedASTFile:" << fileName; - - indexer(client_data)->m_importedASTs.insert(fileName, false); - - return info->file; - } - - static CXIdxClientContainer startedTranslationUnit(CXClientData client_data, void *reserved) { - Q_UNUSED(client_data); - Q_UNUSED(reserved); - -// qDebug() << "startedTranslationUnit"; - return 0; - } - - static void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo *info) { - LibClangIndexer *lci = indexer(client_data); - - File *includingFile = 0; - unsigned line = 0, column = 0, offset = 0; - clang_indexLoc_getFileLocation(info->loc, reinterpret_cast(&includingFile), 0, &line, &column, &offset); - - QString kind = getQString(clang_getCursorKindSpelling(info->cursor.kind)); - QString displayName = getQString(clang_getCursorDisplayName(info->cursor)); - QString spellingName = getQString(clang_getCursorSpelling(info->cursor)); -// qDebug() << (includingFile ? includingFile->name() : QLatin1String("")) << ":"<newSymbol(info->cursor.kind, displayName, spellingName, includingFile, line, column, offset); - - // TODO: add to decl container... - if (includingFile) // TODO: check why includingFile can be null... - includingFile->addSymbol(sym); - - if (const CXIdxContainerInfo *semanticContainer = info->semanticContainer) { - if (Symbol *container = static_cast(clang_index_getClientContainer(semanticContainer))) { - sym->semanticContainer = container; - container->addSymbol(sym); - } - } - - // TODO: ObjC containers - // TODO: index forward decls too? - - if (info->declAsContainer) - clang_index_setClientContainer(info->declAsContainer, sym); - } - - static void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo *info) { - Q_UNUSED(client_data); - Q_UNUSED(info); - - // TODO: well, we do get the info, so why not (optionally?) remember all references? - } - -protected: - struct File; - struct Symbol; - - typedef QHash FilesByName; - struct File - { - File(const QString &fileName) - : m_fileName(fileName) - {} - - void addInclude(File *f) - { -// assert(f); - m_includes.insert(f->name(), f); - } - - QList includes() const - { return m_includes.values(); } - - QString name() const - { return m_fileName; } - - void setMainFile(bool isMainFile = true) - { m_isMainFile = isMainFile; } - - bool isMainFile() const - { return m_isMainFile; } - - void addSymbol(Symbol *symbol) - { -// assert(symbol); - m_symbols.append(symbol); - } - - QVector symbols() const - { return m_symbols; } - - private: - QString m_fileName; - FilesByName m_includes; - bool m_isMainFile; - QVector m_symbols; - }; - - struct Symbol - { - Symbol(enum CXCursorKind kind, const QString &displayName, const QString &spellingName, File *file, unsigned line, unsigned column, unsigned offset) - : kind(kind) - , displayName(displayName) - , spellingName(spellingName) - , file(file) - , line(line) - , column(column) - , offset(offset) - , semanticContainer(0) - {} - - QString spellKind() const - { return getQString(clang_getCursorKindSpelling(kind)); } - - void addSymbol(Symbol *symbol) - { symbols.append(symbol); } - - enum CXCursorKind kind; - QString displayName, spellingName; - File *file; - unsigned line, column, offset; - Symbol *semanticContainer; - QVector symbols; - }; - -protected: - bool isCanceled() const - { return m_isCanceled; } - - void finish() - { m_indexer->finished(this); } - - File *file(const QString &fileName) - { - File *f = m_allFiles[fileName]; - if (!f) { - f = new File(fileName); - m_allFiles.insert(fileName, f); - } - return f; - } - - Symbol *newSymbol(enum CXCursorKind kind, const QString &displayName, const QString &spellingName, File *file, unsigned line, unsigned column, unsigned offset) - { - Symbol *s = new Symbol(kind, displayName, spellingName, file, line, column, offset); - m_allSymbols.append(s); - return s; - } - - void dumpInfo() - { - qDebug() << "=== indexing info dump ==="; - qDebug() << "indexed" << m_allFiles.size() << "files. Main files:"; - foreach (const File *f, m_allFiles) { - if (!f->isMainFile()) - continue; - qDebug() << f->name() << ":"; - foreach (const File *inc, f->includes()) - qDebug() << " includes" << inc->name(); - dumpSymbols(f->symbols(), QByteArray(" ")); - } - - qDebug() << "=== end of dump ==="; - } - - void dumpSymbols(const QVector &symbols, const QByteArray &indent) - { - if (symbols.isEmpty()) - return; - - qDebug("%scontained symbols:", indent.constData()); - QByteArray newIndent = indent + " "; - foreach (const Symbol *s, symbols) { - qDebug("%s%s (%s)", newIndent.constData(), s->spellingName.toUtf8().constData(), s->spellKind().toUtf8().constData()); - dumpSymbols(s->symbols, newIndent); - } - } - - void unfoldSymbols(QVector &result, const QString &fileName) { - const QVector symbolsForFile = file(fileName)->symbols(); - foreach (const Symbol *s, symbolsForFile) { - unfoldSymbols(s, result); - } - } - - void unfoldSymbols(const Symbol *s, QVector &result) { - if (!s->file) - return; - - Symbol sym; - sym.m_name = s->spellingName; - sym.m_qualification = s->spellingName; - - static QLatin1String sep("::"); - for (Symbol *parent = s->semanticContainer; parent; parent = parent->semanticContainer) - sym.m_qualification = parent->spellingName + sep + sym.m_qualification; - - sym.m_location = SourceLocation(s->file->name(), s->line, s->column, s->offset); - - switch (s->kind) { - case CXCursor_EnumDecl: sym.m_kind = Symbol::Enum; break; - case CXCursor_StructDecl: - case CXCursor_ClassDecl: sym.m_kind = Symbol::Class; break; - case CXCursor_CXXMethod: sym.m_kind = Symbol::Method; break; - case CXCursor_FunctionTemplate: - case CXCursor_FunctionDecl: sym.m_kind = Symbol::Function; break; - case CXCursor_DeclStmt: sym.m_kind = Symbol::Declaration; break; - case CXCursor_Constructor: sym.m_kind = Symbol::Constructor; break; - case CXCursor_Destructor: sym.m_kind = Symbol::Destructor; break; - default: sym.m_kind = Symbol::Unknown; break; - } - - result.append(sym); - } - -protected: - static IndexerCallbacks IndexCB; - -protected: - IndexerPrivate *m_indexer; - bool m_isCanceled; - QHash m_importedASTs; - FilesByName m_allFiles; - QVector m_allSymbols; -}; - -IndexerCallbacks LibClangIndexer::IndexCB = { - abortQuery, - diagnostic, - enteredMainFile, - includedFile, - importedASTFile, - startedTranslationUnit, - indexDeclaration, - indexEntityReference -}; - -class ProjectPartIndexer: public LibClangIndexer -{ -public: - ProjectPartIndexer(IndexerPrivate *indexer, const QList &todo) - : LibClangIndexer(indexer) - , m_todo(todo) - {} - - void run() - { - if (isCanceled() || m_todo.isEmpty()) { - finish(); - return; - } - - const ProjectPart::Ptr &pPart = m_todo[0].m_projectPart; - -restart: - CXIndex idx; - if (!(idx = clang_createIndex(/* excludeDeclsFromPCH */ 1, - /* displayDiagnosics=*/1))) { - qDebug() << "Could not create Index"; - return; - } - - CXIndexAction idxAction = clang_IndexAction_create(idx); - const unsigned index_opts = CXIndexOpt_SuppressWarnings; - - PchManager *pchManager = PchManager::instance(); - PchInfo::Ptr pchInfo = pchManager->pchInfo(pPart); - - for (int i = 0, ei = m_todo.size(); i < ei; ++i) { - const IndexerPrivate::FileData &fd = m_todo.at(i); - if (fd.m_upToDate) - continue; - - if (pchManager->pchInfo(pPart) != pchInfo) { - clang_IndexAction_dispose(idxAction); - clang_disposeIndex(idx); - goto restart; - } - - QStringList opts = Utils::createClangOptions(pPart, fd.m_fileName); - if (!pchInfo.isNull()) - opts.append(Utils::createPCHInclusionOptions(pchInfo->fileName())); - - ScopedClangOptions scopedOpts(opts); - QByteArray fileName = fd.m_fileName.toUtf8(); - -// qDebug() << "Indexing file" << fd.m_fileName << "with options" << opts; - unsigned parsingOptions = fd.m_managementOptions; - parsingOptions |= CXTranslationUnit_SkipFunctionBodies; - - /*int result =*/ clang_indexSourceFile(idxAction, this, - &IndexCB, sizeof(IndexCB), - index_opts, fileName.constData(), - scopedOpts.data(), scopedOpts.size(), 0, 0, 0, - parsingOptions); - - // index imported ASTs: - foreach (const QString &astFile, m_importedASTs.keys()) { - if (m_importedASTs.value(astFile)) - continue; - - if (CXTranslationUnit TU = clang_createTranslationUnit( - idx, astFile.toUtf8().constData())) { - /*result =*/ clang_indexTranslationUnit(idxAction, this, - &IndexCB, - sizeof(IndexCB), - index_opts, TU); - clang_disposeTranslationUnit(TU); - } - - m_importedASTs[astFile] = true; - } - - propagateResults(fd.m_projectPart); - if (isCanceled()) - break; - } - -// dumpInfo(); - - clang_IndexAction_dispose(idxAction); - clang_disposeIndex(idx); - - finish(); - } - -private: - QList m_todo; -}; - -class QuickIndexer: public LibClangIndexer -{ -public: - QuickIndexer(IndexerPrivate *indexer, const Unit::Ptr &unit, const ProjectPart::Ptr&projectPart) - : LibClangIndexer(indexer) - , m_unit(unit) - , m_projectPart(projectPart) - {} - - void run() - { - if (isCanceled() || !m_unit->isLoaded()) { - finish(); - return; - } - - CXIndexAction idxAction = clang_IndexAction_create(m_unit->clangIndex()); - const unsigned index_opts = CXIndexOpt_SuppressWarnings; - -// qDebug() << "Indexing TU" << m_unit.fileName() << "..."; - /*int result =*/ clang_indexTranslationUnit(idxAction, this, - &IndexCB, sizeof(IndexCB), - index_opts, - m_unit->clangTranslationUnit()); - - propagateResults(m_projectPart); - - clang_IndexAction_dispose(idxAction); - finish(); - } - -private: - Unit::Ptr m_unit; - ProjectPart::Ptr m_projectPart; -}; - -} // ClangCodeModel - -IndexerPrivate::IndexerPrivate(Indexer *indexer) - : m_mutex(QMutex::Recursive) - , m_q(indexer) - , m_files(TotalFileTypes) - , m_hasQueuedFullRun(false) - , m_isLoaded(false) - , m_loadingWatcher(new QFutureWatcher) - , m_indexingWatcher(new QFutureWatcher) -{ -// const int magicThreadCount = QThread::idealThreadCount() * 4 / 3; - const int magicThreadCount = QThread::idealThreadCount() - 1; - m_indexingPool.setMaxThreadCount(std::max(magicThreadCount, 1)); - m_indexingPool.setExpiryTimeout(1000); -} - -void IndexerPrivate::runCore(const QHash & /*headers*/, - const QHash &impls, - IndexingMode /*mode*/) -{ - QMutexLocker locker(&m_mutex); - - typedef QHash::const_iterator FileContIt; - QHash > parts; - typedef QHash >::Iterator PartIter; - - QList docs = Core::DocumentModel::openedDocuments(); - QSet openDocs; - foreach (Core::IDocument *doc, docs) - openDocs.insert(doc->filePath().toString()); - - for (FileContIt tit = impls.begin(), eit = impls.end(); tit != eit; ++tit) { - if (!tit->m_upToDate && openDocs.contains(tit.key())) { - const IndexerPrivate::FileData &fd = tit.value(); - parts[fd.m_projectPart].append(fd); - } - } - - if (parts.isEmpty()) - return; - - for (PartIter i = parts.begin(), ei = parts.end(); i != ei; ++i) { - ProjectPartIndexer *ppi = new ProjectPartIndexer(this, i.value()); - m_runningIndexers.insert(ppi); - m_indexingPool.start(ppi); - } - - QFuture task = QtConcurrent::run(&IndexerPrivate::watchIndexingThreads, this); - m_indexingWatcher->setFuture(task); - emit m_q->indexingStarted(task); -} - -void IndexerPrivate::watchIndexingThreads(QFutureInterface &future) -{ - int maxTodo = runningIndexerCount(); - future.setProgressRange(0, maxTodo); - - int todo = -1; - while (todo) { - int newTodo = runningIndexerCount(); - if (todo != newTodo) - future.setProgressValue(maxTodo - newTodo); - todo = newTodo; - if (future.isCanceled()) { - cancelIndexing(); - return; - } - m_indexingPool.waitForDone(500); - } -} - -void IndexerPrivate::run() -{ - Q_ASSERT(m_isLoaded); - - QMutexLocker locker(&m_mutex); - - if (m_runningIndexers.isEmpty()) { - runCore(m_files.value(HeaderFile), - m_files.value(ImplementationFile), - RelaxedIndexing); - } else { - m_hasQueuedFullRun = true; - cancelIndexing(); - } -} - -void IndexerPrivate::run(const QStringList &fileNames) -{ - Q_ASSERT(m_isLoaded); - QMutexLocker locker(&m_mutex); - - if (noIndexersRunning()) { - QVector > files(TotalFileTypes); - foreach (const QString &fileName, fileNames) { - FileType type = identifyFileType(fileName); - if (!isTrackingFile(fileName, type)) { - // @TODO - continue; - } - - FileData *data = &m_files[type][fileName]; - data->m_upToDate = false; - files[type].insert(fileName, *data); - m_index.removeFile(fileName); - } - runCore(files.value(HeaderFile), - files.value(ImplementationFile), - ConstrainedIndexing); - } else { - m_queuedFilesRun.unite(fileNames.toSet()); - } -} - -bool IndexerPrivate::isBusy() const -{ - return !noIndexersRunning() || m_loadingWatcher->isRunning(); -} - -void IndexerPrivate::cancel(bool wait) -{ -// m_dependencyGraph.discard(); - - m_loadingWatcher->cancel(); - cancelIndexing(); - if (wait) { - m_loadingWatcher->waitForFinished(); - m_indexingWatcher->waitForFinished(); - while (!noIndexersRunning()) - m_indexingPool.waitForDone(100); - } -} - -void IndexerPrivate::reset() -{ - cancel(true); - serializeSymbols(); - - for (int i = 0; i < TotalFileTypes; ++i) - m_files[i].clear(); - m_hasQueuedFullRun = false; - m_queuedFilesRun.clear(); - m_storagePath.clear(); - m_index.clear(); - m_isLoaded = false; -} - -void IndexerPrivate::synchronize(const QVector &results) -{ - Q_UNUSED(results); -#if 0 - foreach (const IndexingResult &result, results) { - QMutexLocker locker(&m_mutex); - - foreach (const Symbol &symbol, result.m_symbolsInfo) { - addOrUpdateFileData(symbol.m_location.fileName(), - result.m_projectPart, - true); - - // Make the symbol available in the database. - m_index.insertSymbol(symbol, result.m_unit->timeStamp()); - } - - // There might be files which were processed but did not "generate" any indexable symbol, - // but we still need to make the index aware of them. - result.m_processedFiles.insert(result.m_unit->fileName()); - foreach (const QString &fileName, result.m_processedFiles) { - if (!m_index.containsFile(fileName)) - m_index.insertFile(fileName, result.m_unit.timeStamp()); - } - - // If this unit is being kept alive, update in the manager. - if (LiveUnitsManager::instance()->isTracking(result.m_unit.fileName())) - LiveUnitsManager::instance()->updateUnit(result.m_unit.fileName(), result.m_unit); - } -#endif -} - -void IndexerPrivate::finished(LibClangIndexer *indexer) -{ - QMutexLocker locker(&m_mutex); - - m_runningIndexers.remove(indexer); - if (noIndexersRunning()) - indexingFinished(); -} - -bool IndexerPrivate::noIndexersRunning() const -{ - QMutexLocker locker(&m_mutex); - - return m_runningIndexers.isEmpty(); -} - -void IndexerPrivate::indexingFinished() -{ - if (m_hasQueuedFullRun) { - m_hasQueuedFullRun = false; - run(); - } else if (!m_queuedFilesRun.isEmpty()) { - const QStringList &files = m_queuedFilesRun.toList(); - m_queuedFilesRun.clear(); - run(files); - } - - emit m_q->indexingFinished(); -} - -void IndexerPrivate::cancelIndexing() -{ - QMutexLocker locker(&m_mutex); - - foreach (LibClangIndexer* partIndexer, m_runningIndexers) { - partIndexer->cancel(); - } -} - -int IndexerPrivate::runningIndexerCount() const -{ - QMutexLocker locker(&m_mutex); - return m_runningIndexers.size(); -} - -void IndexerPrivate::addOrUpdateFileData(const QString &fileName, - ProjectPart::Ptr projectPart, - bool upToDate) -{ - Q_ASSERT(QDir::isAbsolutePath(fileName)); - - QString cleanFileName(normalizeFileName(fileName)); - - FileType fileType = identifyFileType(cleanFileName); - if (isTrackingFile(cleanFileName, fileType)) { - m_files[fileType][cleanFileName].m_projectPart = projectPart; - m_files[fileType][cleanFileName].m_upToDate = upToDate; - } else { - m_files[fileType].insert(cleanFileName, - FileData(cleanFileName, projectPart, upToDate)); - } - - if (!upToDate) - m_index.removeFile(cleanFileName); -} - -bool IndexerPrivate::addFile(const QString &fileName, - ProjectPart::Ptr projectPart) -{ - if (isBusy() - || fileName.trimmed().isEmpty() - || !QFileInfo(fileName).isFile()) - return false; - - addOrUpdateFileData(fileName, projectPart, false); - - return true; -} - -QStringList IndexerPrivate::allFiles() const -{ - QStringList all; - populateFileNames(&all, m_files.at(ImplementationFile).values()); - populateFileNames(&all, m_files.at(HeaderFile).values()); - return all; -} - -bool IndexerPrivate::isTrackingFile(const QString &fileName, FileType type) const -{ - return m_files.value(type).contains(normalizeFileName(fileName)); -} - -QStringList IndexerPrivate::compilationOptions(const QString &fileName) const -{ - FileType type = identifyFileType(fileName); - return Utils::createClangOptions(m_files.value(type).value(normalizeFileName(fileName)).m_projectPart); -} - -IndexerPrivate::FileType IndexerPrivate::identifyFileType(const QString &fileName) -{ - const QString fn = fileName.toLower(); - if (fn.endsWith(QLatin1String(".cpp")) - || fn.endsWith(QLatin1String(".cxx")) - || fn.endsWith(QLatin1String(".cc")) - || fn.endsWith(QLatin1String(".c")) - || fn.endsWith(QLatin1String(".m")) - || fn.endsWith(QLatin1String(".mm"))) { - return ImplementationFile; - } - - // Everything that is not an implementation file is treated as a header. This makes things - // easier when handling standard library files and any other file that does not use - // conventional suffixes. - return HeaderFile; -} - -void IndexerPrivate::populateFileNames(QStringList *all, const QList &data) -{ - foreach (const FileData &fileData, data) - all->append(fileData.m_fileName); -} - - -namespace { - -struct DepedencyVisitor -{ - DepedencyVisitor(IndexerPrivate *indexer) : m_indexer(indexer) {} - - bool acceptFile(const QString &includer) - { - IndexerPrivate::FileType fileType = IndexerPrivate::identifyFileType(includer); - if (m_indexer->isTrackingFile(includer, fileType)) { - m_match = m_indexer->m_files.at(fileType).value(includer); - return true; - } - return false; - } - - IndexerPrivate *m_indexer; - IndexerPrivate::FileData m_match; -}; - -} // Anonymous - -void IndexerPrivate::startLoading() -{ - // In the case of existent persisted symbols, we restore them and make them visible - // to the indexer. However, we need a dependency graph in order to identify the proper - // options. - - if (deserealizeSymbols() && !m_index.isEmpty()) - computeDependencyGraph(); - else - concludeLoading(); -} - -void IndexerPrivate::concludeLoading() -{ - m_isLoaded = true; - run(); -} - -void IndexerPrivate::computeDependencyGraph() -{ - // FIXME -// for (int fileType = ImplementationFile; fileType < TotalFileTypes; ++fileType) { -// QHash::iterator it = m_files[fileType].begin(); -// for (; it != m_files[fileType].end(); ++it) -// m_dependencyGraph.addFile(it.value().m_fileName, it.value().m_compilationOptions); -// } - - m_loadingWatcher.reset(new QFutureWatcher); - connect(m_loadingWatcher.data(), SIGNAL(finished()), this, SLOT(dependencyGraphComputed())); -// m_loadingWatcher->setFuture(m_dependencyGraph.compute()); -} - -void IndexerPrivate::dependencyGraphComputed() -{ - if (m_loadingWatcher->isCanceled()) - return; - - m_loadingWatcher.reset(new QFutureWatcher); - connect(m_loadingWatcher.data(), SIGNAL(finished()), this, SLOT(restoredSymbolsAnalysed())); - m_loadingWatcher->setFuture(QtConcurrent::run(this, &IndexerPrivate::analyzeRestoredSymbols)); -} - -void IndexerPrivate::analyzeRestoredSymbols() -{ - // @TODO: We only check for time stamps, so we still need to handle somehow the case in - // which the project options (for example a .pro file) changed while "outside" a Creator - // session. - - foreach (const QString &fileName, m_index.files()) { - bool upToDate = m_index.validate(fileName); - - FileType fileType = identifyFileType(fileName); - if (isTrackingFile(fileName, fileType)) { - // When the file is already being tracked we simply need to update its state. - if (upToDate) - m_files[fileType][fileName].m_upToDate = true; - } else { - // If it's not being tracked we need to find at least one tracked dependency - // so we can use its options. - DepedencyVisitor visitor(this); -// m_dependencyGraph.collectDependencies(fileName, -// DependencyGraph::FilesWhichInclude, -// &visitor); - if (!visitor.m_match.m_fileName.isEmpty()) { - addOrUpdateFileData(fileName, - visitor.m_match.m_projectPart, - upToDate); - } else { - m_index.removeFile(fileName); - } - } - - if (!upToDate && m_index.containsFile(fileName)) - m_index.removeFile(fileName); - } -} - -void IndexerPrivate::runQuickIndexing(const Unit::Ptr &unit, const CppTools::ProjectPart::Ptr &part) -{ - QMutexLocker locker(&m_mutex); - - addOrUpdateFileData(unit->fileName(), part, false); - - QuickIndexer indexer(this, unit, part); - indexer.run(); -} - -void IndexerPrivate::restoredSymbolsAnalysed() -{ - if (m_loadingWatcher->isCanceled()) - return; - - concludeLoading(); -} - -bool IndexerPrivate::deserealizeSymbols() -{ - if (m_storagePath.isEmpty()) - return false; - - ::Utils::FileReader reader; - if (reader.fetch(m_storagePath)) { - m_index.deserialize(reader.data()); - return true; - } - - return false; -} - -void IndexerPrivate::serializeSymbols() const -{ - if (m_storagePath.isEmpty()) - return; - - ::Utils::FileSaver saver(m_storagePath); - saver.write(m_index.serialize()); - if (!saver.finalize()) - qWarning("Failed to serialize index"); -} - -QList IndexerPrivate::symbols(Symbol::Kind kind) const -{ - if (m_loadingWatcher->isRunning()) - return QList(); - - return m_index.symbols(kind); -} - -QList IndexerPrivate::symbols(const QString &fileName, const Symbol::Kind kind) const -{ - if (m_loadingWatcher->isRunning()) - return QList(); - - if (kind == Symbol::Unknown) - return m_index.symbols(fileName); - - return m_index.symbols(fileName, kind); -} - -void IndexerPrivate::match(ClangSymbolSearcher *searcher) const -{ - if (m_loadingWatcher->isRunning()) - return; - - m_index.match(searcher); -} - -Indexer::Indexer(QObject *parent) - : QObject(parent) - , m_d(new IndexerPrivate(this)) -{} - -Indexer::~Indexer() -{} - -void Indexer::regenerate() -{ - if (!m_d->m_isLoaded) { - if (m_d->m_loadingWatcher->isRunning()) - return; - m_d->startLoading(); - } else { - m_d->run(); - } -} - -void Indexer::initialize(const QString &storagePath) -{ - Q_ASSERT(!m_d->m_isLoaded); - - m_d->m_storagePath = storagePath; -} - -void Indexer::evaluateFile(const QString &fileName) -{ - if (!m_d->m_isLoaded) - return; - - m_d->run(QStringList(normalizeFileName(fileName))); -} - -bool Indexer::isBusy() const -{ - return m_d->isBusy(); -} - -void Indexer::cancel(bool waitForFinished) -{ - return m_d->cancel(waitForFinished); -} - -void Indexer::finalize() -{ - m_d->reset(); -} - -bool Indexer::addFile(const QString &fileName, ProjectPart::Ptr projectPart) -{ - return m_d->addFile(fileName, projectPart); -} - -QStringList Indexer::allFiles() const -{ - return m_d->allFiles(); -} - -QStringList Indexer::compilationOptions(const QString &fileName) const -{ - return m_d->compilationOptions(fileName); -} - -QList Indexer::allFunctions() const -{ - return m_d->symbols(Symbol::Function); -} - -QList Indexer::allClasses() const -{ - return m_d->symbols(Symbol::Class); -} - -QList Indexer::allMethods() const -{ - return m_d->symbols(Symbol::Method); -} - -QList Indexer::allConstructors() const -{ - return m_d->symbols(Symbol::Constructor); -} - -QList Indexer::allDestructors() const -{ - return m_d->symbols(Symbol::Destructor); -} - -QList Indexer::functionsFromFile(const QString &fileName) const -{ - return m_d->symbols(fileName, Symbol::Function); -} - -QList Indexer::classesFromFile(const QString &fileName) const -{ - return m_d->symbols(fileName, Symbol::Class); -} - -QList Indexer::methodsFromFile(const QString &fileName) const -{ - return m_d->symbols(fileName, Symbol::Method); -} - -QList Indexer::constructorsFromFile(const QString &fileName) const -{ - return m_d->symbols(fileName, Symbol::Constructor); -} - -QList Indexer::destructorsFromFile(const QString &fileName) const -{ - return m_d->symbols(fileName, Symbol::Destructor); -} - -QList Indexer::allFromFile(const QString &fileName) const -{ - return m_d->symbols(fileName, Symbol::Unknown); -} - -void Indexer::match(ClangSymbolSearcher *searcher) const -{ - m_d->match(searcher); -} - -void Indexer::runQuickIndexing(Unit::Ptr unit, const CppTools::ProjectPart::Ptr &part) -{ - m_d->runQuickIndexing(unit, part); -} - -bool Indexer::isTracking(const QString &fileName) const -{ - return m_d->isTrackingFile(fileName, IndexerPrivate::ImplementationFile) - || m_d->isTrackingFile(fileName, IndexerPrivate::HeaderFile); -} - -#include "indexer.moc" diff --git a/src/plugins/clangcodemodel/indexer.h b/src/plugins/clangcodemodel/indexer.h deleted file mode 100644 index dbe352ae58a..00000000000 --- a/src/plugins/clangcodemodel/indexer.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef INDEXER_H -#define INDEXER_H - -#include "clang_global.h" -#include "clangsymbol.h" -#include "unit.h" - -#include - -#include -#include -#include -#include -#include - -namespace ClangCodeModel { - -namespace Internal { class ClangSymbolSearcher; } - -class IndexerPrivate; - -class CLANG_EXPORT Indexer : public QObject -{ - Q_OBJECT - -public: - typedef CppTools::ProjectPart ProjectPart; - -public: - Indexer(QObject *parent = 0); - ~Indexer(); - - void initialize(const QString &storagePath); - void finalize(); - - void regenerate(); - void evaluateFile(const QString &fileName); - bool isBusy() const; - void cancel(bool waitForFinished); - - bool addFile(const QString &fileName, ProjectPart::Ptr projectPart); - QStringList allFiles() const; - QStringList compilationOptions(const QString &fileName) const; - - QList allFunctions() const; - QList allClasses() const; - QList allMethods() const; - QList allConstructors() const; - QList allDestructors() const; - QList functionsFromFile(const QString &fileName) const; - QList classesFromFile(const QString &fileName) const; - QList methodsFromFile(const QString &fileName) const; - QList constructorsFromFile(const QString &fileName) const; - QList destructorsFromFile(const QString &fileName) const; - QList allFromFile(const QString &fileName) const; - - void match(Internal::ClangSymbolSearcher *searcher) const; - - void runQuickIndexing(Internal::Unit::Ptr unit, const ProjectPart::Ptr &part); - - bool isTracking(const QString &fileName) const; - -signals: - void indexingStarted(QFuture future); - void indexingFinished(); - -private: - friend class IndexerPrivate; - QScopedPointer m_d; -}; - -} // ClangCodeModel - -#endif // INDEXER_H diff --git a/src/plugins/clangcodemodel/pchmanager.cpp b/src/plugins/clangcodemodel/pchmanager.cpp index 11cf0abcba3..abda6ff8730 100644 --- a/src/plugins/clangcodemodel/pchmanager.cpp +++ b/src/plugins/clangcodemodel/pchmanager.cpp @@ -29,7 +29,7 @@ ****************************************************************************/ #include "pchmanager.h" -#include "utils.h" +#include "unit.h" #include "clangutils.h" #include @@ -44,6 +44,70 @@ using namespace ClangCodeModel; using namespace ClangCodeModel::Internal; using namespace CPlusPlus; +namespace { + +QString getQString(const CXString &cxString, bool disposeCXString = true) +{ + QString s = QString::fromUtf8(clang_getCString(cxString)); + if (disposeCXString) + clang_disposeString(cxString); + return s; +} + +QStringList formattedDiagnostics(const Unit::Ptr &unit) +{ + QStringList diags; + if (!unit->isLoaded()) + return diags; + + const unsigned count = unit->getNumDiagnostics(); + for (unsigned i = 0; i < count; ++i) { + CXDiagnostic diag = unit->getDiagnostic(i); + + unsigned opt = CXDiagnostic_DisplaySourceLocation + | CXDiagnostic_DisplayColumn + | CXDiagnostic_DisplaySourceRanges + | CXDiagnostic_DisplayOption + | CXDiagnostic_DisplayCategoryId + | CXDiagnostic_DisplayCategoryName + ; + diags << getQString(clang_formatDiagnostic(diag, opt)); + clang_disposeDiagnostic(diag); + } + + return diags; +} + +/** + * Utility method to create a PCH file from a header file. + * + * \returns a boolean indicating success (true) or failure (false), and a + * list of diagnostic messages. + */ +QPair precompile(const PchInfo::Ptr &pchInfo) +{ +// qDebug() << "*** Precompiling" << pchInfo->inputFileName() +// << "into" << pchInfo->fileName() +// << "with options" << pchInfo->options(); + + bool ok = false; + + Unit::Ptr unit = Unit::create(pchInfo->inputFileName()); + unit->setCompilationOptions(pchInfo->options()); + + unsigned parseOpts = CXTranslationUnit_ForSerialization + | CXTranslationUnit_Incomplete; + unit->setManagementOptions(parseOpts); + + unit->parse(); + if (unit->isLoaded()) + ok = CXSaveError_None == unit->save(pchInfo->fileName()); + + return qMakePair(ok, formattedDiagnostics(unit)); +} + +} // anonymous namespace + PchManager *PchManager::m_instance = 0; PchManager::PchManager(QObject *parent) diff --git a/src/plugins/clangcodemodel/semanticmarker.cpp b/src/plugins/clangcodemodel/semanticmarker.cpp deleted file mode 100644 index 274e28e5ca6..00000000000 --- a/src/plugins/clangcodemodel/semanticmarker.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "semanticmarker.h" -#include "unit.h" -#include "utils_p.h" -#include "cxraii.h" - -#include -#include - -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; - -static const unsigned ATTACHED_NOTES_LIMIT = 10; - -SemanticMarker::SemanticMarker() -{ -} - -SemanticMarker::~SemanticMarker() -{ -} - -QString SemanticMarker::fileName() const -{ - if (!m_unit) - return QString(); - - return m_unit->fileName(); -} - -void SemanticMarker::setFileName(const QString &fileName) -{ - if (this->fileName() == fileName) - return; - - QStringList oldOptions; - if (m_unit) - oldOptions = m_unit->compilationOptions(); - m_unit = Unit::create(fileName); - if (!oldOptions.isEmpty()) - m_unit->setCompilationOptions(oldOptions); - - unsigned clangOpts = clang_defaultEditingTranslationUnitOptions(); - clangOpts |= CXTranslationUnit_DetailedPreprocessingRecord; - clangOpts |= CXTranslationUnit_Incomplete; - clangOpts &= ~CXTranslationUnit_CacheCompletionResults; - m_unit->setManagementOptions(clangOpts); -} - -void SemanticMarker::setCompilationOptions(const QStringList &options) -{ - QTC_ASSERT(m_unit, return); - - if (m_unit->compilationOptions() == options) - return; - - m_unit->setCompilationOptions(options); - m_unit->unload(); -} - -void SemanticMarker::reparse(const UnsavedFiles &unsavedFiles) -{ - QTC_ASSERT(m_unit, return); - - m_unit->setUnsavedFiles(unsavedFiles); - if (m_unit->isLoaded()) - m_unit->reparse(); - else - m_unit->parse(); -} - -/** - * \brief Calculate one or several ranges and append diagnostic for each range - * Extracted from SemanticMarker::diagnostics() to reuse code - */ -static void appendDiagnostic(const CXDiagnostic &diag, - const CXSourceLocation &cxLocation, - Diagnostic::Severity severity, - const QString &spelling, - QList &diagnostics) -{ - const unsigned rangeCount = clang_getDiagnosticNumRanges(diag); - bool expandLocation = true; - - for (unsigned i = 0; i < rangeCount; ++i) { - CXSourceRange r = clang_getDiagnosticRange(diag, i); - const SourceLocation &spellBegin = Internal::getSpellingLocation(clang_getRangeStart(r)); - const SourceLocation &spellEnd = Internal::getSpellingLocation(clang_getRangeEnd(r)); - unsigned length = spellEnd.offset() - spellBegin.offset(); - - // File name can be empty due clang bug - if (!spellBegin.fileName().isEmpty()) { - Diagnostic d(severity, spellBegin, length, spelling); - diagnostics.append(d); - expandLocation = false; - } - } - - if (expandLocation) { - const SourceLocation &location = Internal::getExpansionLocation(cxLocation); - Diagnostic d(severity, location, 0, spelling); - diagnostics.append(d); - } -} - -static bool isBlackListedDiagnostic(const Utils::MimeType &mimeType, const QString &diagnostic) -{ - static const QStringList blackList { - QLatin1String("#pragma once in main file"), - QLatin1String("#include_next in primary source file") - }; - - return mimeType.inherits(QLatin1String("text/x-chdr")) && blackList.contains(diagnostic); -} - -QList SemanticMarker::diagnostics() const -{ - QList diagnostics; - if (!m_unit || !m_unit->isLoaded()) - return diagnostics; - - Utils::MimeDatabase mimeDatabase; - const Utils::MimeType mimeType = mimeDatabase.mimeTypeForFile(fileName()); - - const unsigned diagCount = m_unit->getNumDiagnostics(); - for (unsigned i = 0; i < diagCount; ++i) { - ScopedCXDiagnostic diag(m_unit->getDiagnostic(i)); - - Diagnostic::Severity severity = static_cast(clang_getDiagnosticSeverity(diag)); - if (severity == Diagnostic::Ignored || severity == Diagnostic::Note) - continue; - - CXSourceLocation cxLocation = clang_getDiagnosticLocation(diag); - QString spelling = Internal::getQString(clang_getDiagnosticSpelling(diag)); - - if (isBlackListedDiagnostic(mimeType, spelling)) - continue; - - // Attach messages with Diagnostic::Note severity - ScopedCXDiagnosticSet cxChildren(clang_getChildDiagnostics(diag)); - const unsigned numChildren = clang_getNumDiagnosticsInSet(cxChildren); - const unsigned size = qMin(ATTACHED_NOTES_LIMIT, numChildren); - for (unsigned di = 0; di < size; ++di) { - ScopedCXDiagnostic child(clang_getDiagnosticInSet(cxChildren, di)); - - const Diagnostic::Severity severity - = static_cast(clang_getDiagnosticSeverity(child)); - if (severity == Diagnostic::Ignored || severity == Diagnostic::Note) - continue; - - spelling.append(QLatin1String("\n ")); - spelling.append(Internal::getQString(clang_getDiagnosticSpelling(child))); - } - - // Fatal error may occur in another file, but it breaks whole parsing - // Typical fatal error is unresolved #include - if (severity == Diagnostic::Fatal) { - for (unsigned di = 0; di < numChildren; ++di) { - ScopedCXDiagnostic child(clang_getDiagnosticInSet(cxChildren, di)); - appendDiagnostic(child, clang_getDiagnosticLocation(child), Diagnostic::Warning, spelling, diagnostics); - } - } - - appendDiagnostic(diag, cxLocation, severity, spelling, diagnostics); - } - - return diagnostics; -} - -QList SemanticMarker::ifdefedOutBlocks() const -{ - QList blocks; - - if (!m_unit || !m_unit->isLoaded()) - return blocks; - -#if CINDEX_VERSION_MINOR >= 21 - CXSourceRangeList *skippedRanges = clang_getSkippedRanges(m_unit->clangTranslationUnit(), - m_unit->getFile()); - blocks.reserve(skippedRanges->count); - for (unsigned i = 0; i < skippedRanges->count; ++i) { - const CXSourceRange &r = skippedRanges->ranges[i]; - const SourceLocation &spellBegin = Internal::getSpellingLocation(clang_getRangeStart(r)); - if (spellBegin.fileName() != fileName()) - continue; - const SourceLocation &spellEnd = Internal::getSpellingLocation(clang_getRangeEnd(r)); - const int begin = spellBegin.offset() + 1; - const int end = spellEnd.offset() - spellEnd.column(); - blocks.append(Range(begin, end)); - } - clang_disposeSourceRangeList(skippedRanges); -#endif - - return blocks; -} - -namespace { -static void add(QList &markers, - const CXSourceRange &extent, - SourceMarker::Kind kind) -{ - CXSourceLocation start = clang_getRangeStart(extent); - CXSourceLocation end = clang_getRangeEnd(extent); - const SourceLocation &location = Internal::getExpansionLocation(start); - const SourceLocation &locationEnd = Internal::getExpansionLocation(end); - - if (location.offset() < locationEnd.offset()) { - const unsigned length = locationEnd.offset() - location.offset(); - markers.append(SourceMarker(location, length, kind)); - } -} - -/** - * @brief Selects correct highlighting for cursor that is reference - * @return SourceMarker::Unknown if cannot select highlighting - */ -static SourceMarker::Kind getKindByReferencedCursor(const CXCursor &cursor) -{ - const CXCursor referenced = clang_getCursorReferenced(cursor); - switch (clang_getCursorKind(referenced)) { - case CXCursor_EnumConstantDecl: - return SourceMarker::Enumeration; - - case CXCursor_FieldDecl: - case CXCursor_ObjCIvarDecl: - case CXCursor_ObjCPropertyDecl: - return SourceMarker::Field; - - case CXCursor_FunctionDecl: - case CXCursor_FunctionTemplate: - case CXCursor_Constructor: - return SourceMarker::Function; - - case CXCursor_VarDecl: - case CXCursor_ParmDecl: - case CXCursor_NonTypeTemplateParameter: - return SourceMarker::Local; - - case CXCursor_CXXMethod: - if (clang_CXXMethod_isVirtual(referenced)) - return SourceMarker::VirtualMethod; - else - return SourceMarker::Function; - - case CXCursor_ObjCClassMethodDecl: - case CXCursor_ObjCInstanceMethodDecl: - // calling method as property, e.h. "layer.shouldRasterize = YES" - return SourceMarker::Field; - - case CXCursor_UnexposedDecl: - // NSObject "self" method which is a pseudo keyword - if (clang_getCursorLanguage(referenced) == CXLanguage_ObjC) - return SourceMarker::PseudoKeyword; - break; - - default: - break; - } - return SourceMarker::Unknown; -} - -static const QSet ObjcPseudoKeywords = QSet() - << QLatin1String("end") - << QLatin1String("try") - << QLatin1String("defs") - << QLatin1String("throw") - << QLatin1String("class") - << QLatin1String("catch") - << QLatin1String("encode") - << QLatin1String("public") - << QLatin1String("dynamic") - << QLatin1String("finally") - << QLatin1String("package") - << QLatin1String("private") - << QLatin1String("optional") - << QLatin1String("property") - << QLatin1String("protocol") - << QLatin1String("required") - << QLatin1String("selector") - << QLatin1String("interface") - << QLatin1String("protected") - << QLatin1String("synthesize") - << QLatin1String("not_keyword") - << QLatin1String("synchronized") - << QLatin1String("implementation") - << QLatin1String("compatibility_alias") - ; - -} // Anonymous namespace - -/** - * @brief SemanticMarker::sourceMarkersInRange - * @param firstLine - first line where to generate highlighting markers - * @param lastLine - last line where to generate highlighting markers - * - * There still two kinds of problems: - * - clang_annotateTokens() can return wrong cursor, and it's normal behavior - * - some cases no handled - * - * Problems caused by wrong cursors: - * - range-based for from C++ 2011 - * - identifiers in some compound statements have type DeclStmt - * or CompoundStmt which refers to top-level construction. - * - CXCursor_ObjCIvarDecl mapped to field, but instance variable have - * incorrect cursor kind if it declared in private interface - * @interface MyApplication() { - * NSArray* _items; - * } - * - * Missed cases: - * - global variables highlighted as locals - * - appropriate marker had not been selected for listed cursors: - * CXCursor_ObjCProtocolExpr, CXCursor_ObjCEncodeExpr, - * CXCursor_ObjCDynamicDecl, CXCursor_ObjCBridgedCastExpr, - * CXCursor_ObjCSuperClassRef - * - template members of template classes&functions always highlighted - * as members, even if they are functions - no way to differ found. - * - @1, @{}, @[] - */ -QList SemanticMarker::sourceMarkersInRange(unsigned firstLine, - unsigned lastLine) -{ - QList result; - - if (!m_unit || !m_unit->isLoaded()) - return result; - - // Highlighting called asynchronously, and a few lines at the end can be deleted for this time. - CXSourceRange unitRange = clang_getCursorExtent(m_unit->getTranslationUnitCursor()); - SourceLocation unitEnd = getExpansionLocation(clang_getRangeEnd(unitRange)); - if (lastLine > unitEnd.line()) - lastLine = unitEnd.line(); - - if (firstLine > lastLine) - return result; - - IdentifierTokens idTokens(*m_unit, firstLine, lastLine); - - const CXSourceRange *atTokenExtent = 0; - for (unsigned i = 0; i < idTokens.count(); ++i) { - const CXToken &tok = idTokens.token(i); - CXTokenKind kind = clang_getTokenKind(tok); - if (atTokenExtent) { - if (CXToken_Literal == kind) { - if (m_unit->getTokenSpelling(tok).startsWith(QLatin1Char('"'))) - add(result, *atTokenExtent, SourceMarker::ObjCString); - atTokenExtent = 0; - continue; - } else { - add(result, *atTokenExtent, SourceMarker::PseudoKeyword); - atTokenExtent = 0; - } - } - - const CXSourceRange &tokenExtent = idTokens.extent(i); - - if (CXToken_Keyword == kind) { - QString spell = m_unit->getTokenSpelling(tok); - if (ObjcPseudoKeywords.contains(spell)) - add(result, tokenExtent, SourceMarker::PseudoKeyword); - continue; - } - - if (CXToken_Punctuation == kind) { - static const QLatin1String at("@"); - if (m_unit->getTokenSpelling(tok) == at) - atTokenExtent = &tokenExtent; - continue; - } - - if (CXToken_Identifier != kind) - continue; - - const CXCursor &cursor = idTokens.cursor(i); - const CXCursorKind cursorKind = clang_getCursorKind(cursor); - if (clang_isInvalid(cursorKind)) - continue; - - switch (cursorKind) { - case CXCursor_EnumConstantDecl: - add(result, tokenExtent, SourceMarker::Enumeration); - break; - - case CXCursor_ClassDecl: - case CXCursor_UnionDecl: - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - case CXCursor_EnumDecl: - case CXCursor_Namespace: - case CXCursor_NamespaceRef: - case CXCursor_NamespaceAlias: - case CXCursor_StructDecl: - case CXCursor_TemplateRef: - case CXCursor_TypeRef: - case CXCursor_TypedefDecl: - case CXCursor_Constructor: - case CXCursor_TemplateTypeParameter: - case CXCursor_TemplateTemplateParameter: - case CXCursor_UnexposedDecl: /* friend class MyClass; */ - add(result, tokenExtent, SourceMarker::Type); - break; - - case CXCursor_ParmDecl: - case CXCursor_VariableRef: - case CXCursor_VarDecl: - case CXCursor_NonTypeTemplateParameter: - add(result, tokenExtent, SourceMarker::Local); - break; - - case CXCursor_MemberRefExpr: - case CXCursor_MemberRef: - case CXCursor_DeclRefExpr: - case CXCursor_CallExpr: { - SourceMarker::Kind kind = getKindByReferencedCursor(cursor); - if (kind == SourceMarker::Unknown && cursorKind == CXCursor_MemberRefExpr) { - /* template class member in template function */ - kind = SourceMarker::Field; - } - if (kind != SourceMarker::Unknown) - add(result, tokenExtent, kind); - } break; - - case CXCursor_FieldDecl: - add(result, tokenExtent, SourceMarker::Field); - break; - - case CXCursor_Destructor: - case CXCursor_CXXMethod: { - if (clang_CXXMethod_isVirtual(cursor)) - add(result, tokenExtent, SourceMarker::VirtualMethod); - else - add(result, tokenExtent, SourceMarker::Function); - } break; - - case CXCursor_CXXOverrideAttr: - case CXCursor_CXXFinalAttr: - case CXCursor_AnnotateAttr: // 'annotate' in '__attribute__((annotate("AnyComment")))' - case CXCursor_UnexposedAttr: // 'align' in '__declspec(align(8))' - add(result, tokenExtent, SourceMarker::PseudoKeyword); - break; - - case CXCursor_FunctionDecl: - case CXCursor_FunctionTemplate: - case CXCursor_OverloadedDeclRef: - add(result, tokenExtent, SourceMarker::Function); - break; - - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_ObjCClassMethodDecl: - case CXCursor_ObjCSelectorExpr: - add(result, tokenExtent, SourceMarker::ObjectiveCMessage); - break; - - case CXCursor_ObjCMessageExpr: { - static const QLatin1String super("super"); - if (m_unit->getTokenSpelling(tok) == super) - add(result, tokenExtent, SourceMarker::PseudoKeyword); - else - add(result, tokenExtent, SourceMarker::ObjectiveCMessage); - } break; - - case CXCursor_ObjCCategoryDecl: - case CXCursor_ObjCCategoryImplDecl: - case CXCursor_ObjCImplementationDecl: - case CXCursor_ObjCInterfaceDecl: - case CXCursor_ObjCProtocolDecl: - case CXCursor_ObjCProtocolRef: - case CXCursor_ObjCClassRef: - case CXCursor_ObjCSuperClassRef: - case CXCursor_TypeAliasDecl: // C++11 type alias: 'using value_t = T' - add(result, tokenExtent, SourceMarker::Type); - break; - - case CXCursor_ObjCSynthesizeDecl: - case CXCursor_ObjCDynamicDecl: - case CXCursor_ObjCPropertyDecl: - case CXCursor_ObjCIvarDecl: - add(result, tokenExtent, SourceMarker::Field); - break; - - case CXCursor_MacroDefinition: - case CXCursor_MacroExpansion: - add(result, tokenExtent, SourceMarker::Macro); - break; - - case CXCursor_LabelRef: - case CXCursor_LabelStmt: - add(result, tokenExtent, SourceMarker::Label); - break; - - default: - break; - } - } - - return result; -} - -Unit::Ptr SemanticMarker::unit() const -{ - return m_unit; -} diff --git a/src/plugins/clangcodemodel/semanticmarker.h b/src/plugins/clangcodemodel/semanticmarker.h deleted file mode 100644 index 238555b6665..00000000000 --- a/src/plugins/clangcodemodel/semanticmarker.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANG_SEMANTICMARKER_H -#define CLANG_SEMANTICMARKER_H - -#include "clang_global.h" -#include "diagnostic.h" -#include "fastindexer.h" -#include "sourcemarker.h" -#include "utils.h" - -#include -#include -#include -#include -#include - -namespace ClangCodeModel { - -class CLANG_EXPORT SemanticMarker -{ - Q_DISABLE_COPY(SemanticMarker) - -public: - typedef QSharedPointer Ptr; - - class Range - { - Range(); - public: - Range(int first, int last) : first(first), last(last) {} - - int first; - int last; - }; - -public: - SemanticMarker(); - ~SemanticMarker(); - - QMutex *mutex() const - { return &m_mutex; } - - QString fileName() const; - void setFileName(const QString &fileName); - - void setCompilationOptions(const QStringList &options); - - void reparse(const Internal::UnsavedFiles &unsavedFiles); - - QList diagnostics() const; - - QList ifdefedOutBlocks() const; - - QList sourceMarkersInRange(unsigned firstLine, - unsigned lastLine); - - Internal::Unit::Ptr unit() const; - -private: - mutable QMutex m_mutex; - Internal::Unit::Ptr m_unit; -}; - -} // namespace ClangCodeModel - -#endif // CLANG_SEMANTICMARKER_H diff --git a/src/plugins/clangcodemodel/sourcelocation.cpp b/src/plugins/clangcodemodel/sourcelocation.cpp deleted file mode 100644 index 2a48d4ed6cc..00000000000 --- a/src/plugins/clangcodemodel/sourcelocation.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "sourcelocation.h" - -using namespace ClangCodeModel; - -SourceLocation::SourceLocation() - : m_line(0) - , m_column(0) - , m_offset(0) -{} - -SourceLocation::SourceLocation(const QString &fileName, - unsigned line, - unsigned column, - unsigned offset) - : m_fileName(fileName) - , m_line(line) - , m_column(column) - , m_offset(offset) -{} - -namespace ClangCodeModel { - -bool operator==(const SourceLocation &a, const SourceLocation &b) -{ - return a.line() == b.line() - && a.column() == b.column() - && a.offset() == b.offset() - && a.fileName() == b.fileName() - ; -} - -bool operator!=(const SourceLocation &a, const SourceLocation &b) -{ - return !(a == b); -} - -QDebug operator<<(QDebug dbg, const SourceLocation &location) -{ - dbg.nospace() << location.fileName() - << " [" - << location.line() - << ":" - << location.column() - << "(" - << location.offset() - << ")]"; - return dbg.space(); -} - -} // ClangCodeModel diff --git a/src/plugins/clangcodemodel/sourcelocation.h b/src/plugins/clangcodemodel/sourcelocation.h deleted file mode 100644 index fab53ac720e..00000000000 --- a/src/plugins/clangcodemodel/sourcelocation.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef SOURCELOCATION_H -#define SOURCELOCATION_H - -#include "clang_global.h" - -#include -#include - -namespace ClangCodeModel { - -class CLANG_EXPORT SourceLocation -{ -public: - SourceLocation(); - SourceLocation(const QString &fileName, - unsigned line = 0, - unsigned column = 0, - unsigned offset = 0); - - bool isNull() const { return m_fileName.isEmpty(); } - const QString &fileName() const { return m_fileName; } - unsigned line() const { return m_line; } - unsigned column() const { return m_column; } - unsigned offset() const { return m_offset; } - -private: - QString m_fileName; - unsigned m_line; - unsigned m_column; - unsigned m_offset; -}; - -bool operator==(const SourceLocation &a, const SourceLocation &b); -bool operator!=(const SourceLocation &a, const SourceLocation &b); - -QDebug operator<<(QDebug dbg, const SourceLocation &location); - -} // ClangCodeModel - -#endif // SOURCELOCATION_H diff --git a/src/plugins/clangcodemodel/sourcemarker.cpp b/src/plugins/clangcodemodel/sourcemarker.cpp deleted file mode 100644 index 3566bc4b1df..00000000000 --- a/src/plugins/clangcodemodel/sourcemarker.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "sourcemarker.h" - -using namespace ClangCodeModel; - -SourceMarker::SourceMarker() - : m_length(0), m_kind(Unknown) -{} - -SourceMarker::SourceMarker(const SourceLocation &location, unsigned length, Kind kind) - : m_loc(location), m_length(length), m_kind(kind) -{ -} diff --git a/src/plugins/clangcodemodel/sourcemarker.h b/src/plugins/clangcodemodel/sourcemarker.h deleted file mode 100644 index eaf014ca525..00000000000 --- a/src/plugins/clangcodemodel/sourcemarker.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANG_SOURCEMARKER_H -#define CLANG_SOURCEMARKER_H - -#include "clang_global.h" -#include "sourcelocation.h" - -namespace ClangCodeModel { - -class CLANG_EXPORT SourceMarker -{ -public: // TODO: remove this, it's about the same as the TextEditor::SemanticHighlighter::Result - enum Kind { - Unknown = 0, - Type = 1, - Local, - Field, - Enumeration, - VirtualMethod, - Label, - Macro, - Function, - PseudoKeyword, - ObjCString, - - ObjectiveCMessage = VirtualMethod - }; - - SourceMarker(); - SourceMarker(const SourceLocation &location, - unsigned length, - Kind kind); - - bool isValid() const - { return m_loc.line() != 0; } - - bool isInvalid() const - { return m_loc.line() == 0; } - - const SourceLocation &location() const - { return m_loc; } - - unsigned length() const - { return m_length; } - - Kind kind() const - { return m_kind; } - - bool lessThan(const SourceMarker &other) const - { - if (m_loc.line() != other.m_loc.line()) - return m_loc.line() < other.m_loc.line(); - if (m_loc.column() != other.m_loc.column()) - return m_loc.column() < other.m_loc.column(); - return m_length < other.m_length; - } - -private: - SourceLocation m_loc; - unsigned m_length; - Kind m_kind; -}; - -CLANG_EXPORT inline bool operator<(const SourceMarker &one, const SourceMarker &two) -{ return one.lessThan(two); } - -} // namespace Clang - -#endif // CLANG_SOURCEMARKER_H diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 01d5cdbbef7..fca3051875d 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -179,7 +179,7 @@ bool writeFile(const QString &filePath, const QByteArray &contents) void insertTextAtTopOfEditor(TextEditor::BaseTextEditor *editor, const QByteArray &text) { QTC_ASSERT(editor, return); - Utils::ChangeSet cs; + ::Utils::ChangeSet cs; cs.insert(0, QString::fromUtf8(text)); QTextCursor textCursor = editor->textCursor(); cs.apply(&textCursor); @@ -1099,7 +1099,7 @@ void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderByRefactor // Modify header document without switching to its editor. // This simulates e.g. changes from refactoring actions. - Utils::ChangeSet cs; + ::Utils::ChangeSet cs; cs.insert(0, QLatin1String("int globalFromHeaderUnsaved;\n")); QTextCursor textCursor = openHeader.editor()->textCursor(); cs.apply(&textCursor); diff --git a/src/plugins/clangcodemodel/unit.cpp b/src/plugins/clangcodemodel/unit.cpp index 89e8963bf2a..83b1aaed932 100644 --- a/src/plugins/clangcodemodel/unit.cpp +++ b/src/plugins/clangcodemodel/unit.cpp @@ -32,7 +32,6 @@ #include "clangutils.h" #include "unsavedfiledata.h" -#include "utils_p.h" #include @@ -105,12 +104,12 @@ void Unit::setCompilationOptions(const QStringList &compOptions) m_sharedCompOptions.reloadOptions(compOptions); } -UnsavedFiles Unit::unsavedFiles() const +ClangCodeModel::Utils::UnsavedFiles Unit::unsavedFiles() const { return m_unsaved; } -void Unit::setUnsavedFiles(const UnsavedFiles &unsavedFiles) +void Unit::setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles) { m_unsaved = unsavedFiles; } @@ -189,20 +188,6 @@ CXSourceLocation Unit::getLocation(const CXFile &file, unsigned line, unsigned c return clang_getLocation(m_tu, file, line, column); } -void Unit::codeCompleteAt(unsigned line, unsigned column, ScopedCXCodeCompleteResults &results) -{ - unsigned flags = clang_defaultCodeCompleteOptions(); -#if defined(CINDEX_VERSION) && (CINDEX_VERSION > 5) - flags |= CXCodeComplete_IncludeBriefComments; -#endif - - UnsavedFileData unsaved(m_unsaved); - results.reset(clang_codeCompleteAt(m_tu, m_fileName.constData(), - line, column, - unsaved.files(), unsaved.count(), - flags)); -} - void Unit::tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const { Q_ASSERT(isLoaded()); @@ -250,13 +235,6 @@ CXIndex Unit::clangIndex() const return m_index; } -QString Unit::getTokenSpelling(const CXToken &tok) const -{ - Q_ASSERT(isLoaded()); - - return getQString(clang_getTokenSpelling(m_tu, tok)); -} - CXCursor Unit::getTranslationUnitCursor() const { Q_ASSERT(isLoaded()); diff --git a/src/plugins/clangcodemodel/unit.h b/src/plugins/clangcodemodel/unit.h index 2506dc24fed..a32865fe38e 100644 --- a/src/plugins/clangcodemodel/unit.h +++ b/src/plugins/clangcodemodel/unit.h @@ -31,9 +31,10 @@ #ifndef UNIT_H #define UNIT_H -#include "utils.h" +#include "clangutils.h" #include "raii/scopedclangoptions.h" -#include "cxraii.h" + +#include #include #include @@ -95,8 +96,8 @@ public: QStringList compilationOptions() const; void setCompilationOptions(const QStringList &compOptions); - UnsavedFiles unsavedFiles() const; - void setUnsavedFiles(const UnsavedFiles &unsavedFiles); + Utils::UnsavedFiles unsavedFiles() const; + void setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles); unsigned managementOptions() const; void setManagementOptions(unsigned managementOptions); @@ -135,8 +136,6 @@ public: // - Physical source locations CXSourceLocation getLocation(const CXFile &file, unsigned line, unsigned column) const; - void codeCompleteAt(unsigned line, unsigned column, ScopedCXCodeCompleteResults &results); - void tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const; void disposeTokens(CXToken *tokens, unsigned tokenCount) const; CXSourceRange getTokenExtent(const CXToken &token) const; @@ -145,8 +144,6 @@ public: CXTranslationUnit clangTranslationUnit() const; CXIndex clangIndex() const; - QString getTokenSpelling(const CXToken &tok) const; - private: void updateTimeStamp(); @@ -156,7 +153,7 @@ private: QStringList m_compOptions; SharedClangOptions m_sharedCompOptions; unsigned m_managementOptions; - UnsavedFiles m_unsaved; + Utils::UnsavedFiles m_unsaved; QDateTime m_timeStamp; }; diff --git a/src/plugins/clangcodemodel/unsavedfiledata.h b/src/plugins/clangcodemodel/unsavedfiledata.h index c07753854d4..a3b867db278 100644 --- a/src/plugins/clangcodemodel/unsavedfiledata.h +++ b/src/plugins/clangcodemodel/unsavedfiledata.h @@ -31,7 +31,7 @@ #ifndef CLANG_INTERNAL_UNSAVEDFILEDATA_H #define CLANG_INTERNAL_UNSAVEDFILEDATA_H -#include "utils.h" +#include "clangutils.h" #include @@ -43,7 +43,7 @@ class UnsavedFileData UnsavedFileData(const UnsavedFileData &); UnsavedFileData &operator=(const UnsavedFileData &); - typedef ClangCodeModel::Internal::UnsavedFiles UnsavedFiles; + typedef ClangCodeModel::Utils::UnsavedFiles UnsavedFiles; public: UnsavedFileData(const UnsavedFiles &unsavedFiles); diff --git a/src/plugins/clangcodemodel/utils.cpp b/src/plugins/clangcodemodel/utils.cpp deleted file mode 100644 index e7505f52112..00000000000 --- a/src/plugins/clangcodemodel/utils.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "diagnostic.h" -#include "unit.h" -#include "utils.h" -#include "utils_p.h" - -#include - -#include -#include - -namespace ClangCodeModel { -namespace Internal { - -QPair precompile(const PchInfo::Ptr &pchInfo) -{ -// qDebug() << "*** Precompiling" << pchInfo->inputFileName() -// << "into" << pchInfo->fileName() -// << "with options" << pchInfo->options(); - - bool ok = false; - - Internal::Unit::Ptr unit = Internal::Unit::create(pchInfo->inputFileName()); - unit->setCompilationOptions(pchInfo->options()); - - unsigned parseOpts = CXTranslationUnit_ForSerialization - | CXTranslationUnit_Incomplete; - unit->setManagementOptions(parseOpts); - - unit->parse(); - if (unit->isLoaded()) - ok = CXSaveError_None == unit->save(pchInfo->fileName()); - - return qMakePair(ok, Internal::formattedDiagnostics(unit)); -} - -namespace { -static bool clangInitialised = false; -static QMutex initialisationMutex; -} // anonymous namespace - -void initializeClang() -{ - if (clangInitialised) - return; - - QMutexLocker locker(&initialisationMutex); - if (clangInitialised) - return; - - clang_toggleCrashRecovery(1); - clang_enableStackTraces(); - clangInitialised = true; - - qRegisterMetaType(); - qRegisterMetaType >(); -} - -} // Internal namespace -} // ClangCodeModel namespace - diff --git a/src/plugins/clangcodemodel/utils.h b/src/plugins/clangcodemodel/utils.h deleted file mode 100644 index 4126e48eb31..00000000000 --- a/src/plugins/clangcodemodel/utils.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef UTILS_H -#define UTILS_H - -#include "pchinfo.h" - -#include -#include -#include -#include -#include - -/* - * A header for globally visible typedefs. This is particularly useful - * so we don't have to #include files simply because of a typedef. Still, - * not every typedef should go in here, only the minimal subset of the - * ones which are needed quite often. - */ -namespace ClangCodeModel { -namespace Internal { - -typedef QMap UnsavedFiles; - -/** - * Utility method to create a PCH file from a header file. - * - * \returns a boolean indicating success (true) or failure (false), and a - * list of diagnostic messages. - */ -QPair precompile(const PchInfo::Ptr &pchInfo); - -void initializeClang(); - -} // Internal namespace -} // ClangCodeModel namespace - -#endif // UTILS_H diff --git a/src/plugins/clangcodemodel/utils_p.cpp b/src/plugins/clangcodemodel/utils_p.cpp deleted file mode 100644 index 07cec0e523f..00000000000 --- a/src/plugins/clangcodemodel/utils_p.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "unit.h" -#include "utils_p.h" - -#include -#include - -namespace ClangCodeModel { -namespace Internal { - -QString getQString(const CXString &cxString, bool disposeCXString) -{ - QString s = QString::fromUtf8(clang_getCString(cxString)); - if (disposeCXString) - clang_disposeString(cxString); - return s; -} - -namespace { - -SourceLocation getLocation(const CXSourceLocation &loc, - void (*clangFunction)(CXSourceLocation, - CXFile *, - unsigned *, - unsigned *, - unsigned *)) -{ - CXFile file; - unsigned line, column, offset; - (*clangFunction)(loc, &file, &line, &column, &offset); - return SourceLocation(normalizeFileName(getQString(clang_getFileName(file))), - line, - column, - offset); -} - -} // Anonymous - -SourceLocation getInstantiationLocation(const CXSourceLocation &loc) -{ - return getLocation(loc, &clang_getInstantiationLocation); -} - -SourceLocation getSpellingLocation(const CXSourceLocation &loc) -{ - return getLocation(loc, &clang_getSpellingLocation); -} - -SourceLocation getExpansionLocation(const CXSourceLocation &loc) -{ -// return getLocation(loc, &clang_getExpansionLocation); - return getLocation(loc, &clang_getInstantiationLocation); -} - -QString normalizeFileName(const QString &fileName) -{ - if (fileName.isEmpty()) - return fileName; - - return normalizeFileName(QFileInfo(fileName)); -} - -QString normalizeFileName(const QFileInfo &fileInfo) -{ - if (!fileInfo.isFile()) - return QString(); - - return QDir::cleanPath(fileInfo.absoluteFilePath()); -} - -QStringList formattedDiagnostics(const Unit::Ptr &unit) -{ - QStringList diags; - if (!unit->isLoaded()) - return diags; - - const unsigned count = unit->getNumDiagnostics(); - for (unsigned i = 0; i < count; ++i) { - CXDiagnostic diag = unit->getDiagnostic(i); - - unsigned opt = CXDiagnostic_DisplaySourceLocation - | CXDiagnostic_DisplayColumn - | CXDiagnostic_DisplaySourceRanges - | CXDiagnostic_DisplayOption - | CXDiagnostic_DisplayCategoryId - | CXDiagnostic_DisplayCategoryName - ; - diags << getQString(clang_formatDiagnostic(diag, opt)); - clang_disposeDiagnostic(diag); - } - - return diags; -} - -} // Internal -} // ClangCodeModel diff --git a/src/plugins/clangcodemodel/utils_p.h b/src/plugins/clangcodemodel/utils_p.h deleted file mode 100644 index ea0f2837b16..00000000000 --- a/src/plugins/clangcodemodel/utils_p.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANG_REUSE_H -#define CLANG_REUSE_H - -#include "sourcelocation.h" -#include "unit.h" - -#include - -#include - -QT_BEGIN_NAMESPACE -class QFileInfo; -QT_END_NAMESPACE - -namespace ClangCodeModel { -namespace Internal { - -QString getQString(const CXString &cxString, bool disposeCXString = true); - -SourceLocation getInstantiatonLocation(const CXSourceLocation &loc); // Deprecated -SourceLocation getSpellingLocation(const CXSourceLocation &loc); -SourceLocation getExpansionLocation(const CXSourceLocation &loc); - -// There are slight differences of behavior from apparently similar Qt file processing functions. -// For instance, QFileInfo::absoluteFilePath will uppercase driver letters, while the corresponding -// QDir function will not do so. Besides, we need to keep paths clean. So in order to avoid -// inconsistencies the functions below should be used for any indexing related task. -QString normalizeFileName(const QString &fileName); -QString normalizeFileName(const QFileInfo &fileInfo); - -QStringList formattedDiagnostics(const Unit::Ptr &unit); - -} // Internal -} // ClangCodeModel - -#endif // CLANG_REUSE_H From 5f98b8ec24051280dbdbc1fed52300ee15f01701 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 27 Nov 2015 18:21:46 +0100 Subject: [PATCH 20/47] Clang: Remove PchManager ...which is the last dependency to libclang from the plugin. Change-Id: I173ee7e9621912ec88706b4cf62db2b1dbcf7610 Reviewed-by: Marco Bubke Reviewed-by: Nikolai Kosjar --- .../clangbackendipcintegration.cpp | 5 +- src/plugins/clangcodemodel/clangcodemodel.pro | 18 +- src/plugins/clangcodemodel/clangcodemodel.qbs | 16 - .../clangcodemodel/clangcodemodelplugin.cpp | 33 +- .../clangcompletionassistinterface.cpp | 14 - .../clangcompletionassistinterface.h | 5 - .../clangcompletionassistprovider.cpp | 3 - .../clangeditordocumentprocessor.cpp | 1 - .../clangprojectsettingspropertiespage.cpp | 89 --- .../clangprojectsettingspropertiespage.h | 9 +- .../clangprojectsettingspropertiespage.ui | 3 + src/plugins/clangcodemodel/clangutils.cpp | 24 +- src/plugins/clangcodemodel/clangutils.h | 7 +- src/plugins/clangcodemodel/pchinfo.cpp | 63 --- src/plugins/clangcodemodel/pchinfo.h | 81 --- src/plugins/clangcodemodel/pchmanager.cpp | 512 ------------------ src/plugins/clangcodemodel/pchmanager.h | 109 ---- .../raii/scopedclangoptions.cpp | 104 ---- .../clangcodemodel/raii/scopedclangoptions.h | 73 --- src/plugins/clangcodemodel/unit.cpp | 335 ------------ src/plugins/clangcodemodel/unit.h | 197 ------- .../clangcodemodel/unsavedfiledata.cpp | 62 --- src/plugins/clangcodemodel/unsavedfiledata.h | 66 --- 23 files changed, 10 insertions(+), 1819 deletions(-) delete mode 100644 src/plugins/clangcodemodel/pchinfo.cpp delete mode 100644 src/plugins/clangcodemodel/pchinfo.h delete mode 100644 src/plugins/clangcodemodel/pchmanager.cpp delete mode 100644 src/plugins/clangcodemodel/pchmanager.h delete mode 100644 src/plugins/clangcodemodel/raii/scopedclangoptions.cpp delete mode 100644 src/plugins/clangcodemodel/raii/scopedclangoptions.h delete mode 100644 src/plugins/clangcodemodel/unit.cpp delete mode 100644 src/plugins/clangcodemodel/unit.h delete mode 100644 src/plugins/clangcodemodel/unsavedfiledata.cpp delete mode 100644 src/plugins/clangcodemodel/unsavedfiledata.h diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 055099e7c6e..49cb0d795ce 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -34,7 +34,6 @@ #include "clangeditordocumentprocessor.h" #include "clangmodelmanagersupport.h" #include "clangutils.h" -#include "pchmanager.h" #include #include @@ -335,10 +334,8 @@ void IpcCommunicator::initializeBackend() static QStringList projectPartOptions(const CppTools::ProjectPart::Ptr &projectPart) { - QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart, + const QStringList options = ClangCodeModel::Utils::createClangOptions(projectPart, CppTools::ProjectFile::Unclassified); // No language option - if (PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart)) - options += ClangCodeModel::Utils::createPCHInclusionOptions(pchInfo->fileName()); return options; } diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index 9b5ac7ddbfd..ab5e8597a85 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -1,16 +1,12 @@ include(../../qtcreatorplugin.pri) include(../../shared/clang/clang_installation.pri) -LIBS += $$LLVM_LIBS -INCLUDEPATH += $$LLVM_INCLUDEPATH DEFINES += CLANGCODEMODEL_LIBRARY # The following defines are used to determine the clang include path for intrinsics. DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\" DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\"" -unix:QMAKE_LFLAGS += -Wl,-rpath,\'$$LLVM_LIBDIR\' - SOURCES += \ activationsequencecontextprocessor.cpp \ activationsequenceprocessor.cpp \ @@ -36,12 +32,7 @@ SOURCES += \ clangtextmark.cpp \ clangutils.cpp \ completionchunkstotextconverter.cpp \ - highlightingmarksreporter.cpp \ - pchinfo.cpp \ - pchmanager.cpp \ - raii/scopedclangoptions.cpp \ - unit.cpp \ - unsavedfiledata.cpp + highlightingmarksreporter.cpp HEADERS += \ activationsequencecontextprocessor.h \ @@ -70,12 +61,7 @@ HEADERS += \ clangutils.h \ completionchunkstotextconverter.h \ constants.h \ - highlightingmarksreporter.h \ - pchinfo.h \ - pchmanager.h \ - raii/scopedclangoptions.h \ - unit.h \ - unsavedfiledata.h + highlightingmarksreporter.h FORMS += clangprojectsettingspropertiespage.ui diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index e6d06a752bd..dc275e7ead8 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -23,16 +23,10 @@ QtcPlugin { property string llvmConfig: Clang.llvmConfig(qbs, QtcFunctions, QtcProcessOutputReader) property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader) property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader) - property string llvmLibs: Clang.libraries(qbs.targetOS) property string llvmVersion: Clang.version(llvmConfig, QtcProcessOutputReader) condition: llvmConfig && File.exists(llvmIncludeDir.concat("/clang-c/Index.h")) - cpp.includePaths: base.concat(llvmIncludeDir) - cpp.libraryPaths: base.concat(llvmLibDir) - cpp.rpaths: cpp.libraryPaths - cpp.dynamicLibraries: base.concat(llvmLibs) - cpp.defines: { var defines = base; // The following defines are used to determine the clang include path for intrinsics. @@ -95,16 +89,6 @@ QtcPlugin { "constants.h", "highlightingmarksreporter.cpp", "highlightingmarksreporter.h", - "pchinfo.cpp", - "pchinfo.h", - "pchmanager.cpp", - "pchmanager.h", - "raii/scopedclangoptions.cpp", - "raii/scopedclangoptions.h", - "unit.cpp", - "unit.h", - "unsavedfiledata.cpp", - "unsavedfiledata.h", ] Group { diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 35229a68dc0..069923ff5f5 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -32,7 +32,6 @@ #include "clangprojectsettingspropertiespage.h" #include "constants.h" -#include "pchmanager.h" #ifdef WITH_TESTS # include "test/clangcodecompletion_test.h" @@ -46,8 +45,6 @@ #include -#include - namespace ClangCodeModel { namespace Internal { @@ -61,23 +58,6 @@ void initializeTextMarks() Utils::Theme::ClangCodeModel_Error_TextMarkColor); } -static bool clangInitialised = false; -static QMutex initialisationMutex; - -void initializeClang() -{ - if (clangInitialised) - return; - - QMutexLocker locker(&initialisationMutex); - if (clangInitialised) - return; - - clang_toggleCrashRecovery(1); - clang_enableStackTraces(); - clangInitialised = true; -} - } // anonymous namespace bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *errorMessage) @@ -92,19 +72,8 @@ bool ClangCodeModelPlugin::initialize(const QStringList &arguments, QString *err panelFactory->setSimpleCreateWidgetFunction(QIcon()); ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); - // Initialize Clang - ClangCodeModel::Internal::initializeClang(); - - // Set up PchManager - PchManager *pchManager = new PchManager(this); - ProjectExplorer::SessionManager *sessionManager = ProjectExplorer::SessionManager::instance(); - connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject, - pchManager, &PchManager::onAboutToRemoveProject); - auto cppModelManager = CppTools::CppModelManager::instance(); - connect(cppModelManager, &CppTools::CppModelManager::projectPartsUpdated, - pchManager, &PchManager::onProjectPartsUpdated); - // Register ModelManagerSupportProvider + auto cppModelManager = CppTools::CppModelManager::instance(); cppModelManager->setClangModelManagerSupportProvider(&m_modelManagerSupportProvider); initializeTextMarks(); diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp index 0c1f9dff1f9..b8fbb2f4bc7 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.cpp @@ -32,14 +32,10 @@ #include "clangutils.h" -#include #include -#include #include -#include - namespace ClangCodeModel { namespace Internal { @@ -50,18 +46,13 @@ ClangCompletionAssistInterface::ClangCompletionAssistInterface( const QString &fileName, TextEditor::AssistReason reason, const CppTools::ProjectPart::HeaderPaths &headerPaths, - const PchInfo::Ptr &pchInfo, const CPlusPlus::LanguageFeatures &features) : AssistInterface(textEditorWidget->document(), position, fileName, reason) , m_ipcCommunicator(ipcCommunicator) , m_headerPaths(headerPaths) - , m_savedPchPointer(pchInfo) , m_languageFeatures(features) , m_textEditorWidget(textEditorWidget) { - m_unsavedFiles = Utils::createUnsavedFiles( - CppTools::CppModelManager::instance()->workingCopy(), - CppTools::modifiedFiles()); } bool ClangCompletionAssistInterface::objcEnabled() const @@ -94,11 +85,6 @@ IpcCommunicator &ClangCompletionAssistInterface::ipcCommunicator() const return m_ipcCommunicator; } -const Utils::UnsavedFiles &ClangCompletionAssistInterface::unsavedFiles() const -{ - return m_unsavedFiles; -} - } // namespace Internal } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangcompletionassistinterface.h b/src/plugins/clangcodemodel/clangcompletionassistinterface.h index 58f429d06e1..11bd0d7ddd9 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistinterface.h +++ b/src/plugins/clangcodemodel/clangcompletionassistinterface.h @@ -32,7 +32,6 @@ #define CLANGCODEMODEL_INTERNAL_CLANGCOMPLETIONASSISTINTERFACE_H #include "clangbackendipcintegration.h" -#include "pchinfo.h" #include "clangutils.h" #include @@ -51,11 +50,9 @@ public: const QString &fileName, TextEditor::AssistReason reason, const CppTools::ProjectPart::HeaderPaths &headerPaths, - const PchInfo::Ptr &pchInfo, const CPlusPlus::LanguageFeatures &features); IpcCommunicator &ipcCommunicator() const; - const Utils::UnsavedFiles &unsavedFiles() const; bool objcEnabled() const; const CppTools::ProjectPart::HeaderPaths &headerPaths() const; CPlusPlus::LanguageFeatures languageFeatures() const; @@ -65,10 +62,8 @@ public: private: IpcCommunicator &m_ipcCommunicator; - Utils::UnsavedFiles m_unsavedFiles; QStringList m_options; CppTools::ProjectPart::HeaderPaths m_headerPaths; - Internal::PchInfo::Ptr m_savedPchPointer; CPlusPlus::LanguageFeatures m_languageFeatures; const TextEditor::TextEditorWidget *m_textEditorWidget; }; diff --git a/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp b/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp index 4aa358ab081..d9e6b577713 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprovider.cpp @@ -33,7 +33,6 @@ #include "clangcompletionassistprocessor.h" #include "clangeditordocumentprocessor.h" #include "clangutils.h" -#include "pchmanager.h" #include #include @@ -73,14 +72,12 @@ TextEditor::AssistInterface *ClangCompletionAssistProvider::createAssistInterfac { const CppTools::ProjectPart::Ptr projectPart = Utils::projectPartForFileBasedOnProcessor(filePath); if (projectPart) { - const PchInfo::Ptr pchInfo = PchManager::instance()->pchInfo(projectPart); return new ClangCompletionAssistInterface(m_ipcCommunicator, textEditorWidget, position, filePath, reason, projectPart->headerPaths, - pchInfo, projectPart->languageFeatures); } diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index a0c3514f156..f0744856079 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -35,7 +35,6 @@ #include "clangmodelmanagersupport.h" #include "clangutils.h" #include "highlightingmarksreporter.h" -#include "pchinfo.h" #include #include diff --git a/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.cpp b/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.cpp index 5a08c1a0eac..3fb2e797f05 100644 --- a/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.cpp +++ b/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.cpp @@ -30,11 +30,6 @@ #include "clangprojectsettings.h" #include "clangprojectsettingspropertiespage.h" -#include "pchmanager.h" - -#include -#include -#include using namespace ProjectExplorer; using namespace ClangCodeModel::Internal; @@ -43,88 +38,4 @@ ClangProjectSettingsWidget::ClangProjectSettingsWidget(Project *project) : m_project(project) { m_ui.setupUi(this); - - ClangProjectSettings *cps = PchManager::instance()->settingsForProject(project); - Q_ASSERT(cps); - - QButtonGroup *pchGroup = new QButtonGroup(this); - pchGroup->addButton(m_ui.noneButton, ClangProjectSettings::PchUse_None); - pchGroup->addButton(m_ui.exactButton, ClangProjectSettings::PchUse_BuildSystem_Exact); - pchGroup->addButton(m_ui.fuzzyButton, ClangProjectSettings::PchUse_BuildSystem_Fuzzy); - pchGroup->addButton(m_ui.customButton, ClangProjectSettings::PchUse_Custom); - switch (cps->pchUsage()) { - case ClangProjectSettings::PchUse_None: - case ClangProjectSettings::PchUse_BuildSystem_Exact: - case ClangProjectSettings::PchUse_BuildSystem_Fuzzy: - case ClangProjectSettings::PchUse_Custom: - pchGroup->button(cps->pchUsage())->setChecked(true); - break; - default: break; - } - pchUsageChanged(cps->pchUsage()); - connect(pchGroup, SIGNAL(buttonClicked(int)), - this, SLOT(pchUsageChanged(int))); - - m_ui.customField->setText(cps->customPchFile()); - connect(m_ui.customField, SIGNAL(editingFinished()), - this, SLOT(customPchFileChanged())); - connect(m_ui.customButton, SIGNAL(clicked()), - this, SLOT(customPchButtonClicked())); -} - -void ClangProjectSettingsWidget::pchUsageChanged(int id) -{ - ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project); - Q_ASSERT(cps); - cps->setPchUsage(static_cast(id)); - - switch (id) { - case ClangProjectSettings::PchUse_None: - case ClangProjectSettings::PchUse_BuildSystem_Fuzzy: - case ClangProjectSettings::PchUse_BuildSystem_Exact: - m_ui.customField->setEnabled(false); - m_ui.chooseButton->setEnabled(false); - break; - - case ClangProjectSettings::PchUse_Custom: - m_ui.customField->setEnabled(true); - m_ui.chooseButton->setEnabled(true); - break; - - default: - break; - } -} - -void ClangProjectSettingsWidget::customPchFileChanged() -{ - ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project); - Q_ASSERT(cps); - if (cps->pchUsage() != ClangProjectSettings::PchUse_Custom) - return; - QString fileName = m_ui.customField->text(); - if (!QFile(fileName).exists()) - return; - - cps->setCustomPchFile(fileName); -} - -void ClangProjectSettingsWidget::customPchButtonClicked() -{ - ClangProjectSettings *cps = PchManager::instance()->settingsForProject(m_project); - Q_ASSERT(cps); - - QFileDialog d(this); - d.setNameFilters(QStringList() << tr("Header Files (*.h)") - << tr("All Files (*)")); - d.setFileMode(QFileDialog::ExistingFile); - d.setDirectory(m_project->projectDirectory().toString()); - if (!d.exec()) - return; - const QStringList fileNames = d.selectedFiles(); - if (fileNames.isEmpty() || fileNames.first().isEmpty()) - return; - - m_ui.customField->setText(fileNames.first()); - cps->setCustomPchFile(fileNames.first()); } diff --git a/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.h b/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.h index 0e1f87f54ae..f77ef342328 100644 --- a/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.h +++ b/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.h @@ -33,10 +33,8 @@ #include "ui_clangprojectsettingspropertiespage.h" -#include - namespace ProjectExplorer { - class Project; +class Project; } namespace ClangCodeModel { @@ -49,11 +47,6 @@ class ClangProjectSettingsWidget: public QWidget public: ClangProjectSettingsWidget(ProjectExplorer::Project *project); -protected slots: - void pchUsageChanged(int id); - void customPchFileChanged(); - void customPchButtonClicked(); - private: Ui::ClangProjectSettingsPropertiesPage m_ui; ProjectExplorer::Project *m_project; diff --git a/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.ui b/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.ui index 66dcf45c5b8..8b2fae3a6f9 100644 --- a/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.ui +++ b/src/plugins/clangcodemodel/clangprojectsettingspropertiespage.ui @@ -2,6 +2,9 @@ ClangCodeModel::Internal::ClangProjectSettingsPropertiesPage + + false + 0 diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 28c223d80ad..a3c693b126d 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -32,25 +32,18 @@ #include "clangeditordocumentprocessor.h" -#include - #include #include - #include #include -#include - #include - #include #include #include #include #include -#include -#include +#include using namespace ClangCodeModel; using namespace ClangCodeModel::Internal; @@ -62,21 +55,6 @@ namespace Utils { Q_LOGGING_CATEGORY(verboseRunLog, "qtc.clangcodemodel.verboserun") -UnsavedFiles createUnsavedFiles(const WorkingCopy &workingCopy, - const ::Utils::FileNameList &modifiedFiles) -{ - UnsavedFiles result; - QHashIterator< ::Utils::FileName, QPair > wcIter = workingCopy.iterator(); - while (wcIter.hasNext()) { - wcIter.next(); - const ::Utils::FileName &fileName = wcIter.key(); - if (modifiedFiles.contains(fileName) && QFile(fileName.toString()).exists()) - result.insert(fileName.toString(), wcIter.value().first); - } - - return result; -} - /** * @brief Creates list of message-line arguments required for correct parsing * @param pPart Null if file isn't part of any project diff --git a/src/plugins/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h index b8e524e749b..7590333a03b 100644 --- a/src/plugins/clangcodemodel/clangutils.h +++ b/src/plugins/clangcodemodel/clangutils.h @@ -33,20 +33,15 @@ #include "clang_global.h" -#include +#include #include namespace ClangCodeModel { namespace Utils { -typedef QMap UnsavedFiles; - Q_DECLARE_LOGGING_CATEGORY(verboseRunLog) -UnsavedFiles createUnsavedFiles(const CppTools::WorkingCopy &workingCopy, - const ::Utils::FileNameList &modifiedFiles); - QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart, CppTools::ProjectFile::Kind fileKind); QStringList createClangOptions(const CppTools::ProjectPart::Ptr &pPart, diff --git a/src/plugins/clangcodemodel/pchinfo.cpp b/src/plugins/clangcodemodel/pchinfo.cpp deleted file mode 100644 index a517d0f792f..00000000000 --- a/src/plugins/clangcodemodel/pchinfo.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "pchinfo.h" - -#include - -using namespace ClangCodeModel::Internal; - -PchInfo::PchInfo() -{ -} - -PchInfo::~PchInfo() -{ -} - -PchInfo::Ptr PchInfo::createEmpty() -{ - return Ptr(new PchInfo); -} - -PchInfo::Ptr PchInfo::createWithFileName(const QString &inputFileName, - const QStringList &options, - bool objcEnabled) -{ - Ptr result(new PchInfo); - result->m_inputFileName = inputFileName; - result->m_options = options; - result->m_objcEnabled = objcEnabled; - - // The next 2 lines are just here to generate the file name.... - result->m_file.open(); - result->m_file.close(); - return result; -} diff --git a/src/plugins/clangcodemodel/pchinfo.h b/src/plugins/clangcodemodel/pchinfo.h deleted file mode 100644 index ea542dc8355..00000000000 --- a/src/plugins/clangcodemodel/pchinfo.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef PCHINFO_H -#define PCHINFO_H - -#include -#include -#include -#include - -namespace ClangCodeModel { -namespace Internal { - -class PchInfo -{ - PchInfo(); - -public: - typedef QSharedPointer Ptr; - -public: - ~PchInfo(); - - static Ptr createEmpty(); - static Ptr createWithFileName(const QString &inputFileName, - const QStringList &options, bool objcEnabled); - - /// \return the (temporary) file name for the PCH file. - QString fileName() const - { return m_file.fileName(); } - - /// \return the input file for the PCH compilation. - QString inputFileName() const - { return m_inputFileName; } - - /// \return the options used to generate this PCH file. - QStringList options() const - { return m_options; } - - bool objcWasEnabled() const - { return m_objcEnabled; } - -private: - QString m_inputFileName; - QStringList m_options; - bool m_objcEnabled; - QTemporaryFile m_file; -}; - -} // Internal namespace -} // ClangCodeModel namespace - -#endif // PCHINFO_H diff --git a/src/plugins/clangcodemodel/pchmanager.cpp b/src/plugins/clangcodemodel/pchmanager.cpp deleted file mode 100644 index abda6ff8730..00000000000 --- a/src/plugins/clangcodemodel/pchmanager.cpp +++ /dev/null @@ -1,512 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "pchmanager.h" -#include "unit.h" -#include "clangutils.h" - -#include -#include - -#include -#include - -#include - -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; -using namespace CPlusPlus; - -namespace { - -QString getQString(const CXString &cxString, bool disposeCXString = true) -{ - QString s = QString::fromUtf8(clang_getCString(cxString)); - if (disposeCXString) - clang_disposeString(cxString); - return s; -} - -QStringList formattedDiagnostics(const Unit::Ptr &unit) -{ - QStringList diags; - if (!unit->isLoaded()) - return diags; - - const unsigned count = unit->getNumDiagnostics(); - for (unsigned i = 0; i < count; ++i) { - CXDiagnostic diag = unit->getDiagnostic(i); - - unsigned opt = CXDiagnostic_DisplaySourceLocation - | CXDiagnostic_DisplayColumn - | CXDiagnostic_DisplaySourceRanges - | CXDiagnostic_DisplayOption - | CXDiagnostic_DisplayCategoryId - | CXDiagnostic_DisplayCategoryName - ; - diags << getQString(clang_formatDiagnostic(diag, opt)); - clang_disposeDiagnostic(diag); - } - - return diags; -} - -/** - * Utility method to create a PCH file from a header file. - * - * \returns a boolean indicating success (true) or failure (false), and a - * list of diagnostic messages. - */ -QPair precompile(const PchInfo::Ptr &pchInfo) -{ -// qDebug() << "*** Precompiling" << pchInfo->inputFileName() -// << "into" << pchInfo->fileName() -// << "with options" << pchInfo->options(); - - bool ok = false; - - Unit::Ptr unit = Unit::create(pchInfo->inputFileName()); - unit->setCompilationOptions(pchInfo->options()); - - unsigned parseOpts = CXTranslationUnit_ForSerialization - | CXTranslationUnit_Incomplete; - unit->setManagementOptions(parseOpts); - - unit->parse(); - if (unit->isLoaded()) - ok = CXSaveError_None == unit->save(pchInfo->fileName()); - - return qMakePair(ok, formattedDiagnostics(unit)); -} - -} // anonymous namespace - -PchManager *PchManager::m_instance = 0; - -PchManager::PchManager(QObject *parent) - : QObject(parent) -{ - Q_ASSERT(!m_instance); - m_instance = this; - - QObject *msgMgr = Core::MessageManager::instance(); - connect(this, SIGNAL(pchMessage(QString,Core::MessageManager::PrintToOutputPaneFlags)), - msgMgr, SLOT(write(QString,Core::MessageManager::PrintToOutputPaneFlags))); - - connect(&m_pchGenerationWatcher, SIGNAL(finished()), - this, SLOT(updateActivePchFiles())); -} - -PchManager::~PchManager() -{ - Q_ASSERT(m_instance); - m_instance = 0; - qDeleteAll(m_projectSettings.values()); - m_projectSettings.clear(); -} - -PchManager *PchManager::instance() -{ - return m_instance; -} - -PchInfo::Ptr PchManager::pchInfo(const ProjectPart::Ptr &projectPart) const -{ - QMutexLocker locker(&m_mutex); - - return m_activePchFiles[projectPart]; -} - -ClangProjectSettings *PchManager::settingsForProject(ProjectExplorer::Project *project) -{ - QMutexLocker locker(&m_mutex); - - ClangProjectSettings *cps = m_projectSettings.value(project); - if (!cps) { - cps = new ClangProjectSettings(project); - m_projectSettings.insert(project, cps); - cps->pullSettings(); - connect(cps, SIGNAL(pchSettingsChanged()), - this, SLOT(clangProjectSettingsChanged())); - } - return cps; -} - -void PchManager::setPCHInfo(const QList &projectParts, - const PchInfo::Ptr &pchInfo, - const QPair &msgs) -{ - QMutexLocker locker(&m_mutex); - - foreach (ProjectPart::Ptr pPart, projectParts) - m_activePchFiles[pPart] = pchInfo; - - if (pchInfo) { - if (msgs.first) { - if (!pchInfo->fileName().isEmpty()) - emit pchMessage(tr("Successfully generated PCH file \"%1\".").arg( - pchInfo->fileName()), Core::MessageManager::Silent); - } else { - emit pchMessage(tr("Failed to generate PCH file \"%1\".").arg( - pchInfo->fileName()), Core::MessageManager::Silent); - } - if (!msgs.second.isEmpty()) - emit pchMessage(msgs.second.join(QLatin1Char('\n')), Core::MessageManager::Flash); - } -} - -void PchManager::clangProjectSettingsChanged() -{ - ClangProjectSettings *cps = qobject_cast(sender()); - if (!cps) - return; - - onProjectPartsUpdated(cps->project()); -} - -void PchManager::onAboutToRemoveProject(ProjectExplorer::Project *project) -{ - Q_UNUSED(project); - - // we cannot ask the ModelManager for the parts, because, depending on - // the order of signal delivery, it might already have wiped any information - // about the project. - - updateActivePchFiles(); -} - -void PchManager::onProjectPartsUpdated(ProjectExplorer::Project *project) -{ - ClangProjectSettings *cps = settingsForProject(project); - Q_ASSERT(cps); - - CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance(); - const QList projectParts = mmi->projectInfo( - cps->project()).projectParts(); - updatePchInfo(cps, projectParts); -} - -void PchManager::updatePchInfo(ClangProjectSettings *cps, - const QList &projectParts) -{ - if (m_pchGenerationWatcher.isRunning()) { - m_pchGenerationWatcher.waitForFinished(); - } - - const QString customPchFile = cps->customPchFile(); - const ClangProjectSettings::PchUsage pchUsage = cps->pchUsage(); - - void (*updateFunction)(QFutureInterface &future, - const PchManager::UpdateParams params) = 0; - QString message; - if (pchUsage == ClangProjectSettings::PchUse_None - || (pchUsage == ClangProjectSettings::PchUse_Custom && customPchFile.isEmpty())) { - updateFunction = &PchManager::doPchInfoUpdateNone; - message = QLatin1String("updatePchInfo: switching to none"); - } else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Fuzzy) { - updateFunction = &PchManager::doPchInfoUpdateFuzzy; - message = QLatin1String("updatePchInfo: switching to build system (fuzzy)"); - } else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Exact) { - updateFunction = &PchManager::doPchInfoUpdateExact; - message = QLatin1String("updatePchInfo: switching to build system (exact)"); - } else if (pchUsage == ClangProjectSettings::PchUse_Custom) { - updateFunction = &PchManager::doPchInfoUpdateCustom; - message = QLatin1String("updatePchInfo: switching to custom") + customPchFile; - } - - QTC_ASSERT(updateFunction && !message.isEmpty(), return); - - Core::MessageManager::write(message, Core::MessageManager::Silent); - QFuture future = QtConcurrent::run(updateFunction, - UpdateParams(customPchFile, projectParts)); - m_pchGenerationWatcher.setFuture(future); - Core::ProgressManager::addTask(future, tr("Precompiling"), "Key.Tmp.Precompiling"); -} - -namespace { - -bool hasObjCFiles(const CppTools::ProjectPart::Ptr &projectPart) -{ - foreach (const CppTools::ProjectFile &file, projectPart->files) { - switch (file.kind) { - case CppTools::ProjectFile::ObjCHeader: - case CppTools::ProjectFile::ObjCSource: - case CppTools::ProjectFile::ObjCXXHeader: - case CppTools::ProjectFile::ObjCXXSource: - return true; - default: - break; - } - } - return false; -} - -bool hasCppFiles(const CppTools::ProjectPart::Ptr &projectPart) -{ - foreach (const CppTools::ProjectFile &file, projectPart->files) { - switch (file.kind) { - case CppTools::ProjectFile::CudaSource: - case CppTools::ProjectFile::CXXHeader: - case CppTools::ProjectFile::CXXSource: - case CppTools::ProjectFile::OpenCLSource: - case CppTools::ProjectFile::ObjCXXHeader: - case CppTools::ProjectFile::ObjCXXSource: - return true; - default: - break; - } - } - return false; -} - -CppTools::ProjectFile::Kind getPrefixFileKind(bool hasObjectiveC, bool hasCPlusPlus) -{ - if (hasObjectiveC && hasCPlusPlus) - return CppTools::ProjectFile::ObjCXXHeader; - else if (hasObjectiveC) - return CppTools::ProjectFile::ObjCHeader; - else if (hasCPlusPlus) - return CppTools::ProjectFile::CXXHeader; - return CppTools::ProjectFile::CHeader; -} - -} - -void PchManager::doPchInfoUpdateNone(QFutureInterface &future, - const PchManager::UpdateParams params) -{ - future.setProgressRange(0, 1); - PchInfo::Ptr emptyPch = PchInfo::createEmpty(); - PchManager::instance()->setPCHInfo(params.projectParts, emptyPch, - qMakePair(true, QStringList())); - future.setProgressValue(1); -} - -void PchManager::doPchInfoUpdateFuzzy(QFutureInterface &future, - const PchManager::UpdateParams params) -{ - typedef ProjectPart::HeaderPath HeaderPath; - QHash> headers; - QHash > definesPerPCH; - QHash objc; - QHash cplusplus; - QHash qtVersions; - QHash languageVersions; - QHash languageExtensionsMap; - QHash > inputToParts; - foreach (const ProjectPart::Ptr &projectPart, params.projectParts) { - if (projectPart->precompiledHeaders.isEmpty()) - continue; - const QString &pch = projectPart->precompiledHeaders.first(); // TODO: support more than 1 PCH file. - if (!QFile(pch).exists()) - continue; - inputToParts[pch].append(projectPart); - - headers[pch].unite(QSet::fromList(projectPart->headerPaths)); - languageVersions[pch] = std::max(languageVersions.value(pch, ProjectPart::C89), - projectPart->languageVersion); - languageExtensionsMap[pch] = languageExtensionsMap[pch] | projectPart->languageExtensions; - - if (hasObjCFiles(projectPart)) - objc[pch] = true; - if (hasCppFiles(projectPart)) - cplusplus[pch] = true; - - QSet projectDefines = QSet::fromList(projectPart->toolchainDefines.split('\n')); - QMutableSetIterator iter(projectDefines); - while (iter.hasNext()){ - QByteArray v = iter.next(); - if (v.startsWith("#define _") || v.isEmpty()) // TODO: see ProjectPart::createClangOptions - iter.remove(); - } - projectDefines.unite(QSet::fromList(projectPart->projectDefines.split('\n'))); - - if (definesPerPCH.contains(pch)) { - definesPerPCH[pch].intersect(projectDefines); - } else { - definesPerPCH[pch] = projectDefines; - } - - qtVersions[pch] = projectPart->qtVersion; - } - - future.setProgressRange(0, definesPerPCH.size() + 1); - future.setProgressValue(0); - - foreach (const QString &pch, inputToParts.keys()) { - if (future.isCanceled()) - return; - ProjectPart::Ptr projectPart(new ProjectPart); - projectPart->qtVersion = qtVersions[pch]; - projectPart->languageVersion = languageVersions[pch]; - projectPart->languageExtensions = languageExtensionsMap[pch]; - projectPart->headerPaths = headers[pch].toList(); - projectPart->updateLanguageFeatures(); - - QList defines = definesPerPCH[pch].toList(); - if (!defines.isEmpty()) { - projectPart->projectDefines = defines[0]; - for (int i = 1; i < defines.size(); ++i) { - projectPart->projectDefines += '\n'; - projectPart->projectDefines += defines[i]; - } - } - - CppTools::ProjectFile::Kind prefixFileKind = - getPrefixFileKind(objc.value(pch, false), cplusplus.value(pch, false)); - - QStringList options = Utils::createClangOptions(projectPart, prefixFileKind); - projectPart.clear(); - - PchManager *pchManager = PchManager::instance(); - PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(pch, options, true); - QPair msgs = qMakePair(true, QStringList()); - if (pchInfo.isNull()) { - - pchInfo = PchInfo::createWithFileName(pch, options, objc[pch]); - msgs = precompile(pchInfo); - } - pchManager->setPCHInfo(inputToParts[pch], pchInfo, msgs); - future.setProgressValue(future.progressValue() + 1); - } - - future.setProgressValue(future.progressValue() + 1); -} - -void PchManager::doPchInfoUpdateExact(QFutureInterface &future, - const PchManager::UpdateParams params) -{ - future.setProgressRange(0, params.projectParts.size() + 1); - future.setProgressValue(0); - foreach (const ProjectPart::Ptr &projectPart, params.projectParts) { - if (future.isCanceled()) - return; - if (projectPart->precompiledHeaders.isEmpty()) - continue; - const QString &pch = projectPart->precompiledHeaders.first(); // TODO: support more than 1 PCH file. - if (!QFile(pch).exists()) - continue; - - const bool hasObjC = hasObjCFiles(projectPart); - QStringList options = Utils::createClangOptions( - projectPart, getPrefixFileKind(hasObjC, hasCppFiles(projectPart))); - - PchManager *pchManager = PchManager::instance(); - PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(pch, options, false); - QPair msgs = qMakePair(true, QStringList()); - if (pchInfo.isNull()) { - pchInfo = PchInfo::createWithFileName(pch, options, hasObjC); - msgs = precompile(pchInfo); - } - pchManager->setPCHInfo(QList() << projectPart, - pchInfo, msgs); - future.setProgressValue(future.progressValue() + 1); - } - - future.setProgressValue(future.progressValue() + 1); -} - -void PchManager::doPchInfoUpdateCustom(QFutureInterface &future, - const PchManager::UpdateParams params) -{ - future.setProgressRange(0, 1); - future.setProgressValue(0); - - ProjectPart::HeaderPaths headers; - bool objc = false; - bool cplusplus = false; - ProjectPart::Ptr united(new ProjectPart()); - united->languageVersion = ProjectPart::C89; - foreach (const ProjectPart::Ptr &projectPart, params.projectParts) { - headers += projectPart->headerPaths; - united->languageVersion = std::max(united->languageVersion, projectPart->languageVersion); - united->qtVersion = std::max(united->qtVersion, projectPart->qtVersion); - objc |= hasObjCFiles(projectPart); - cplusplus |= hasCppFiles(projectPart); - } - united->updateLanguageFeatures(); - united->headerPaths = headers; - QStringList opts = Utils::createClangOptions( - united, getPrefixFileKind(objc, cplusplus)); - united.clear(); - - PchManager *pchManager = PchManager::instance(); - PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(params.customPchFile, opts, true); - QPair msgs = qMakePair(true, QStringList());; - if (future.isCanceled()) - return; - if (pchInfo.isNull()) { - pchInfo = PchInfo::createWithFileName(params.customPchFile, opts, objc); - msgs = precompile(pchInfo); - } - pchManager->setPCHInfo(params.projectParts, pchInfo, msgs); - future.setProgressValue(1); -} - -PchInfo::Ptr PchManager::findMatchingPCH(const QString &inputFileName, - const QStringList &options, - bool fuzzyMatching) const -{ - QMutexLocker locker(&m_mutex); - - if (fuzzyMatching) { - QStringList opts = options; - opts.sort(); - foreach (PchInfo::Ptr pchInfo, m_activePchFiles.values()) { - if (pchInfo->inputFileName() != inputFileName) - continue; - QStringList pchOpts = pchInfo->options(); - pchOpts.sort(); - if (pchOpts == opts) - return pchInfo; - } - } else { - foreach (PchInfo::Ptr pchInfo, m_activePchFiles.values()) - if (pchInfo->inputFileName() == inputFileName - && pchInfo->options() == options) - return pchInfo; - } - - return PchInfo::Ptr(); -} - -void PchManager::updateActivePchFiles() -{ - QMutexLocker locker(&m_mutex); - - QSet activeParts; - CppTools::CppModelManager *mmi = CppTools::CppModelManager::instance(); - foreach (const CppTools::ProjectInfo &pi, mmi->projectInfos()) - activeParts.unite(QSet::fromList(pi.projectParts())); - QList partsWithPCHFiles = m_activePchFiles.keys(); - foreach (ProjectPart::Ptr pPart, partsWithPCHFiles) - if (!activeParts.contains(pPart)) - m_activePchFiles.remove(pPart); -} diff --git a/src/plugins/clangcodemodel/pchmanager.h b/src/plugins/clangcodemodel/pchmanager.h deleted file mode 100644 index 1d6f4816d68..00000000000 --- a/src/plugins/clangcodemodel/pchmanager.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef PCHMANAGER_H -#define PCHMANAGER_H - -#include "clangprojectsettings.h" -#include "pchinfo.h" - -#include -#include -#include - -#include -#include -#include -#include - -namespace ClangCodeModel { -namespace Internal { - -class PchManager : public QObject -{ - Q_OBJECT - - typedef CppTools::ProjectPart ProjectPart; - - static PchManager *m_instance; - -public: - PchManager(QObject *parent = 0); - virtual ~PchManager(); - - static PchManager *instance(); - - PchInfo::Ptr pchInfo(const ProjectPart::Ptr &projectPart) const; - ClangProjectSettings *settingsForProject(ProjectExplorer::Project *project); - -signals: - void pchMessage(const QString &message, Core::MessageManager::PrintToOutputPaneFlags flags); - -public slots: - void clangProjectSettingsChanged(); - void onAboutToRemoveProject(ProjectExplorer::Project *project); - void onProjectPartsUpdated(ProjectExplorer::Project *project); - -private slots: - void updateActivePchFiles(); - -private: - struct UpdateParams { - UpdateParams(const QString &customPchFile, const QList &projectParts) - : customPchFile(customPchFile) , projectParts(projectParts) {} - const QString customPchFile; - const QList projectParts; - }; - - void updatePchInfo(ClangProjectSettings *cps, - const QList &projectParts); - - static void doPchInfoUpdateNone(QFutureInterface &future, const UpdateParams params); - static void doPchInfoUpdateFuzzy(QFutureInterface &future, const UpdateParams params); - static void doPchInfoUpdateExact(QFutureInterface &future, const UpdateParams params); - static void doPchInfoUpdateCustom(QFutureInterface &future, const UpdateParams params); - - void setPCHInfo(const QList &projectParts, - const PchInfo::Ptr &pchInfo, - const QPair &msgs); - PchInfo::Ptr findMatchingPCH(const QString &inputFileName, const QStringList &options, - bool fuzzyMatching) const; - -private: - mutable QMutex m_mutex; - QHash m_activePchFiles; - QHash m_projectSettings; - QFutureWatcher m_pchGenerationWatcher; -}; - -} // namespace Internal -} // namespace ClangCodeModel - -#endif // PCHMANAGER_H diff --git a/src/plugins/clangcodemodel/raii/scopedclangoptions.cpp b/src/plugins/clangcodemodel/raii/scopedclangoptions.cpp deleted file mode 100644 index 8d74d428d66..00000000000 --- a/src/plugins/clangcodemodel/raii/scopedclangoptions.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "scopedclangoptions.h" - -namespace ClangCodeModel { - -/** - * @class ClangCodeModel::ScopedClangOptions - * @brief Converts QStringList to raw options, acceptable by clang-c parsing and indexing API - */ - -ScopedClangOptions::ScopedClangOptions(const QStringList &options) - : m_size(options.size()) - , m_rawOptions(new const char*[options.size()]) -{ - for (int i = 0 ; i < m_size; ++i) - m_rawOptions[i] = qstrdup(options[i].toUtf8()); -} - -ScopedClangOptions::~ScopedClangOptions() -{ - for (int i = 0; i < m_size; ++i) - delete[] m_rawOptions[i]; - delete[] m_rawOptions; -} - -const char **ScopedClangOptions::data() const -{ - return m_rawOptions; -} - -int ScopedClangOptions::size() const -{ - return m_size; -} - -/** - * @class ClangCodeModel::SharedClangOptions - * @brief Shared wrapper around \a {ClangCodeModel::ScopedClangOptions} ScopedClangOptions - */ - -SharedClangOptions::SharedClangOptions() - : d(0) -{ -} - -SharedClangOptions::SharedClangOptions(const QStringList &options) - : d(new ScopedClangOptions(options)) -{ -} - -/** - * @return Replaces options with new options list - */ -void SharedClangOptions::reloadOptions(const QStringList &options) -{ - d = QSharedPointer(new ScopedClangOptions(options)); -} - -/** - * @return Pointer to clang raw options or NULL if uninitialized - */ -const char **SharedClangOptions::data() const -{ - return d ? d->data() : 0; -} - -/** - * @return Options count or 0 if uninitialized - */ -int SharedClangOptions::size() const -{ - return d ? d->size() : 0; -} - -} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/raii/scopedclangoptions.h b/src/plugins/clangcodemodel/raii/scopedclangoptions.h deleted file mode 100644 index 45ba6063baf..00000000000 --- a/src/plugins/clangcodemodel/raii/scopedclangoptions.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANGCODEMODEL_SCOPEDCLANGOPTIONS_H -#define CLANGCODEMODEL_SCOPEDCLANGOPTIONS_H - -#include "../clang_global.h" -#include -#include - -namespace ClangCodeModel { - -class CLANG_EXPORT ScopedClangOptions -{ -public: - ScopedClangOptions(const QStringList &options); - ~ScopedClangOptions(); - - const char **data() const; - int size() const; - -private: - void release(); - - int m_size; - const char **m_rawOptions; -}; - -class CLANG_EXPORT SharedClangOptions -{ -public: - SharedClangOptions(); - SharedClangOptions(const QStringList &options); - - void reloadOptions(const QStringList &options); - - const char **data() const; - int size() const; - -private: - QSharedPointer d; -}; - -} // namespace ClangCodeModel - -#endif // CLANGCODEMODEL_SCOPEDCLANGOPTIONS_H diff --git a/src/plugins/clangcodemodel/unit.cpp b/src/plugins/clangcodemodel/unit.cpp deleted file mode 100644 index 83b1aaed932..00000000000 --- a/src/plugins/clangcodemodel/unit.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "unit.h" - -#include "clangutils.h" -#include "unsavedfiledata.h" - -#include - -#include -#include -#include - -#ifdef DEBUG_UNIT_COUNT -# include -# include -static QBasicAtomicInt unitDataCount = Q_BASIC_ATOMIC_INITIALIZER(0); -#endif // DEBUG_UNIT_COUNT - -using namespace ClangCodeModel; -using namespace ClangCodeModel::Internal; - -Unit::Unit() - : m_index(0) - , m_tu(0) - , m_managementOptions(0) -{} - -Unit::Unit(const QString &fileName) - : m_index(clang_createIndex(/*excludeDeclsFromPCH*/ 1, Utils::verboseRunLog().isDebugEnabled())) - , m_tu(0) - , m_fileName(fileName.toUtf8()) - , m_managementOptions(0) -{} - -Unit::~Unit() -{ - unload(); - clang_disposeIndex(m_index); - m_index = 0; -} - -Unit::Ptr Unit::create() -{ - return Unit::Ptr(new Unit); -} - -Unit::Ptr Unit::create(const QString &fileName) -{ - return Unit::Ptr(new Unit(fileName)); -} - -const QString Unit::fileName() const -{ - return QString::fromUtf8(m_fileName.data(), m_fileName.size()); -} - -bool Unit::isLoaded() const -{ - return m_tu && m_index; -} - -const QDateTime &Unit::timeStamp() const -{ - return m_timeStamp; -} - -QStringList Unit::compilationOptions() const -{ - return m_compOptions; -} - -void Unit::setCompilationOptions(const QStringList &compOptions) -{ - m_compOptions = compOptions; - m_sharedCompOptions.reloadOptions(compOptions); -} - -ClangCodeModel::Utils::UnsavedFiles Unit::unsavedFiles() const -{ - return m_unsaved; -} - -void Unit::setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles) -{ - m_unsaved = unsavedFiles; -} - -unsigned Unit::managementOptions() const -{ - return m_managementOptions; -} - -void Unit::setManagementOptions(unsigned managementOptions) -{ - m_managementOptions = managementOptions; -} - -void Unit::parse() -{ - unload(); - - updateTimeStamp(); - - UnsavedFileData unsaved(m_unsaved); - m_tu = clang_parseTranslationUnit(m_index, m_fileName.constData(), - m_sharedCompOptions.data(), m_sharedCompOptions.size(), - unsaved.files(), unsaved.count(), - m_managementOptions); -} - -void Unit::reparse() -{ - Q_ASSERT(isLoaded()); - - UnsavedFileData unsaved(m_unsaved); - const unsigned opts = clang_defaultReparseOptions(m_tu); - if (clang_reparseTranslationUnit(m_tu, unsaved.count(), unsaved.files(), opts) != 0) - unload(); -} - -int Unit::save(const QString &unitFileName) -{ - Q_ASSERT(isLoaded()); - - return clang_saveTranslationUnit(m_tu, unitFileName.toUtf8().constData(), - clang_defaultSaveOptions(m_tu)); -} - -void Unit::unload() -{ - if (m_tu) { - clang_disposeTranslationUnit(m_tu); - m_tu = 0; - -#ifdef DEBUG_UNIT_COUNT - qDebug() << "# translation units:" << (unitDataCount.fetchAndAddOrdered(-1) - 1); -#endif // DEBUG_UNIT_COUNT - } -} - -CXFile Unit::getFile() const -{ - Q_ASSERT(isLoaded()); - - return clang_getFile(m_tu, m_fileName.constData()); -} - -CXCursor Unit::getCursor(const CXSourceLocation &location) const -{ - Q_ASSERT(isLoaded()); - - return clang_getCursor(m_tu, location); -} - -CXSourceLocation Unit::getLocation(const CXFile &file, unsigned line, unsigned column) const -{ - Q_ASSERT(isLoaded()); - - return clang_getLocation(m_tu, file, line, column); -} - -void Unit::tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const -{ - Q_ASSERT(isLoaded()); - Q_ASSERT(tokens); - Q_ASSERT(tokenCount); - Q_ASSERT(!clang_Range_isNull(range)); - - clang_tokenize(m_tu, range, tokens, tokenCount); -} - -void Unit::disposeTokens(CXToken *tokens, unsigned tokenCount) const -{ - Q_ASSERT(isLoaded()); - - clang_disposeTokens(m_tu, tokens, tokenCount); -} - -CXSourceRange Unit::getTokenExtent(const CXToken &token) const -{ - Q_ASSERT(isLoaded()); - - return clang_getTokenExtent(m_tu, token); -} - -void Unit::annotateTokens(CXToken *tokens, unsigned tokenCount, CXCursor *cursors) const -{ - Q_ASSERT(isLoaded()); - Q_ASSERT(tokens); - Q_ASSERT(cursors); - - clang_annotateTokens(m_tu, tokens, tokenCount, cursors); -} - -CXTranslationUnit Unit::clangTranslationUnit() const -{ - Q_ASSERT(isLoaded()); - - return m_tu; -} - -CXIndex Unit::clangIndex() const -{ - Q_ASSERT(isLoaded()); - - return m_index; -} - -CXCursor Unit::getTranslationUnitCursor() const -{ - Q_ASSERT(isLoaded()); - - return clang_getTranslationUnitCursor(m_tu); -} - -CXString Unit::getTranslationUnitSpelling() const -{ - Q_ASSERT(isLoaded()); - - return clang_getTranslationUnitSpelling(m_tu); -} - -void Unit::getInclusions(CXInclusionVisitor visitor, CXClientData clientData) const -{ - Q_ASSERT(isLoaded()); - - clang_getInclusions(m_tu, visitor, clientData); -} - -unsigned Unit::getNumDiagnostics() const -{ - Q_ASSERT(isLoaded()); - - return clang_getNumDiagnostics(m_tu); -} - -CXDiagnostic Unit::getDiagnostic(unsigned index) const -{ - Q_ASSERT(isLoaded()); - - return clang_getDiagnostic(m_tu, index); -} - -void Unit::updateTimeStamp() -{ - m_timeStamp = QDateTime::currentDateTime(); -} - -IdentifierTokens::IdentifierTokens(const Unit &unit, unsigned firstLine, unsigned lastLine) - : m_unit(unit) - , m_tokenCount(0) - , m_tokens(0) - , m_cursors(0) - , m_extents(0) -{ - Q_ASSERT(unit.isLoaded()); - - // Calculate the range: - CXFile file = unit.getFile(); - CXSourceLocation startLocation = unit.getLocation(file, firstLine, 1); - CXSourceLocation endLocation = unit.getLocation(file, lastLine, 1); - CXSourceRange range = clang_getRange(startLocation, endLocation); - - // Retrieve all identifier tokens: - unit.tokenize(range, &m_tokens, &m_tokenCount); - if (m_tokenCount == 0) - return; - - // Get the cursors for the tokens: - m_cursors = new CXCursor[m_tokenCount]; - unit.annotateTokens(m_tokens, - m_tokenCount, - m_cursors); - - m_extents = new CXSourceRange[m_tokenCount]; - // Create the markers using the cursor to check the types: - for (unsigned i = 0; i < m_tokenCount; ++i) - m_extents[i] = unit.getTokenExtent(m_tokens[i]); -} - -IdentifierTokens::~IdentifierTokens() -{ - dispose(); -} - -void IdentifierTokens::dispose() -{ - if (!m_unit.isLoaded()) - return; - - if (m_tokenCount && m_tokens) { - m_unit.disposeTokens(m_tokens, m_tokenCount); - m_tokens = 0; - m_tokenCount = 0; - } - - if (m_cursors) { - delete[] m_cursors; - m_cursors = 0; - } - - if (m_extents) { - delete[] m_extents; - m_extents = 0; - } -} diff --git a/src/plugins/clangcodemodel/unit.h b/src/plugins/clangcodemodel/unit.h deleted file mode 100644 index a32865fe38e..00000000000 --- a/src/plugins/clangcodemodel/unit.h +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef UNIT_H -#define UNIT_H - -#include "clangutils.h" -#include "raii/scopedclangoptions.h" - -#include - -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QDateTime; -QT_END_NAMESPACE - -namespace ClangCodeModel { -namespace Internal { - -class UnitData; - -/* - * This is a minimal wrapper around clang's translation unit functionality. - * It should should contain only the very basic primitives which allow other - * components such as code completion, code navigation, and others to access - * data which directly depends on the translation unit. - * - * In other words, what's wrapped here is only the functions that receive a - * CXTranslationUnit as a parameter. And this class itself is then the corresponding - * abstraction of the CXTranslationUnit. - * - * Notes: - * - This class is not thread-safe. - * - It's responsibility of the client to make sure that the wrapped translation - * unit is consistent with the other data such as cursor and locations being used. - * - * @TODO: This is similar but not exactly the same as the current ClangWrapper class. - * That class is now tuned to specific features, so it's not generic enough to be used - * an underlying component and aslo don't provide the data in a fine granularity as - * needed here. At some point we should split ClangWrapper into its different logical - * components and use this is the underlying structure. - */ -class Unit -{ - Q_DISABLE_COPY(Unit) - - Unit(); - explicit Unit(const QString &fileName); - -public: - ~Unit(); - - typedef QSharedPointer Ptr; - static Ptr create(); - static Ptr create(const QString &fileName); - - bool isLoaded() const; - - const QString fileName() const; - - const QDateTime &timeStamp() const; - - QStringList compilationOptions() const; - void setCompilationOptions(const QStringList &compOptions); - - Utils::UnsavedFiles unsavedFiles() const; - void setUnsavedFiles(const ClangCodeModel::Utils::UnsavedFiles &unsavedFiles); - - unsigned managementOptions() const; - void setManagementOptions(unsigned managementOptions); - - // Methods for generating the TU. Name mappings are direct, for example: - // - parse corresponds to clang_parseTranslationUnit - // - createFromSourceFile corresponds to clang_createTranslationUnitFromSourceFile - void parse(); - void reparse(); - int save(const QString &unitFileName); - void unload(); - - // Simple forwarding methods, separated by clang categories for convenience. - // As above, the names are directly mapped. Separated by categories as clang for convenience. - // Note that only methods that take the TU as a parameter should be wrapped. - - // - Diagnostic reporting - unsigned getNumDiagnostics() const; - CXDiagnostic getDiagnostic(unsigned index) const; - - // - Translation unit manipulation - CXString getTranslationUnitSpelling() const; - - // - File manipulation routines - CXFile getFile() const; - - // - Mapping between cursors and source code - CXCursor getCursor(const CXSourceLocation &location) const; - - // - Miscellaneous utility functions - void getInclusions(CXInclusionVisitor visitor, CXClientData clientData) const; - - // - Cursor manipulations - CXCursor getTranslationUnitCursor() const; - - // - Physical source locations - CXSourceLocation getLocation(const CXFile &file, unsigned line, unsigned column) const; - - void tokenize(CXSourceRange range, CXToken **tokens, unsigned *tokenCount) const; - void disposeTokens(CXToken *tokens, unsigned tokenCount) const; - CXSourceRange getTokenExtent(const CXToken &token) const; - void annotateTokens(CXToken *tokens, unsigned tokenCount, CXCursor *cursors) const; - - CXTranslationUnit clangTranslationUnit() const; - CXIndex clangIndex() const; - -private: - void updateTimeStamp(); - - CXIndex m_index; - CXTranslationUnit m_tu; - QByteArray m_fileName; - QStringList m_compOptions; - SharedClangOptions m_sharedCompOptions; - unsigned m_managementOptions; - Utils::UnsavedFiles m_unsaved; - QDateTime m_timeStamp; -}; - -class IdentifierTokens -{ - Q_DISABLE_COPY(IdentifierTokens) - -public: - IdentifierTokens(const Unit &m_unit, unsigned firstLine, unsigned lastLine); - ~IdentifierTokens(); - - unsigned count() const - { return m_tokenCount; } - - const CXToken &token(unsigned nr) const - { Q_ASSERT(nr < count()); return m_tokens[nr]; } - - const CXCursor &cursor(unsigned nr) const - { Q_ASSERT(nr < count()); return m_cursors[nr]; } - - const CXSourceRange &extent(unsigned nr) const - { Q_ASSERT(nr < count()); return m_extents[nr]; } - -private: - void dispose(); - -private: - const Unit &m_unit; - unsigned m_tokenCount; - CXToken *m_tokens; - - CXCursor *m_cursors; - CXSourceRange *m_extents; -}; - -} // Internal -} // Clang - -Q_DECLARE_METATYPE(ClangCodeModel::Internal::Unit::Ptr) - -#endif // UNIT_H diff --git a/src/plugins/clangcodemodel/unsavedfiledata.cpp b/src/plugins/clangcodemodel/unsavedfiledata.cpp deleted file mode 100644 index 7dd54c6db25..00000000000 --- a/src/plugins/clangcodemodel/unsavedfiledata.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "unsavedfiledata.h" - -using namespace ClangCodeModel::Internal; - -UnsavedFileData::UnsavedFileData(const UnsavedFiles &unsavedFiles) - : m_count(unsavedFiles.count()) - , m_files(0) -{ - if (m_count) { - m_files = new CXUnsavedFile[m_count]; - unsigned idx = 0; - for (UnsavedFiles::const_iterator it = unsavedFiles.begin(); it != unsavedFiles.end(); ++it, ++idx) { - QByteArray contents = it.value(); - const char *contentChars = qstrdup(contents.constData()); - m_files[idx].Contents = contentChars; - m_files[idx].Length = contents.size(); - - const char *fileName = qstrdup(it.key().toUtf8().constData()); - m_files[idx].Filename = fileName; - } - } -} - -UnsavedFileData::~UnsavedFileData() -{ - for (unsigned i = 0; i < m_count; ++i) { - delete[] m_files[i].Contents; - delete[] m_files[i].Filename; - } - - delete[] m_files; -} diff --git a/src/plugins/clangcodemodel/unsavedfiledata.h b/src/plugins/clangcodemodel/unsavedfiledata.h deleted file mode 100644 index a3b867db278..00000000000 --- a/src/plugins/clangcodemodel/unsavedfiledata.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANG_INTERNAL_UNSAVEDFILEDATA_H -#define CLANG_INTERNAL_UNSAVEDFILEDATA_H - -#include "clangutils.h" - -#include - -namespace ClangCodeModel { -namespace Internal { - -class UnsavedFileData -{ - UnsavedFileData(const UnsavedFileData &); - UnsavedFileData &operator=(const UnsavedFileData &); - - typedef ClangCodeModel::Utils::UnsavedFiles UnsavedFiles; - -public: - UnsavedFileData(const UnsavedFiles &unsavedFiles); - ~UnsavedFileData(); - - unsigned count() const - { return m_count; } - - CXUnsavedFile *files() const - { return m_files; } - -private: - unsigned m_count; - CXUnsavedFile *m_files; -}; - -} // namespace Internal -} // namespace ClangCodeModel - -#endif // CLANG_INTERNAL_UNSAVEDFILEDATA_H From 6a393afeda21401013fe89c061fec5cac7a811b2 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 30 Nov 2015 09:43:37 +0100 Subject: [PATCH 21/47] Clang: Remove unneeded CLANG_EXPORT Change-Id: Ib05f97212758a4dd3f1abb7774f071c9385377b4 Reviewed-by: Marco Bubke --- src/plugins/clangcodemodel/clang_global.h | 43 ------------------- src/plugins/clangcodemodel/clangcodemodel.pro | 3 -- src/plugins/clangcodemodel/clangcodemodel.qbs | 1 - .../clangcodemodel/clangprojectsettings.h | 4 +- src/plugins/clangcodemodel/clangutils.h | 2 - .../highlightingmarksreporter.h | 2 - 6 files changed, 1 insertion(+), 54 deletions(-) delete mode 100644 src/plugins/clangcodemodel/clang_global.h diff --git a/src/plugins/clangcodemodel/clang_global.h b/src/plugins/clangcodemodel/clang_global.h deleted file mode 100644 index 2f0faa7fc1c..00000000000 --- a/src/plugins/clangcodemodel/clang_global.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://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 http://www.qt.io/terms-conditions. For further information -** use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef CLANG_GLOBAL_H -#define CLANG_GLOBAL_H - -#include - -#if defined(CLANGCODEMODEL_LIBRARY) -# define CLANG_EXPORT Q_DECL_EXPORT -#else -# define CLANG_EXPORT Q_DECL_IMPORT -#endif - - -#endif // CLANG_GLOBAL_H diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index ab5e8597a85..181ac8a0b3a 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -1,8 +1,6 @@ include(../../qtcreatorplugin.pri) include(../../shared/clang/clang_installation.pri) -DEFINES += CLANGCODEMODEL_LIBRARY - # The following defines are used to determine the clang include path for intrinsics. DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\" DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\"" @@ -53,7 +51,6 @@ HEADERS += \ clangfixitoperation.h \ clangfixitoperationsextractor.h \ clangfunctionhintmodel.h \ - clang_global.h \ clangmodelmanagersupport.h \ clangprojectsettings.h \ clangprojectsettingspropertiespage.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index dc275e7ead8..cc734651edd 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -72,7 +72,6 @@ QtcPlugin { "clangfixitoperationsextractor.h", "clangfunctionhintmodel.cpp", "clangfunctionhintmodel.h", - "clang_global.h", "clangmodelmanagersupport.cpp", "clangmodelmanagersupport.h", "clangprojectsettings.cpp", diff --git a/src/plugins/clangcodemodel/clangprojectsettings.h b/src/plugins/clangcodemodel/clangprojectsettings.h index 1f38120b70e..a5956d33dfa 100644 --- a/src/plugins/clangcodemodel/clangprojectsettings.h +++ b/src/plugins/clangcodemodel/clangprojectsettings.h @@ -31,8 +31,6 @@ #ifndef CLANGPROJECTSETTINGS_H #define CLANGPROJECTSETTINGS_H -#include "clang_global.h" - #include #include @@ -40,7 +38,7 @@ namespace ClangCodeModel { -class CLANG_EXPORT ClangProjectSettings: public QObject +class ClangProjectSettings: public QObject { Q_OBJECT diff --git a/src/plugins/clangcodemodel/clangutils.h b/src/plugins/clangcodemodel/clangutils.h index 7590333a03b..7bce88179df 100644 --- a/src/plugins/clangcodemodel/clangutils.h +++ b/src/plugins/clangcodemodel/clangutils.h @@ -31,8 +31,6 @@ #ifndef CPPTOOLS_CLANGUTILS_H #define CPPTOOLS_CLANGUTILS_H -#include "clang_global.h" - #include #include diff --git a/src/plugins/clangcodemodel/highlightingmarksreporter.h b/src/plugins/clangcodemodel/highlightingmarksreporter.h index 5726ce0b58b..54ed8e3d2a9 100644 --- a/src/plugins/clangcodemodel/highlightingmarksreporter.h +++ b/src/plugins/clangcodemodel/highlightingmarksreporter.h @@ -31,8 +31,6 @@ #ifndef CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H #define CLANGCODEMODEL_HIGHLIGHTINGMARKSREPORTER_H -#include "clang_global.h" - #include #include #include From 1410bf3faf222d79b6789add5bd2b759d1abf22a Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 30 Nov 2015 09:43:50 +0100 Subject: [PATCH 22/47] Clang: Use "clang" prefix plugin files ...for consistency and to avoid future file name clashes. Change-Id: If595c8debfa1ceb01a1bb0ed34649fa513660503 Reviewed-by: Marco Bubke --- ...angactivationsequencecontextprocessor.cpp} | 4 +-- ...clangactivationsequencecontextprocessor.h} | 0 ...p => clangactivationsequenceprocessor.cpp} | 2 +- ...r.h => clangactivationsequenceprocessor.h} | 0 .../clangassistproposalitem.cpp | 2 +- src/plugins/clangcodemodel/clangcodemodel.pro | 20 ++++++------- src/plugins/clangcodemodel/clangcodemodel.qbs | 18 +++++------ .../clangcodemodel/clangcodemodelplugin.cpp | 2 +- .../clangcodemodelunittestfiles.pri | 30 ++++++++++--------- .../clangcompletionassistprocessor.cpp | 4 +-- ... clangcompletionchunkstotextconverter.cpp} | 2 +- ...=> clangcompletionchunkstotextconverter.h} | 0 .../clangcompletioncontextanalyzer.cpp | 4 +-- .../{constants.h => clangconstants.h} | 6 ++-- .../clangeditordocumentprocessor.cpp | 2 +- .../clangcodemodel/clangfunctionhintmodel.cpp | 2 +- ...cpp => clanghighlightingmarksreporter.cpp} | 2 +- ...ter.h => clanghighlightingmarksreporter.h} | 0 .../clangmodelmanagersupport.cpp | 2 +- src/plugins/clangcodemodel/clangtextmark.cpp | 2 +- ...activationsequencecontextprocessortest.cpp | 2 +- .../activationsequenceprocessortest.cpp | 2 +- .../completionchunkstotextconvertertest.cpp | 2 +- .../highlightingmarksreportertest.cpp | 2 +- 24 files changed, 57 insertions(+), 55 deletions(-) rename src/plugins/clangcodemodel/{activationsequencecontextprocessor.cpp => clangactivationsequencecontextprocessor.cpp} (98%) rename src/plugins/clangcodemodel/{activationsequencecontextprocessor.h => clangactivationsequencecontextprocessor.h} (100%) rename src/plugins/clangcodemodel/{activationsequenceprocessor.cpp => clangactivationsequenceprocessor.cpp} (99%) rename src/plugins/clangcodemodel/{activationsequenceprocessor.h => clangactivationsequenceprocessor.h} (100%) rename src/plugins/clangcodemodel/{completionchunkstotextconverter.cpp => clangcompletionchunkstotextconverter.cpp} (99%) rename src/plugins/clangcodemodel/{completionchunkstotextconverter.h => clangcompletionchunkstotextconverter.h} (100%) rename src/plugins/clangcodemodel/{constants.h => clangconstants.h} (95%) rename src/plugins/clangcodemodel/{highlightingmarksreporter.cpp => clanghighlightingmarksreporter.cpp} (99%) rename src/plugins/clangcodemodel/{highlightingmarksreporter.h => clanghighlightingmarksreporter.h} (100%) diff --git a/src/plugins/clangcodemodel/activationsequencecontextprocessor.cpp b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp similarity index 98% rename from src/plugins/clangcodemodel/activationsequencecontextprocessor.cpp rename to src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp index 1b03f0e5b75..0b19ce24aec 100644 --- a/src/plugins/clangcodemodel/activationsequencecontextprocessor.cpp +++ b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.cpp @@ -28,9 +28,9 @@ ** ****************************************************************************/ -#include "activationsequencecontextprocessor.h" +#include "clangactivationsequencecontextprocessor.h" -#include "activationsequenceprocessor.h" +#include "clangactivationsequenceprocessor.h" #include #include diff --git a/src/plugins/clangcodemodel/activationsequencecontextprocessor.h b/src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.h similarity index 100% rename from src/plugins/clangcodemodel/activationsequencecontextprocessor.h rename to src/plugins/clangcodemodel/clangactivationsequencecontextprocessor.h diff --git a/src/plugins/clangcodemodel/activationsequenceprocessor.cpp b/src/plugins/clangcodemodel/clangactivationsequenceprocessor.cpp similarity index 99% rename from src/plugins/clangcodemodel/activationsequenceprocessor.cpp rename to src/plugins/clangcodemodel/clangactivationsequenceprocessor.cpp index a7f4ea948d0..08f97558e7f 100644 --- a/src/plugins/clangcodemodel/activationsequenceprocessor.cpp +++ b/src/plugins/clangcodemodel/clangactivationsequenceprocessor.cpp @@ -28,7 +28,7 @@ ** ****************************************************************************/ -#include "activationsequenceprocessor.h" +#include "clangactivationsequenceprocessor.h" namespace ClangCodeModel { namespace Internal { diff --git a/src/plugins/clangcodemodel/activationsequenceprocessor.h b/src/plugins/clangcodemodel/clangactivationsequenceprocessor.h similarity index 100% rename from src/plugins/clangcodemodel/activationsequenceprocessor.h rename to src/plugins/clangcodemodel/clangactivationsequenceprocessor.h diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.cpp b/src/plugins/clangcodemodel/clangassistproposalitem.cpp index f44a2a8b285..f96128b9171 100644 --- a/src/plugins/clangcodemodel/clangassistproposalitem.cpp +++ b/src/plugins/clangcodemodel/clangassistproposalitem.cpp @@ -30,7 +30,7 @@ #include "clangassistproposalitem.h" -#include "completionchunkstotextconverter.h" +#include "clangcompletionchunkstotextconverter.h" #include #include diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index 181ac8a0b3a..436e15b6072 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -6,8 +6,8 @@ DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\" DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\"" SOURCES += \ - activationsequencecontextprocessor.cpp \ - activationsequenceprocessor.cpp \ + clangactivationsequencecontextprocessor.cpp \ + clangactivationsequenceprocessor.cpp \ clangassistproposal.cpp \ clangassistproposalitem.cpp \ clangassistproposalmodel.cpp \ @@ -16,6 +16,7 @@ SOURCES += \ clangcompletionassistinterface.cpp \ clangcompletionassistprocessor.cpp \ clangcompletionassistprovider.cpp \ + clangcompletionchunkstotextconverter.cpp \ clangcompletioncontextanalyzer.cpp \ clangdiagnosticfilter.cpp \ clangdiagnosticmanager.cpp \ @@ -24,17 +25,16 @@ SOURCES += \ clangfixitoperation.cpp \ clangfixitoperationsextractor.cpp \ clangfunctionhintmodel.cpp \ + clanghighlightingmarksreporter.cpp \ clangmodelmanagersupport.cpp \ clangprojectsettings.cpp \ clangprojectsettingspropertiespage.cpp \ clangtextmark.cpp \ - clangutils.cpp \ - completionchunkstotextconverter.cpp \ - highlightingmarksreporter.cpp + clangutils.cpp HEADERS += \ - activationsequencecontextprocessor.h \ - activationsequenceprocessor.h \ + clangactivationsequencecontextprocessor.h \ + clangactivationsequenceprocessor.h \ clangassistproposal.h \ clangassistproposalitem.h \ clangassistproposalmodel.h \ @@ -43,7 +43,9 @@ HEADERS += \ clangcompletionassistinterface.h \ clangcompletionassistprocessor.h \ clangcompletionassistprovider.h \ + clangcompletionchunkstotextconverter.h \ clangcompletioncontextanalyzer.h \ + clangconstants.h \ clangdiagnosticfilter.h \ clangdiagnosticmanager.h \ clangeditordocumentparser.h \ @@ -51,14 +53,12 @@ HEADERS += \ clangfixitoperation.h \ clangfixitoperationsextractor.h \ clangfunctionhintmodel.h \ + clanghighlightingmarksreporter.h \ clangmodelmanagersupport.h \ clangprojectsettings.h \ clangprojectsettingspropertiespage.h \ clangtextmark.h \ clangutils.h \ - completionchunkstotextconverter.h \ - constants.h \ - highlightingmarksreporter.h FORMS += clangprojectsettingspropertiespage.ui diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index cc734651edd..eccd34b53bb 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -36,10 +36,10 @@ QtcPlugin { } files: [ - "activationsequencecontextprocessor.cpp", - "activationsequencecontextprocessor.h", - "activationsequenceprocessor.cpp", - "activationsequenceprocessor.h", + "clangactivationsequencecontextprocessor.cpp", + "clangactivationsequencecontextprocessor.h", + "clangactivationsequenceprocessor.cpp", + "clangactivationsequenceprocessor.h", "clangassistproposal.cpp", "clangassistproposal.h", "clangassistproposalitem.cpp", @@ -56,8 +56,11 @@ QtcPlugin { "clangcompletionassistprocessor.h", "clangcompletionassistprovider.cpp", "clangcompletionassistprovider.h", + "clangcompletionchunkstotextconverter.cpp", + "clangcompletionchunkstotextconverter.h", "clangcompletioncontextanalyzer.cpp", "clangcompletioncontextanalyzer.h", + "clangconstants.h", "clangdiagnosticfilter.cpp", "clangdiagnosticfilter.h", "clangdiagnosticmanager.cpp", @@ -72,6 +75,8 @@ QtcPlugin { "clangfixitoperationsextractor.h", "clangfunctionhintmodel.cpp", "clangfunctionhintmodel.h", + "clanghighlightingmarksreporter.cpp", + "clanghighlightingmarksreporter.h", "clangmodelmanagersupport.cpp", "clangmodelmanagersupport.h", "clangprojectsettings.cpp", @@ -83,11 +88,6 @@ QtcPlugin { "clangtextmark.h", "clangutils.cpp", "clangutils.h", - "completionchunkstotextconverter.cpp", - "completionchunkstotextconverter.h", - "constants.h", - "highlightingmarksreporter.cpp", - "highlightingmarksreporter.h", ] Group { diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 069923ff5f5..ea7aa9c3d1b 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -30,8 +30,8 @@ #include "clangcodemodelplugin.h" +#include "clangconstants.h" #include "clangprojectsettingspropertiespage.h" -#include "constants.h" #ifdef WITH_TESTS # include "test/clangcodecompletion_test.h" diff --git a/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri b/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri index 1771e0e0c65..0515875a4ac 100644 --- a/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri +++ b/src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri @@ -1,17 +1,19 @@ INCLUDEPATH += $$PWD -SOURCES += $$PWD/completionchunkstotextconverter.cpp \ - $$PWD/activationsequenceprocessor.cpp \ - $$PWD/activationsequencecontextprocessor.cpp \ - $$PWD/clangcompletioncontextanalyzer.cpp \ - $$PWD/clangdiagnosticfilter.cpp \ - $$PWD/clangfixitoperation.cpp \ - $$PWD/highlightingmarksreporter.cpp +SOURCES += \ + $$PWD/clangactivationsequencecontextprocessor.cpp \ + $$PWD/clangactivationsequenceprocessor.cpp \ + $$PWD/clangcompletionchunkstotextconverter.cpp \ + $$PWD/clangcompletioncontextanalyzer.cpp \ + $$PWD/clangdiagnosticfilter.cpp \ + $$PWD/clangfixitoperation.cpp \ + $$PWD/clanghighlightingmarksreporter.cpp -HEADERS += $$PWD/completionchunkstotextconverter.h \ - $$PWD/activationsequenceprocessor.h \ - $$PWD/activationsequencecontextprocessor.h \ - $$PWD/clangcompletioncontextanalyzer.h \ - $$PWD/clangdiagnosticfilter.h \ - $$PWD/clangfixitoperation.h \ - $$PWD/highlightingmarksreporter.h +HEADERS += \ + $$PWD/clangactivationsequencecontextprocessor.h \ + $$PWD/clangactivationsequenceprocessor.h \ + $$PWD/clangcompletionchunkstotextconverter.h \ + $$PWD/clangcompletioncontextanalyzer.h \ + $$PWD/clangdiagnosticfilter.h \ + $$PWD/clangfixitoperation.h \ + $$PWD/clanghighlightingmarksreporter.h diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index 70dab8f5586..2f6b17ba82e 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -30,7 +30,7 @@ #include "clangassistproposalitem.h" -#include "activationsequenceprocessor.h" +#include "clangactivationsequenceprocessor.h" #include "clangassistproposal.h" #include "clangassistproposalmodel.h" #include "clangcompletionassistprocessor.h" @@ -38,7 +38,7 @@ #include "clangeditordocumentprocessor.h" #include "clangfunctionhintmodel.h" #include "clangutils.h" -#include "completionchunkstotextconverter.h" +#include "clangcompletionchunkstotextconverter.h" #include diff --git a/src/plugins/clangcodemodel/completionchunkstotextconverter.cpp b/src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.cpp similarity index 99% rename from src/plugins/clangcodemodel/completionchunkstotextconverter.cpp rename to src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.cpp index 68e245f6368..43e6c86f76e 100644 --- a/src/plugins/clangcodemodel/completionchunkstotextconverter.cpp +++ b/src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.cpp @@ -28,7 +28,7 @@ ** ****************************************************************************/ -#include "completionchunkstotextconverter.h" +#include "clangcompletionchunkstotextconverter.h" #include #include diff --git a/src/plugins/clangcodemodel/completionchunkstotextconverter.h b/src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.h similarity index 100% rename from src/plugins/clangcodemodel/completionchunkstotextconverter.h rename to src/plugins/clangcodemodel/clangcompletionchunkstotextconverter.h diff --git a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp index eaa2b3d90a6..f59b21db33b 100644 --- a/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp +++ b/src/plugins/clangcodemodel/clangcompletioncontextanalyzer.cpp @@ -31,8 +31,8 @@ #include "clangcompletioncontextanalyzer.h" -#include "activationsequenceprocessor.h" -#include "activationsequencecontextprocessor.h" +#include "clangactivationsequencecontextprocessor.h" +#include "clangactivationsequenceprocessor.h" #include diff --git a/src/plugins/clangcodemodel/constants.h b/src/plugins/clangcodemodel/clangconstants.h similarity index 95% rename from src/plugins/clangcodemodel/constants.h rename to src/plugins/clangcodemodel/clangconstants.h index 40192c06400..e02e9c72d31 100644 --- a/src/plugins/clangcodemodel/constants.h +++ b/src/plugins/clangcodemodel/clangconstants.h @@ -28,8 +28,8 @@ ** ****************************************************************************/ -#ifndef CONSTANTS_H -#define CONSTANTS_H +#ifndef CLANGCONSTANTS_H +#define CLANGCONSTANTS_H namespace ClangCodeModel { namespace Constants { @@ -41,4 +41,4 @@ const char CLANG_WARNING[] = "Clang.Warning"; } // namespace Constants } // namespace ClangCodeModel -#endif // CONSTANTS_H +#endif // CLANGCONSTANTS_H diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index f0744856079..a37595c5ee2 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -32,9 +32,9 @@ #include "clangfixitoperation.h" #include "clangfixitoperationsextractor.h" +#include "clanghighlightingmarksreporter.h" #include "clangmodelmanagersupport.h" #include "clangutils.h" -#include "highlightingmarksreporter.h" #include #include diff --git a/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp b/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp index d037186b995..0ce334975ff 100644 --- a/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp +++ b/src/plugins/clangcodemodel/clangfunctionhintmodel.cpp @@ -30,7 +30,7 @@ #include "clangfunctionhintmodel.h" -#include "completionchunkstotextconverter.h" +#include "clangcompletionchunkstotextconverter.h" #include diff --git a/src/plugins/clangcodemodel/highlightingmarksreporter.cpp b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp similarity index 99% rename from src/plugins/clangcodemodel/highlightingmarksreporter.cpp rename to src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp index 6b3fc07996d..698f158c654 100644 --- a/src/plugins/clangcodemodel/highlightingmarksreporter.cpp +++ b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.cpp @@ -28,7 +28,7 @@ ** ****************************************************************************/ -#include "highlightingmarksreporter.h" +#include "clanghighlightingmarksreporter.h" #include diff --git a/src/plugins/clangcodemodel/highlightingmarksreporter.h b/src/plugins/clangcodemodel/clanghighlightingmarksreporter.h similarity index 100% rename from src/plugins/clangcodemodel/highlightingmarksreporter.h rename to src/plugins/clangcodemodel/clanghighlightingmarksreporter.h diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 1b66c067e94..42e27d3a6f4 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -30,7 +30,7 @@ #include "clangmodelmanagersupport.h" -#include "constants.h" +#include "clangconstants.h" #include "clangeditordocumentprocessor.h" #include "clangutils.h" diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp index dfb19059928..e93f8233f22 100644 --- a/src/plugins/clangcodemodel/clangtextmark.cpp +++ b/src/plugins/clangcodemodel/clangtextmark.cpp @@ -30,7 +30,7 @@ #include "clangtextmark.h" -#include "constants.h" +#include "clangconstants.h" #include diff --git a/tests/unit/unittest/activationsequencecontextprocessortest.cpp b/tests/unit/unittest/activationsequencecontextprocessortest.cpp index e69f8b97f13..6bde8b0065f 100644 --- a/tests/unit/unittest/activationsequencecontextprocessortest.cpp +++ b/tests/unit/unittest/activationsequencecontextprocessortest.cpp @@ -29,7 +29,7 @@ ****************************************************************************/ -#include +#include #include diff --git a/tests/unit/unittest/activationsequenceprocessortest.cpp b/tests/unit/unittest/activationsequenceprocessortest.cpp index d5962cdc5a0..97eb7e2a020 100644 --- a/tests/unit/unittest/activationsequenceprocessortest.cpp +++ b/tests/unit/unittest/activationsequenceprocessortest.cpp @@ -28,7 +28,7 @@ ** ****************************************************************************/ -#include +#include #include diff --git a/tests/unit/unittest/completionchunkstotextconvertertest.cpp b/tests/unit/unittest/completionchunkstotextconvertertest.cpp index 8b41b44bb81..032124dfc52 100644 --- a/tests/unit/unittest/completionchunkstotextconvertertest.cpp +++ b/tests/unit/unittest/completionchunkstotextconvertertest.cpp @@ -29,7 +29,7 @@ ****************************************************************************/ #include -#include +#include #include #include diff --git a/tests/unit/unittest/highlightingmarksreportertest.cpp b/tests/unit/unittest/highlightingmarksreportertest.cpp index bc23150d472..cd543dd35dc 100644 --- a/tests/unit/unittest/highlightingmarksreportertest.cpp +++ b/tests/unit/unittest/highlightingmarksreportertest.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include From ed4bfff64498f592245087c28d95c531e8ee9667 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 27 Nov 2015 15:15:28 +0100 Subject: [PATCH 23/47] Clang: Rename "Editor Updates" to "Document Annotations" "Editor Updates" are not to the point since what we generate is for the document. Change-Id: I94ceeca5c85c7cf01cc659ca55320d07010c8617 Reviewed-by: Marco Bubke --- .../clangbackend/ipcsource/clangipcserver.cpp | 34 +++---- .../clangbackend/ipcsource/clangipcserver.h | 4 +- .../ipcsource/translationunits.cpp | 60 ++++++------ .../clangbackend/ipcsource/translationunits.h | 28 +++--- ... => mocksenddocumentannotationscallback.h} | 16 ++-- tests/unit/unittest/translationunitstest.cpp | 94 +++++++++---------- tests/unit/unittest/unittest.pro | 2 +- 7 files changed, 119 insertions(+), 119 deletions(-) rename tests/unit/unittest/{mocksendeditorupdatescallback.h => mocksenddocumentannotationscallback.h} (80%) diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index eeae3d7ffb5..311169ac6e0 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -66,40 +66,40 @@ namespace ClangBackEnd { namespace { -const int delayedEditorUpdatesTimerInterval = 300; +const int delayedDocumentAnnotationsTimerInterval = 300; } ClangIpcServer::ClangIpcServer() : translationUnits(projects, unsavedFiles) { - const auto sendEditorUpdates + const auto sendDocumentAnnotations = [this] (const DiagnosticsChangedMessage &diagnosticsMessage, const HighlightingChangedMessage &highlightingsMessage) { client()->diagnosticsChanged(diagnosticsMessage); client()->highlightingChanged(highlightingsMessage); }; - const auto sendDelayedEditorUpdates = [this] () { + const auto sendDelayedDocumentAnnotations = [this] () { try { - auto editorUpdatesSendState = translationUnits.sendDelayedEditorUpdates(); - if (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) - sendDelayedEditorUpdatesTimer.setInterval(0); + auto sendState = translationUnits.sendDocumentAnnotations(); + if (sendState == DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations) + sendDocumentAnnotationsTimer.setInterval(0); else - sendDelayedEditorUpdatesTimer.stop(); + sendDocumentAnnotationsTimer.stop(); } catch (const std::exception &exception) { - qWarning() << "Error in ClangIpcServer::sendDelayedEditorUpdatesTimer:" << exception.what(); + qWarning() << "Error in ClangIpcServer::sendDelayedDocumentAnnotationsTimer:" << exception.what(); } }; const auto onFileChanged = [this] (const Utf8String &filePath) { - startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(filePath); + startDocumentAnnotationsTimerIfFileIsNotATranslationUnit(filePath); }; - translationUnits.setSendDelayedEditorUpdatesCallback(sendEditorUpdates); + translationUnits.setSendDocumentAnnotationsCallback(sendDocumentAnnotations); - QObject::connect(&sendDelayedEditorUpdatesTimer, + QObject::connect(&sendDocumentAnnotationsTimer, &QTimer::timeout, - sendDelayedEditorUpdates); + sendDelayedDocumentAnnotations); QObject::connect(translationUnits.clangFileSystemWatcher(), &ClangFileSystemWatcher::fileChanged, @@ -118,7 +118,7 @@ void ClangIpcServer::registerTranslationUnitsForEditor(const ClangBackEnd::Regis try { translationUnits.create(message.fileContainers()); unsavedFiles.createOrUpdate(message.fileContainers()); - sendDelayedEditorUpdatesTimer.start(0); + sendDocumentAnnotationsTimer.start(0); } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); } catch (const std::exception &exception) { @@ -135,7 +135,7 @@ void ClangIpcServer::updateTranslationUnitsForEditor(const UpdateTranslationUnit if (newerFileContainers.size() > 0) { translationUnits.update(newerFileContainers); unsavedFiles.createOrUpdate(newerFileContainers); - sendDelayedEditorUpdatesTimer.start(delayedEditorUpdatesTimerInterval); + sendDocumentAnnotationsTimer.start(delayedDocumentAnnotationsTimerInterval); } } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); @@ -193,7 +193,7 @@ void ClangIpcServer::registerUnsavedFilesForEditor(const RegisterUnsavedFilesFor try { unsavedFiles.createOrUpdate(message.fileContainers()); translationUnits.updateTranslationUnitsWithChangedDependencies(message.fileContainers()); - sendDelayedEditorUpdatesTimer.start(delayedEditorUpdatesTimerInterval); + sendDocumentAnnotationsTimer.start(delayedDocumentAnnotationsTimerInterval); } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); } catch (const std::exception &exception) { @@ -292,10 +292,10 @@ const TranslationUnits &ClangIpcServer::translationUnitsForTestOnly() const return translationUnits; } -void ClangIpcServer::startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(const Utf8String &filePath) +void ClangIpcServer::startDocumentAnnotationsTimerIfFileIsNotATranslationUnit(const Utf8String &filePath) { if (!translationUnits.hasTranslationUnit(filePath)) - sendDelayedEditorUpdatesTimer.start(0); + sendDocumentAnnotationsTimer.start(0); } } diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.h b/src/tools/clangbackend/ipcsource/clangipcserver.h index 5ca9553c85b..f5f768552d9 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.h +++ b/src/tools/clangbackend/ipcsource/clangipcserver.h @@ -67,13 +67,13 @@ public: const TranslationUnits &translationUnitsForTestOnly() const; private: - void startSendDelayedEditorUpdatesTimerIfFileIsNotATranslationUnit(const Utf8String &filePath); + void startDocumentAnnotationsTimerIfFileIsNotATranslationUnit(const Utf8String &filePath); private: ProjectParts projects; UnsavedFiles unsavedFiles; TranslationUnits translationUnits; - QTimer sendDelayedEditorUpdatesTimer; + QTimer sendDocumentAnnotationsTimer; }; } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/ipcsource/translationunits.cpp b/src/tools/clangbackend/ipcsource/translationunits.cpp index 459679fc7a2..afdcd15246c 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.cpp +++ b/src/tools/clangbackend/ipcsource/translationunits.cpp @@ -166,73 +166,73 @@ void TranslationUnits::updateTranslationUnitsWithChangedDependencies(const QVect updateTranslationUnitsWithChangedDependency(fileContainer.filePath()); } -EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdates() +DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotations() { - auto editorUpdatesSendState = sendDelayedEditorUpdatesForCurrentEditor(); - if (editorUpdatesSendState == EditorUpdatesSendState::NoEditorUpdatesSend) - editorUpdatesSendState = sendDelayedEditorUpdatesForVisibleEditors(); - if (editorUpdatesSendState == EditorUpdatesSendState::NoEditorUpdatesSend) - editorUpdatesSendState = sendDelayedEditorUpdatesForAll(); + auto documentAnnotationsSendState = sendDocumentAnnotationsForCurrentEditor(); + if (documentAnnotationsSendState == DocumentAnnotationsSendState::NoDocumentAnnotationsSent) + documentAnnotationsSendState = sendDocumentAnnotationsForVisibleEditors(); + if (documentAnnotationsSendState == DocumentAnnotationsSendState::NoDocumentAnnotationsSent) + documentAnnotationsSendState = sendDocumentAnnotationsForAll(); - return editorUpdatesSendState; + return documentAnnotationsSendState; } template -EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdates(Predicate predicate) +DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotations(Predicate predicate) { auto foundTranslationUnit = std::find_if(translationUnits_.begin(), translationUnits_.end(), predicate); if (foundTranslationUnit != translationUnits().end()) { - sendDelayedEditorUpdates(*foundTranslationUnit); - return EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; + sendDocumentAnnotations(*foundTranslationUnit); + return DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations; } - return EditorUpdatesSendState::NoEditorUpdatesSend; + return DocumentAnnotationsSendState::NoDocumentAnnotationsSent; } namespace { -bool translationUnitHasEditorDocumentUpdates(const TranslationUnit &translationUnit) +bool translationUnitHasNewDocumentAnnotations(const TranslationUnit &translationUnit) { return translationUnit.hasNewDiagnostics() || translationUnit.hasNewHighlightingInformations(); } } -EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForCurrentEditor() +DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotationsForCurrentEditor() { - auto hasEditorUpdatesForCurrentEditor = [] (const TranslationUnit &translationUnit) { + auto hasDocumentAnnotationsForCurrentEditor = [] (const TranslationUnit &translationUnit) { return translationUnit.isUsedByCurrentEditor() - && translationUnitHasEditorDocumentUpdates(translationUnit); + && translationUnitHasNewDocumentAnnotations(translationUnit); }; - return sendDelayedEditorUpdates(hasEditorUpdatesForCurrentEditor); + return sendDocumentAnnotations(hasDocumentAnnotationsForCurrentEditor); } -EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForVisibleEditors() +DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotationsForVisibleEditors() { - auto hasEditorUpdatesForVisibleEditor = [] (const TranslationUnit &translationUnit) { + auto hasDocumentAnnotationsForVisibleEditor = [] (const TranslationUnit &translationUnit) { return translationUnit.isVisibleInEditor() - && translationUnitHasEditorDocumentUpdates(translationUnit); + && translationUnitHasNewDocumentAnnotations(translationUnit); }; - return sendDelayedEditorUpdates(hasEditorUpdatesForVisibleEditor); + return sendDocumentAnnotations(hasDocumentAnnotationsForVisibleEditor); } -EditorUpdatesSendState TranslationUnits::sendDelayedEditorUpdatesForAll() +DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotationsForAll() { - auto hasEditorUpdates = [] (const TranslationUnit &translationUnit) { - return translationUnitHasEditorDocumentUpdates(translationUnit); + auto hasDocumentAnnotations = [] (const TranslationUnit &translationUnit) { + return translationUnitHasNewDocumentAnnotations(translationUnit); }; - return sendDelayedEditorUpdates(hasEditorUpdates); + return sendDocumentAnnotations(hasDocumentAnnotations); } -void TranslationUnits::setSendDelayedEditorUpdatesCallback(DelayedEditorUpdatesCallback &&callback) +void TranslationUnits::setSendDocumentAnnotationsCallback(SendDocumentAnnotationsCallback &&callback) { - sendDelayedEditorUpdatesCallback = std::move(callback); + sendDocumentAnnotationsCallback = std::move(callback); } QVector TranslationUnits::newerFileContainers(const QVector &fileContainers) const @@ -354,9 +354,9 @@ void TranslationUnits::checkIfTranslationUnitsForFilePathsDoesExists(const QVect } } -void TranslationUnits::sendDelayedEditorUpdates(const TranslationUnit &translationUnit) +void TranslationUnits::sendDocumentAnnotations(const TranslationUnit &translationUnit) { - if (sendDelayedEditorUpdatesCallback) { + if (sendDocumentAnnotationsCallback) { const auto fileContainer = translationUnit.fileContainer(); DiagnosticsChangedMessage diagnosticsMessage(fileContainer, translationUnit.mainFileDiagnostics()); @@ -364,8 +364,8 @@ void TranslationUnits::sendDelayedEditorUpdates(const TranslationUnit &translati translationUnit.highlightingInformations().toHighlightingMarksContainers(), translationUnit.skippedSourceRanges().toSourceRangeContainers()); - sendDelayedEditorUpdatesCallback(std::move(diagnosticsMessage), - std::move(highlightingsMessage)); + sendDocumentAnnotationsCallback(std::move(diagnosticsMessage), + std::move(highlightingsMessage)); } } diff --git a/src/tools/clangbackend/ipcsource/translationunits.h b/src/tools/clangbackend/ipcsource/translationunits.h index aca120dad00..90df960a29b 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.h +++ b/src/tools/clangbackend/ipcsource/translationunits.h @@ -48,17 +48,18 @@ class UnsavedFiles; class DiagnosticsChangedMessage; class HighlightingChangedMessage; -enum class EditorUpdatesSendState +enum class DocumentAnnotationsSendState { - NoEditorUpdatesSend, - MaybeThereAreMoreEditorUpdates, + NoDocumentAnnotationsSent, + MaybeThereAreDocumentAnnotations, }; class TranslationUnits { public: - using DelayedEditorUpdatesCallback = std::function; + using SendDocumentAnnotationsCallback + = std::function; public: TranslationUnits(ProjectParts &projectParts, UnsavedFiles &unsavedFiles); @@ -83,13 +84,12 @@ public: void updateTranslationUnitsWithChangedDependency(const Utf8String &filePath); void updateTranslationUnitsWithChangedDependencies(const QVector &fileContainers); - EditorUpdatesSendState sendDelayedEditorUpdatesForCurrentEditor(); - EditorUpdatesSendState sendDelayedEditorUpdatesForVisibleEditors(); - EditorUpdatesSendState sendDelayedEditorUpdatesForAll(); + DocumentAnnotationsSendState sendDocumentAnnotationsForCurrentEditor(); + DocumentAnnotationsSendState sendDocumentAnnotationsForVisibleEditors(); + DocumentAnnotationsSendState sendDocumentAnnotationsForAll(); + DocumentAnnotationsSendState sendDocumentAnnotations(); - EditorUpdatesSendState sendDelayedEditorUpdates(); - - void setSendDelayedEditorUpdatesCallback(DelayedEditorUpdatesCallback &&callback); + void setSendDocumentAnnotationsCallback(SendDocumentAnnotationsCallback &&callback); QVector newerFileContainers(const QVector &fileContainers) const; @@ -108,15 +108,15 @@ private: void checkIfTranslationUnitsDoesNotExists(const QVector &fileContainers) const; void checkIfTranslationUnitsForFilePathsDoesExists(const QVector &fileContainers) const; - void sendDelayedEditorUpdates(const TranslationUnit &translationUnit); void removeTranslationUnits(const QVector &fileContainers); template - EditorUpdatesSendState sendDelayedEditorUpdates(Predicate predicate); + DocumentAnnotationsSendState sendDocumentAnnotations(Predicate predicate); + void sendDocumentAnnotations(const TranslationUnit &translationUnit); private: ClangFileSystemWatcher fileSystemWatcher; - DelayedEditorUpdatesCallback sendDelayedEditorUpdatesCallback; + SendDocumentAnnotationsCallback sendDocumentAnnotationsCallback; std::vector translationUnits_; ProjectParts &projectParts; UnsavedFiles &unsavedFiles_; diff --git a/tests/unit/unittest/mocksendeditorupdatescallback.h b/tests/unit/unittest/mocksenddocumentannotationscallback.h similarity index 80% rename from tests/unit/unittest/mocksendeditorupdatescallback.h rename to tests/unit/unittest/mocksenddocumentannotationscallback.h index 7e13281a544..15ebe7fe72c 100644 --- a/tests/unit/unittest/mocksendeditorupdatescallback.h +++ b/tests/unit/unittest/mocksenddocumentannotationscallback.h @@ -27,27 +27,27 @@ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ****************************************************************************/ -#ifndef MOCKSENDEDITORUPDATESCALLBACK_H -#define MOCKSENDEDITORUPDATESCALLBACK_H +#ifndef MOCKSENDDOCUMENTANNOTATIONSCALLBACK_H +#define MOCKSENDDOCUMENTANNOTATIONSCALLBACK_H #include #include #include #include "gtest-qt-printing.h" -class SendEditorUpdatesCallback +class SendDocumentAnnotationsCallback { public: - virtual ~SendEditorUpdatesCallback() = default; + virtual ~SendDocumentAnnotationsCallback() = default; - virtual void sendEditorUpdates() = 0; + virtual void sendDocumentAnnotations() = 0; }; -class MockSendEditorUpdatesCallback : public SendEditorUpdatesCallback +class MockSendDocumentAnnotationsCallback : public SendDocumentAnnotationsCallback { public: - MOCK_METHOD0(sendEditorUpdates, + MOCK_METHOD0(sendDocumentAnnotations, void()); }; -#endif // MOCKSENDEDITORUPDATESCALLBACK_H +#endif // MOCKSENDDOCUMENTANNOTATIONSCALLBACK_H diff --git a/tests/unit/unittest/translationunitstest.cpp b/tests/unit/unittest/translationunitstest.cpp index d502a51351e..d8a44bff4e0 100644 --- a/tests/unit/unittest/translationunitstest.cpp +++ b/tests/unit/unittest/translationunitstest.cpp @@ -47,7 +47,7 @@ #include -#include "mocksendeditorupdatescallback.h" +#include "mocksenddocumentannotationscallback.h" #include #include @@ -59,7 +59,7 @@ using ClangBackEnd::UnsavedFiles; using ClangBackEnd::ProjectPart; using ClangBackEnd::DiagnosticsChangedMessage; using ClangBackEnd::HighlightingChangedMessage; -using ClangBackEnd::EditorUpdatesSendState; +using ClangBackEnd::DocumentAnnotationsSendState; using testing::IsNull; using testing::NotNull; @@ -87,15 +87,15 @@ class TranslationUnits : public ::testing::Test { protected: void SetUp() override; - void sendAllEditorUpdates(); - void sendAllEditorUpdatesForCurrentEditor(); - void sendAllEditorUpdatesForVisibleEditors(); + void sendAllDocumentAnnotations(); + void sendAllDocumentAnnotationsForCurrentEditor(); + void sendAllDocumentAnnotationsForVisibleEditors(); protected: ClangBackEnd::ProjectParts projects; ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::TranslationUnits translationUnits{projects, unsavedFiles}; - MockSendEditorUpdatesCallback mockSendEditorUpdatesCallback; + MockSendDocumentAnnotationsCallback mockSendDocumentAnnotationsCallback; const Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"); const Utf8String headerPath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"); const Utf8String nonExistingFilePath = Utf8StringLiteral("foo.cpp"); @@ -374,55 +374,55 @@ TEST_F(TranslationUnits, IsNotVisibleEditorAfterBeingVisible) ASSERT_FALSE(translationUnit.isVisibleInEditor()); } -TEST_F(TranslationUnits, DoNotSendEditorUpdatesIfThereIsNothingToSend) +TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsIfThereIsNothingToSend) { - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(0); - sendAllEditorUpdates(); + sendAllDocumentAnnotations(); } -TEST_F(TranslationUnits, SendEditorUpdatessAfterTranslationUnitCreation) +TEST_F(TranslationUnits, SendDocumentAnnotationsAfterTranslationUnitCreation) { translationUnits.create({fileContainer, headerContainer}); - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(2); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(2); - sendAllEditorUpdates(); + sendAllDocumentAnnotations(); } -TEST_F(TranslationUnits, DoNotSendEditorUpdatesAfterGettingEditorUpdates) +TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsAfterGettingDocumentAnnotations) { translationUnits.create({fileContainer, headerContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); translationUnit.diagnostics(); // Reset translationUnit.highlightingInformations(); // Reset - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(1); - sendAllEditorUpdates(); + sendAllDocumentAnnotations(); } -TEST_F(TranslationUnits, SendEditorUpdatesForCurrentEditor) +TEST_F(TranslationUnits, SendDocumentAnnotationsForCurrentEditor) { translationUnits.create({fileContainer, headerContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); translationUnit.setIsUsedByCurrentEditor(true); - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(1); - sendAllEditorUpdatesForCurrentEditor(); + sendAllDocumentAnnotationsForCurrentEditor(); } -TEST_F(TranslationUnits, DoNotSendEditorUpdatesForCurrentEditorIfThereIsNoCurrentEditor) +TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsForCurrentEditorIfThereIsNoCurrentEditor) { translationUnits.create({fileContainer, headerContainer}); - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(0); - sendAllEditorUpdatesForCurrentEditor(); + sendAllDocumentAnnotationsForCurrentEditor(); } -TEST_F(TranslationUnits, DoNotSendEditorUpdatesForCurrentEditorAfterGettingEditorUpdates) +TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsForCurrentEditorAfterGettingDocumentAnnotations) { translationUnits.create({fileContainer, headerContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); @@ -430,21 +430,21 @@ TEST_F(TranslationUnits, DoNotSendEditorUpdatesForCurrentEditorAfterGettingEdito translationUnit.diagnostics(); // Reset translationUnit.highlightingInformations(); // Reset - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(0); - sendAllEditorUpdatesForCurrentEditor(); + sendAllDocumentAnnotationsForCurrentEditor(); } -TEST_F(TranslationUnits, DoNotSendEditorUpdatesForVisibleEditorIfThereAreNoVisibleEditors) +TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsForVisibleEditorIfThereAreNoVisibleEditors) { translationUnits.create({fileContainer, headerContainer}); - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(0); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(0); - translationUnits.sendDelayedEditorUpdatesForVisibleEditors(); + translationUnits.sendDocumentAnnotationsForVisibleEditors(); } -TEST_F(TranslationUnits, SendEditorUpdatesForVisibleEditors) +TEST_F(TranslationUnits, SendDocumentAnnotationsForVisibleEditors) { translationUnits.create({fileContainer, headerContainer}); auto fileTranslationUnit = translationUnits.translationUnit(fileContainer); @@ -452,12 +452,12 @@ TEST_F(TranslationUnits, SendEditorUpdatesForVisibleEditors) auto headerTranslationUnit = translationUnits.translationUnit(headerContainer); headerTranslationUnit.setIsVisibleInEditor(true); - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(2); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(2); - sendAllEditorUpdatesForVisibleEditors(); + sendAllDocumentAnnotationsForVisibleEditors(); } -TEST_F(TranslationUnits, SendOnlyOneEditorUpdateForVisibleEditor) +TEST_F(TranslationUnits, SendDocumentAnnotationsOnlyOnceForVisibleEditor) { translationUnits.create({fileContainer, headerContainer}); auto fileTranslationUnit = translationUnits.translationUnit(fileContainer); @@ -467,9 +467,9 @@ TEST_F(TranslationUnits, SendOnlyOneEditorUpdateForVisibleEditor) headerTranslationUnit.diagnostics(); // Reset headerTranslationUnit.highlightingInformations(); // Reset - EXPECT_CALL(mockSendEditorUpdatesCallback, sendEditorUpdates()).Times(1); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(1); - sendAllEditorUpdatesForVisibleEditors(); + sendAllDocumentAnnotationsForVisibleEditors(); } void TranslationUnits::SetUp() @@ -477,33 +477,33 @@ void TranslationUnits::SetUp() projects.createOrUpdate({ClangBackEnd::ProjectPartContainer(projectPartId)}); auto callback = [&] (const DiagnosticsChangedMessage &, const HighlightingChangedMessage &) { - mockSendEditorUpdatesCallback.sendEditorUpdates(); + mockSendDocumentAnnotationsCallback.sendDocumentAnnotations(); }; - translationUnits.setSendDelayedEditorUpdatesCallback(callback); + translationUnits.setSendDocumentAnnotationsCallback(callback); } -void TranslationUnits::sendAllEditorUpdates() +void TranslationUnits::sendAllDocumentAnnotations() { - auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; + auto sendState = DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations; - while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) - editorUpdatesSendState = translationUnits.sendDelayedEditorUpdates(); + while (sendState == DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations) + sendState = translationUnits.sendDocumentAnnotations(); } -void TranslationUnits::sendAllEditorUpdatesForCurrentEditor() +void TranslationUnits::sendAllDocumentAnnotationsForCurrentEditor() { - auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; + auto sendState = DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations; - while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) - editorUpdatesSendState = translationUnits.sendDelayedEditorUpdatesForCurrentEditor(); + while (sendState == DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations) + sendState = translationUnits.sendDocumentAnnotationsForCurrentEditor(); } -void TranslationUnits::sendAllEditorUpdatesForVisibleEditors() +void TranslationUnits::sendAllDocumentAnnotationsForVisibleEditors() { - auto editorUpdatesSendState = EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates; + auto sendState = DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations; - while (editorUpdatesSendState == EditorUpdatesSendState::MaybeThereAreMoreEditorUpdates) - editorUpdatesSendState = translationUnits.sendDelayedEditorUpdatesForVisibleEditors(); + while (sendState == DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations) + sendState = translationUnits.sendDocumentAnnotationsForVisibleEditors(); } } diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index de135d251eb..d3cefda9da0 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -68,6 +68,6 @@ HEADERS += \ spydummy.h \ matcher-diagnosticcontainer.h \ chunksreportedmonitor.h \ - mocksendeditorupdatescallback.h + mocksenddocumentannotationscallback.h OTHER_FILES += $$files(data/*) From 2186e42697da78728af71708bbae270c9f32932a Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 30 Nov 2015 14:49:18 +0100 Subject: [PATCH 24/47] Debugger: Make sure there are no bools in Python code Python doesn't like lowercase "true" or "false", so we have to convert those to int before we send the command. Change-Id: Id30ebbb0714cae23b030c78eec5e59378ac467bb Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerprotocol.cpp | 33 +++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/plugins/debugger/debuggerprotocol.cpp b/src/plugins/debugger/debuggerprotocol.cpp index 23162320368..4a1a7574b4c 100644 --- a/src/plugins/debugger/debuggerprotocol.cpp +++ b/src/plugins/debugger/debuggerprotocol.cpp @@ -853,14 +853,37 @@ void DebuggerCommand::arg(const char *name, const QJsonValue &value) args = addToJsonObject(args, name, value); } +static QJsonValue translateJsonToPython(const QJsonValue &value) +{ + // TODO: Verify that this covers all incompatibilities between python and json. + switch (value.type()) { + case QJsonValue::Bool: + // Python doesn't understand lowercase "true" or "false" + return QJsonValue(value.toBool() ? 1 : 0); + case QJsonValue::Object: { + QJsonObject object = value.toObject(); + for (QJsonObject::iterator i = object.begin(); i != object.end(); ++i) + i.value() = translateJsonToPython(i.value()); + return object; + } + case QJsonValue::Array: { + QJsonArray array = value.toArray(); + for (QJsonArray::iterator i = array.begin(); i != array.end(); ++i) + *i = translateJsonToPython(*i); + return array; + } + default: + return value; + } +} + QByteArray DebuggerCommand::argsToPython() const { - // TODO: Verify that this is really Python. - - if (args.isArray()) - return QJsonDocument(args.toArray()).toJson(QJsonDocument::Compact); + QJsonValue pythonCompatible(translateJsonToPython(args)); + if (pythonCompatible.isArray()) + return QJsonDocument(pythonCompatible.toArray()).toJson(QJsonDocument::Compact); else - return QJsonDocument(args.toObject()).toJson(QJsonDocument::Compact); + return QJsonDocument(pythonCompatible.toObject()).toJson(QJsonDocument::Compact); } QByteArray DebuggerCommand::argsToString() const From 514a96c75fb63e91ba2080679d6aa05db02666cc Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 30 Nov 2015 16:10:28 +0100 Subject: [PATCH 25/47] Clang: Don't reparse before code completion Task-number: QTCREATORBUG-15365 Change-Id: I37f623449fa95268f1a0a5d5e66d75df0582c183 Reviewed-by: Nikolai Kosjar --- src/tools/clangbackend/ipcsource/clangipcserver.cpp | 2 +- .../clangbackend/ipcsource/clangtranslationunit.cpp | 9 ++++++++- src/tools/clangbackend/ipcsource/clangtranslationunit.h | 1 + src/tools/clangbackend/ipcsource/codecompleter.cpp | 2 +- tests/unit/unittest/codecompletiontest.cpp | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index 311169ac6e0..90e9738175c 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -66,7 +66,7 @@ namespace ClangBackEnd { namespace { -const int delayedDocumentAnnotationsTimerInterval = 300; +const int delayedDocumentAnnotationsTimerInterval = 500; } ClangIpcServer::ClangIpcServer() diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp index a7dd59f27e0..5df086781ff 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp +++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.cpp @@ -173,12 +173,19 @@ CXIndex TranslationUnit::index() const } CXTranslationUnit TranslationUnit::cxTranslationUnit() const +{ + cxTranslationUnitWithoutReparsing(); + reparseTranslationUnitIfFilesAreChanged(); + + return d->translationUnit; +} + +CXTranslationUnit TranslationUnit::cxTranslationUnitWithoutReparsing() const { checkIfNull(); checkIfFileExists(); removeTranslationUnitIfProjectPartWasChanged(); createTranslationUnitIfNeeded(); - reparseTranslationUnitIfFilesAreChanged(); return d->translationUnit; } diff --git a/src/tools/clangbackend/ipcsource/clangtranslationunit.h b/src/tools/clangbackend/ipcsource/clangtranslationunit.h index 2e325ceaf62..61d58c804cd 100644 --- a/src/tools/clangbackend/ipcsource/clangtranslationunit.h +++ b/src/tools/clangbackend/ipcsource/clangtranslationunit.h @@ -97,6 +97,7 @@ public: CXIndex index() const; CXTranslationUnit cxTranslationUnit() const; + CXTranslationUnit cxTranslationUnitWithoutReparsing() const; CXUnsavedFile * cxUnsavedFiles() const; uint unsavedFilesCount() const; diff --git a/src/tools/clangbackend/ipcsource/codecompleter.cpp b/src/tools/clangbackend/ipcsource/codecompleter.cpp index 99d0637a03e..b628c51eb8f 100644 --- a/src/tools/clangbackend/ipcsource/codecompleter.cpp +++ b/src/tools/clangbackend/ipcsource/codecompleter.cpp @@ -49,7 +49,7 @@ CodeCompleter::CodeCompleter(TranslationUnit translationUnit) CodeCompletions CodeCompleter::complete(uint line, uint column) { - ClangCodeCompleteResults completeResults(clang_codeCompleteAt(translationUnit.cxTranslationUnit(), + ClangCodeCompleteResults completeResults(clang_codeCompleteAt(translationUnit.cxTranslationUnitWithoutReparsing(), translationUnit.filePath().constData(), line, column, diff --git a/tests/unit/unittest/codecompletiontest.cpp b/tests/unit/unittest/codecompletiontest.cpp index 3fbc7d0a203..efbf7ea5901 100644 --- a/tests/unit/unittest/codecompletiontest.cpp +++ b/tests/unit/unittest/codecompletiontest.cpp @@ -225,7 +225,7 @@ TEST_F(CodeCompleter, DISABLED_FunctionInChangedIncludedHeader) CodeCompletion::FunctionCompletionKind))); } -TEST_F(CodeCompleter, FunctionInChangedIncludedHeaderWithUnsavedContentInMainFile) +TEST_F(CodeCompleter, DISABLED_FunctionInChangedIncludedHeaderWithUnsavedContentInMainFile) // it's not that bad because we reparse anyway { unsavedFiles.createOrUpdate({unsavedMainFileContainer}); translationUnits.update({unsavedMainFileContainer}); From a12a8c95f9d21fe1df5ce1a58d7d104838271bc6 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 30 Nov 2015 10:55:25 +0100 Subject: [PATCH 26/47] Clang: Request diagnostics/highlighting only if needed Most of the time, the updated diagnostics/highlightings will be send by the backend on translation unit update. The other use case is changing the font settings (e.g. color), here we need to request the highlightings explicitly. Change-Id: I17a574eaf972c8bef12900241e7b33fe6ffd9dbd Reviewed-by: Marco Bubke --- .../clangbackendipcintegration.cpp | 28 +++---- .../clangbackendipcintegration.h | 11 +-- .../clangeditordocumentprocessor.cpp | 76 +++++++++---------- .../clangeditordocumentprocessor.h | 12 +-- .../clangmodelmanagersupport.cpp | 4 +- 5 files changed, 58 insertions(+), 73 deletions(-) diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 49cb0d795ce..1717792837d 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -470,23 +470,15 @@ void IpcCommunicator::updateUnsavedFile(const QString &filePath, const QByteArra documentRevision}}); } -void IpcCommunicator::requestDiagnosticsAndHighlighting(const FileContainer &fileContainer, - DocumentChangedCheck documentChangedCheck) +void IpcCommunicator::updateTranslationUnitWithRevisionCheck(const FileContainer &fileContainer) { if (m_sendMode == IgnoreSendRequests) return; - if (documentChangedCheck == DocumentChangedCheck::RevisionCheck) { - if (documentHasChanged(fileContainer.filePath())) { - updateTranslationUnitsForEditor({fileContainer}); - requestDiagnostics(fileContainer); - requestHighlighting(fileContainer); - setLastSentDocumentRevision(fileContainer.filePath(), - fileContainer.documentRevision()); - } - } else { - requestDiagnostics(fileContainer); - requestHighlighting(fileContainer); + if (documentHasChanged(fileContainer.filePath())) { + updateTranslationUnitsForEditor({fileContainer}); + setLastSentDocumentRevision(fileContainer.filePath(), + fileContainer.documentRevision()); } } @@ -504,16 +496,16 @@ void IpcCommunicator::requestHighlighting(const FileContainer &fileContainer) m_ipcSender->requestHighlighting(message); } -void IpcCommunicator::requestDiagnosticsAndHighlighting(Core::IDocument *document) +void IpcCommunicator::updateTranslationUnitWithRevisionCheck(Core::IDocument *document) { const auto textDocument = qobject_cast(document); const auto filePath = textDocument->filePath().toString(); const QString projectPartId = Utils::projectPartIdForFile(filePath); - requestDiagnosticsAndHighlighting(FileContainer(filePath, - projectPartId, - Utf8StringVector(), - textDocument->document()->revision())); + updateTranslationUnitWithRevisionCheck(FileContainer(filePath, + projectPartId, + Utf8StringVector(), + textDocument->document()->revision())); } void IpcCommunicator::updateChangeContentStartPosition(const QString &filePath, int position) diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h index 8d105cc968a..a6db278addd 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h @@ -118,8 +118,6 @@ public: using FileContainers = QVector; using ProjectPartContainers = QVector; - enum class DocumentChangedCheck { NoCheck, RevisionCheck }; - public: IpcCommunicator(); @@ -130,6 +128,8 @@ public: void unregisterProjectPartsForEditor(const QStringList &projectPartIds); void registerUnsavedFilesForEditor(const FileContainers &fileContainers); void unregisterUnsavedFilesForEditor(const FileContainers &fileContainers); + void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer); + void requestHighlighting(const ClangBackEnd::FileContainer &fileContainer); void completeCode(ClangCompletionAssistProcessor *assistProcessor, const QString &filePath, quint32 line, quint32 column, @@ -144,9 +144,8 @@ public: void updateUnsavedFileFromCppEditorDocument(const QString &filePath); void updateTranslationUnit(const QString &filePath, const QByteArray &contents, uint documentRevision); void updateUnsavedFile(const QString &filePath, const QByteArray &contents, uint documentRevision); - void requestDiagnosticsAndHighlighting(const ClangBackEnd::FileContainer &fileContainer, - DocumentChangedCheck documentChangedCheck = DocumentChangedCheck::RevisionCheck); - void requestDiagnosticsAndHighlighting(Core::IDocument *document); + void updateTranslationUnitWithRevisionCheck(const ClangBackEnd::FileContainer &fileContainer); + void updateTranslationUnitWithRevisionCheck(Core::IDocument *document); void updateChangeContentStartPosition(const QString &filePath, int position); void registerFallbackProjectPart(); @@ -167,8 +166,6 @@ private: void registerCurrentCppEditorDocuments(); void registerCurrentCodeModelUiHeaders(); - void requestHighlighting(const ClangBackEnd::FileContainer &fileContainer); - void requestDiagnostics(const ClangBackEnd::FileContainer &fileContainer); void onBackendRestarted(); void onEditorAboutToClose(Core::IEditor *editor); diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index a37595c5ee2..3d072696ab4 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -93,7 +93,7 @@ ClangEditorDocumentProcessor::~ClangEditorDocumentProcessor() void ClangEditorDocumentProcessor::run() { - requestDiagnosticsAndHighlighting(); + updateTranslationUnitIfProjectPartExists(); // Run clang parser disconnect(&m_parserWatcher, &QFutureWatcher::finished, @@ -121,7 +121,9 @@ void ClangEditorDocumentProcessor::recalculateSemanticInfoDetached(bool force) void ClangEditorDocumentProcessor::semanticRehighlight() { m_semanticHighlighter.updateFormatMapFromFontSettings(); - requestDiagnosticsAndHighlighting(DocumentChangedCheck::NoCheck); + + if (m_projectPart) + requestDocumentAnnotations(m_projectPart->id()); } CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo() @@ -217,9 +219,9 @@ TextEditor::QuickFixOperations ClangEditorDocumentProcessor::extraRefactoringOpe return extractor.extract(assistInterface.fileName(), currentLine(assistInterface)); } -ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainer() const +ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithArguments() const { - return fileContainer(m_projectPart.data()); + return fileContainerWithArguments(m_projectPart.data()); } void ClangEditorDocumentProcessor::clearDiagnosticsWithFixIts() @@ -243,8 +245,7 @@ void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor( const CppTools::ProjectPart::Ptr projectPart = m_parser->projectPart(); if (isProjectPartLoadedOrIsFallback(projectPart)) { - updateTranslationUnitForEditor(projectPart.data()); - requestDiagnosticsAndHighlighting(projectPart.data()); + registerTranslationUnitForEditor(projectPart.data()); m_projectPart = projectPart; } @@ -258,56 +259,41 @@ void ClangEditorDocumentProcessor::onParserFinished() updateProjectPartAndTranslationUnitForEditor(); } -void ClangEditorDocumentProcessor::updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart) +void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart) { QTC_ASSERT(m_modelManagerSupport, return); IpcCommunicator &ipcCommunicator = m_modelManagerSupport->ipcCommunicator(); if (m_projectPart) { if (projectPart->id() != m_projectPart->id()) { - ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainer()}); - ipcCommunicator.registerTranslationUnitsForEditor({fileContainer(projectPart)}); + ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); + ipcCommunicator.registerTranslationUnitsForEditor({fileContainerWithArguments(projectPart)}); + requestDocumentAnnotations(projectPart->id()); } } else { - ipcCommunicator.registerTranslationUnitsForEditor({{fileContainer(projectPart)}}); + ipcCommunicator.registerTranslationUnitsForEditor({{fileContainerWithArguments(projectPart)}}); + requestDocumentAnnotations(projectPart->id()); } } -void ClangEditorDocumentProcessor::requestDiagnosticsAndHighlighting(CppTools::ProjectPart *projectPart) -{ - if (!m_projectPart || projectPart->id() != m_projectPart->id()) { - IpcCommunicator &ipcCommunicator = m_modelManagerSupport->ipcCommunicator(); - - const ClangBackEnd::FileContainer fileContainer_ = fileContainer(projectPart); - ipcCommunicator.requestDiagnosticsAndHighlighting(fileContainer_); - } -} - -IpcCommunicator::DocumentChangedCheck -toIpcCommunicatorDocumentChangedCheck(ClangEditorDocumentProcessor::DocumentChangedCheck condition) -{ - return condition == ClangEditorDocumentProcessor::DocumentChangedCheck::RevisionCheck - ? IpcCommunicator::DocumentChangedCheck::RevisionCheck - : IpcCommunicator::DocumentChangedCheck::NoCheck; -} - -void ClangEditorDocumentProcessor::requestDiagnosticsAndHighlighting(DocumentChangedCheck documentChangedCheck) +void ClangEditorDocumentProcessor::updateTranslationUnitIfProjectPartExists() { if (m_projectPart) { - auto &ipcCommunicator = m_modelManagerSupport->ipcCommunicator(); + const ClangBackEnd::FileContainer fileContainer = fileContainerWithDocumentContent(m_projectPart->id()); - const ClangBackEnd::FileContainer fileContainer(filePath(), - m_projectPart->id(), - baseTextDocument()->plainText(), - true, - revision()); - - const auto documentCheck = toIpcCommunicatorDocumentChangedCheck(documentChangedCheck); - - ipcCommunicator.requestDiagnosticsAndHighlighting(fileContainer, documentCheck); + m_modelManagerSupport->ipcCommunicator().updateTranslationUnitWithRevisionCheck(fileContainer); } } +void ClangEditorDocumentProcessor::requestDocumentAnnotations(const QString &projectpartId) +{ + const auto fileContainer = fileContainerWithDocumentContent(projectpartId); + + auto &ipcCommunicator = m_modelManagerSupport->ipcCommunicator(); + ipcCommunicator.requestDiagnostics(fileContainer); + ipcCommunicator.requestHighlighting(fileContainer); +} + static CppTools::ProjectPart projectPartForLanguageOption(CppTools::ProjectPart *projectPart) { if (projectPart) @@ -331,7 +317,7 @@ static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart } ClangBackEnd::FileContainer -ClangEditorDocumentProcessor::fileContainer(CppTools::ProjectPart *projectPart) const +ClangEditorDocumentProcessor::fileContainerWithArguments(CppTools::ProjectPart *projectPart) const { const auto projectPartId = projectPart ? Utf8String::fromString(projectPart->id()) @@ -341,5 +327,15 @@ ClangEditorDocumentProcessor::fileContainer(CppTools::ProjectPart *projectPart) return {filePath(), projectPartId, Utf8StringVector(theFileArguments), revision()}; } +ClangBackEnd::FileContainer +ClangEditorDocumentProcessor::fileContainerWithDocumentContent(const QString &projectpartId) const +{ + return ClangBackEnd::FileContainer(filePath(), + projectpartId, + baseTextDocument()->plainText(), + true, + revision()); +} + } // namespace Internal } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h index cc696cc8e9a..323f0f54a62 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.h +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.h @@ -83,12 +83,11 @@ public: TextEditor::QuickFixOperations extraRefactoringOperations(const TextEditor::AssistInterface &assistInterface) override; - ClangBackEnd::FileContainer fileContainer() const; + ClangBackEnd::FileContainer fileContainerWithArguments() const; void clearDiagnosticsWithFixIts(); public: - enum class DocumentChangedCheck { NoCheck, RevisionCheck }; static ClangEditorDocumentProcessor *get(const QString &filePath); private slots: @@ -96,10 +95,11 @@ private slots: private: void updateProjectPartAndTranslationUnitForEditor(); - void updateTranslationUnitForEditor(CppTools::ProjectPart *projectPart); - void requestDiagnosticsAndHighlighting(CppTools::ProjectPart *projectPart); - void requestDiagnosticsAndHighlighting(DocumentChangedCheck documentChangedCheck = DocumentChangedCheck::RevisionCheck); - ClangBackEnd::FileContainer fileContainer(CppTools::ProjectPart *projectPart) const; + void registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart); + void updateTranslationUnitIfProjectPartExists(); + void requestDocumentAnnotations(const QString &projectpartId); + ClangBackEnd::FileContainer fileContainerWithArguments(CppTools::ProjectPart *projectPart) const; + ClangBackEnd::FileContainer fileContainerWithDocumentContent(const QString &projectpartId) const; private: ClangDiagnosticManager m_diagnosticManager; diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 42e27d3a6f4..c9e16252eb9 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -193,7 +193,7 @@ void ModelManagerSupportClang::onCppDocumentReloadFinishedOnTranslationUnit(bool if (success) { TextEditor::TextDocument *textDocument = qobject_cast(sender()); connectToTextDocumentContentsChangedForTranslationUnit(textDocument); - m_ipcCommunicator.requestDiagnosticsAndHighlighting(textDocument); + m_ipcCommunicator.updateTranslationUnitWithRevisionCheck(textDocument); } } @@ -342,7 +342,7 @@ void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts( { const auto processors = clangProcessorsWithProjectParts(projectPartIds); foreach (ClangEditorDocumentProcessor *processor, processors) { - m_ipcCommunicator.unregisterTranslationUnitsForEditor({processor->fileContainer()}); + m_ipcCommunicator.unregisterTranslationUnitsForEditor({processor->fileContainerWithArguments()}); processor->clearProjectPart(); processor->run(); } From 8650954f0a4ef97bab3286501c4b0e2448556931 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 30 Nov 2015 17:53:52 +0100 Subject: [PATCH 27/47] Clang: Increase delayedDocumentAnnotationsTimerInterval to 3s We experimented around and 3s are a good compromise. Change-Id: Ib1d73738b221408c753c194b2122f82bae8d5eb2 Reviewed-by: Marco Bubke --- src/tools/clangbackend/ipcsource/clangipcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index 90e9738175c..30f84c09794 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -66,7 +66,7 @@ namespace ClangBackEnd { namespace { -const int delayedDocumentAnnotationsTimerInterval = 500; +const int delayedDocumentAnnotationsTimerInterval = 3000; } ClangIpcServer::ClangIpcServer() From bfeb60ace592950eb148808716edf2d7bc69b477 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 30 Nov 2015 10:17:45 +0100 Subject: [PATCH 28/47] VcsBase: Fix ClearCase plugin unit test Change-Id: Icd1ff6a3e58a654babae4ebf3a4e33a26c4a58f4 (cherry picked from commit b3b3b41a7f8f06f281e18df33f46cf5a0b6c9d0d) Reviewed-by: Orgad Shaneh Reviewed-by: Christian Stenger --- src/plugins/vcsbase/vcsbase.pro | 2 ++ src/plugins/vcsbase/vcsbase.qbs | 2 ++ src/plugins/vcsbase/vcsbaseeditor.cpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/plugins/vcsbase/vcsbase.pro b/src/plugins/vcsbase/vcsbase.pro index b433f817433..e256da05153 100644 --- a/src/plugins/vcsbase/vcsbase.pro +++ b/src/plugins/vcsbase/vcsbase.pro @@ -64,3 +64,5 @@ FORMS += commonsettingspage.ui \ nicknamedialog.ui \ cleandialog.ui \ submiteditorwidget.ui + +equals(TEST, 1): DEFINES += "SRC_DIR=\\\"$$IDE_SOURCE_TREE\\\"" diff --git a/src/plugins/vcsbase/vcsbase.qbs b/src/plugins/vcsbase/vcsbase.qbs index 857577a46a9..fc120227722 100644 --- a/src/plugins/vcsbase/vcsbase.qbs +++ b/src/plugins/vcsbase/vcsbase.qbs @@ -83,4 +83,6 @@ QtcPlugin { "wizard/vcsjsextension.cpp", "wizard/vcsjsextension.h", ] + + cpp.defines: base.concat( testsEnabled ? ['SRC_DIR="' + project.ide_source_tree + '"'] : [] ) } diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index cb1c238aba2..0925088a83b 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -1635,6 +1635,8 @@ void VcsBase::VcsBaseEditorWidget::testDiffFileResolving(const char *id) QFETCH(QByteArray, fileName); QTextDocument doc(QString::fromLatin1(header)); QTextBlock block = doc.lastBlock(); + // set source root for shadow builds + widget->setSource(QString::fromLatin1(SRC_DIR)); QVERIFY(widget->fileNameFromDiffSpecification(block).endsWith(QString::fromLatin1(fileName))); delete editor; From db5bd69b261ed200287b0a06b3c9d979d86380f4 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 1 Dec 2015 11:29:47 +0100 Subject: [PATCH 29/47] Android: Add support for Android 6.0 Change-Id: Icd6a1904d7c1d6fecad3363d9cf72699e01db9f0 Reviewed-by: BogDan Vatra --- src/plugins/android/androidmanager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index e82a14ed85e..54e843954db 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -280,7 +280,7 @@ QString AndroidManager::loadLocalJarsInitClasses(ProjectExplorer::Target *target QPair AndroidManager::apiLevelRange() { - return qMakePair(9, 22); + return qMakePair(9, 23); } QString AndroidManager::androidNameForApiLevel(int x) @@ -324,6 +324,8 @@ QString AndroidManager::androidNameForApiLevel(int x) return QLatin1String("Android 5.0"); case 22: return QLatin1String("Android 5.1"); + case 23: + return QLatin1String("Android 6.0"); default: return tr("Unknown Android version. API Level: %1").arg(QString::number(x)); } From d579608e8a74c2179d44192556cf0b9debe817a4 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 1 Dec 2015 11:57:08 +0100 Subject: [PATCH 30/47] Clang: Prioritize current and visible translation units We reparse first the current and then the visible translation units before we reparse all other units. The signals connections are queued to wait for the visible editor update. Change-Id: I5e2b8bc80568450268ca24e26720b3f5af640995 Reviewed-by: Nikolai Kosjar --- .../clangbackendipcintegration.cpp | 88 +++++++++++++++++++ .../clangbackendipcintegration.h | 5 ++ .../clangeditordocumentprocessor.cpp | 2 + .../clangmodelmanagersupport.cpp | 16 +++- .../clangcodemodel/clangmodelmanagersupport.h | 1 + .../test/clangcodecompletion_test.cpp | 9 ++ src/plugins/cpptools/cppmodelmanager.cpp | 2 +- src/plugins/cpptools/cppmodelmanager.h | 2 +- 8 files changed, 121 insertions(+), 4 deletions(-) diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 1717792837d..887522263fb 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -68,6 +68,7 @@ #include #include #include +#include #include @@ -223,6 +224,7 @@ public: void completeCode(const ClangBackEnd::CompleteCodeMessage &message) override; void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) override; void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) override; + void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override; private: ClangBackEnd::ConnectionClient &m_connection; @@ -294,6 +296,12 @@ void IpcSender::requestHighlighting(const RequestHighlightingMessage &message) m_connection.serverProxy().requestHighlighting(message); } +void IpcSender::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) +{ + QTC_CHECK(m_connection.isConnected()); + m_connection.serverProxy().updateVisibleTranslationUnits(message); +} + IpcCommunicator::IpcCommunicator() : m_connection(&m_ipcReceiver) , m_ipcSender(new IpcSender(m_connection)) @@ -370,6 +378,85 @@ void IpcCommunicator::registerFallbackProjectPart() registerProjectPartsForEditor({projectPartContainer}); } +namespace { +Utf8String currentCppEditorDocumentFilePath() +{ + Utf8String currentCppEditorDocumentFilePath; + + const auto currentEditor = Core::EditorManager::currentEditor(); + if (currentEditor && CppTools::CppModelManager::isCppEditor(currentEditor)) { + const auto currentDocument = currentEditor->document(); + if (currentDocument) + currentCppEditorDocumentFilePath = currentDocument->filePath().toString(); + } + + return currentCppEditorDocumentFilePath; +} + +void removeDuplicates(Utf8StringVector &visibleEditorDocumentsFilePaths) +{ + std::sort(visibleEditorDocumentsFilePaths.begin(), + visibleEditorDocumentsFilePaths.end()); + const auto end = std::unique(visibleEditorDocumentsFilePaths.begin(), + visibleEditorDocumentsFilePaths.end()); + visibleEditorDocumentsFilePaths.erase(end, + visibleEditorDocumentsFilePaths.end()); +} + +void removeNonCppEditors(QList &visibleEditors) +{ + const auto isNotCppEditor = [] (Core::IEditor *editor) { + return !CppTools::CppModelManager::isCppEditor(editor); + }; + + const auto end = std::remove_if(visibleEditors.begin(), + visibleEditors.end(), + isNotCppEditor); + + visibleEditors.erase(end, visibleEditors.end()); +} + +Utf8StringVector visibleCppEditorDocumentsFilePaths() +{ + auto visibleEditors = Core::EditorManager::visibleEditors(); + + removeNonCppEditors(visibleEditors); + + Utf8StringVector visibleCppEditorDocumentsFilePaths; + visibleCppEditorDocumentsFilePaths.reserve(visibleEditors.size()); + + const auto editorFilePaths = [] (Core::IEditor *editor) { + return Utf8String(editor->document()->filePath().toString()); + }; + + std::transform(visibleEditors.begin(), + visibleEditors.end(), + std::back_inserter(visibleCppEditorDocumentsFilePaths), + editorFilePaths); + + removeDuplicates(visibleCppEditorDocumentsFilePaths); + + return visibleCppEditorDocumentsFilePaths; +} + +} + +void IpcCommunicator::updateTranslationUnitVisiblity() +{ + updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths()); +} + +void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorsFilePaths) +{ + if (m_sendMode == IgnoreSendRequests) + return; + + const UpdateVisibleTranslationUnitsMessage message(currentEditorFilePath, visibleEditorsFilePaths); + qCDebug(log) << ">>>" << message; + m_ipcSender->updateVisibleTranslationUnits(message); +} + void IpcCommunicator::registerCurrentProjectParts() { using namespace CppTools; @@ -561,6 +648,7 @@ void IpcCommunicator::initializeBackendWithCurrentData() registerCurrentProjectParts(); registerCurrentCppEditorDocuments(); registerCurrentCodeModelUiHeaders(); + updateTranslationUnitVisiblity(); emit backendReinitialized(); } diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h index a6db278addd..160de329ef9 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h @@ -107,6 +107,7 @@ public: virtual void completeCode(const ClangBackEnd::CompleteCodeMessage &message) = 0; virtual void requestDiagnostics(const ClangBackEnd::RequestDiagnosticsMessage &message) = 0; virtual void requestHighlighting(const ClangBackEnd::RequestHighlightingMessage &message) = 0; + virtual void updateVisibleTranslationUnits(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message) = 0; }; class IpcCommunicator : public QObject @@ -149,6 +150,7 @@ public: void updateChangeContentStartPosition(const QString &filePath, int position); void registerFallbackProjectPart(); + void updateTranslationUnitVisiblity(); public: // for tests IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender); @@ -171,6 +173,9 @@ private: void onEditorAboutToClose(Core::IEditor *editor); void onCoreAboutToClose(); + void updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorsFilePaths); + private: IpcReceiver m_ipcReceiver; ClangBackEnd::ConnectionClient m_connection; diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 3d072696ab4..1485c944030 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -268,10 +268,12 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr if (projectPart->id() != m_projectPart->id()) { ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); ipcCommunicator.registerTranslationUnitsForEditor({fileContainerWithArguments(projectPart)}); + ipcCommunicator.updateTranslationUnitVisiblity(); requestDocumentAnnotations(projectPart->id()); } } else { ipcCommunicator.registerTranslationUnitsForEditor({{fileContainerWithArguments(projectPart)}}); + ipcCommunicator.updateTranslationUnitVisiblity(); requestDocumentAnnotations(projectPart->id()); } } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index c9e16252eb9..8dd11df681a 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -66,9 +66,14 @@ ModelManagerSupportClang::ModelManagerSupportClang() Core::EditorManager *editorManager = Core::EditorManager::instance(); connect(editorManager, &Core::EditorManager::currentEditorChanged, - this, &ModelManagerSupportClang::onCurrentEditorChanged); + this, &ModelManagerSupportClang::onCurrentEditorChanged, + Qt::QueuedConnection); connect(editorManager, &Core::EditorManager::editorOpened, - this, &ModelManagerSupportClang::onEditorOpened); + this, &ModelManagerSupportClang::onEditorOpened, + Qt::QueuedConnection); + connect(editorManager, &Core::EditorManager::editorsClosed, + this, &ModelManagerSupportClang::onEditorClosed, + Qt::QueuedConnection); CppTools::CppModelManager *modelManager = cppModelManager(); connect(modelManager, &CppTools::CppModelManager::abstractEditorSupportContentsUpdated, @@ -111,6 +116,8 @@ void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent) m_previousCppEditor = newCurrent; else m_previousCppEditor.clear(); + + m_ipcCommunicator.updateTranslationUnitVisiblity(); } void ModelManagerSupportClang::connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument) @@ -181,6 +188,11 @@ void ModelManagerSupportClang::onEditorOpened(Core::IEditor *editor) } } +void ModelManagerSupportClang::onEditorClosed(const QList &) +{ + m_ipcCommunicator.updateTranslationUnitVisiblity(); +} + void ModelManagerSupportClang::onCppDocumentAboutToReloadOnTranslationUnit() { TextEditor::TextDocument *textDocument = qobject_cast(sender()); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 54478a6ee53..bbc44f4a6dc 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -71,6 +71,7 @@ public: private: void onEditorOpened(Core::IEditor *editor); + void onEditorClosed(const QList &editors); void onCurrentEditorChanged(Core::IEditor *newCurrent); void onCppDocumentAboutToReloadOnTranslationUnit(); void onCppDocumentReloadFinishedOnTranslationUnit(bool success); diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index fca3051875d..41d12cce5ea 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -385,6 +385,11 @@ QString toString(const RequestHighlightingMessage &) return QStringLiteral("RequestHighlightingMessage\n"); } +QString toString(const UpdateVisibleTranslationUnitsMessage &) +{ + return QStringLiteral("UpdateVisibleTranslationUnitsMessage\n"); +} + class IpcSenderSpy : public IpcSenderInterface { public: @@ -421,6 +426,9 @@ public: void requestHighlighting(const RequestHighlightingMessage &message) override { senderLog.append(toString(message)); } + void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override + { senderLog.append(toString(message)); } + public: QString senderLog; }; @@ -1074,6 +1082,7 @@ void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderInOtherEdi // Switch back to source file and check if modified header is reflected in completions. Core::EditorManager::activateEditor(openSource.editor()); + QCoreApplication::processEvents(); // connections are queued proposal = completionResults(openSource.editor()); QVERIFY(hasItem(proposal, "globalFromHeader")); QVERIFY(hasItem(proposal, "globalFromHeaderUnsaved")); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 079de7cfdd7..7a94dbb5809 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -936,7 +936,7 @@ ProjectPart::Ptr CppModelManager::fallbackProjectPart() return part; } -bool CppModelManager::isCppEditor(Core::IEditor *editor) const +bool CppModelManager::isCppEditor(Core::IEditor *editor) { return editor->context().contains(ProjectExplorer::Constants::LANG_CXX); } diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index dac3973bce5..1c4b91ebf0f 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -120,7 +120,7 @@ public: const QByteArray &contents); void emitAbstractEditorSupportRemoved(const QString &filePath); - bool isCppEditor(Core::IEditor *editor) const; + static bool isCppEditor(Core::IEditor *editor); bool isClangCodeModelAvailable() const; bool isClangCodeModelActive() const; From a5a08647417af4cfc0e79bfc27ec4e28bc642174 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 30 Nov 2015 09:59:52 +0100 Subject: [PATCH 31/47] Clang: Fix warnings about unused members Remove the unused members and remove also ClangAssistProposalModel::[m_]replaceDotForArrow, which is a needled indirection. Change-Id: If6e0f65678b05fabd5fa16823a7a4c634b9fbdef Reviewed-by: Marco Bubke --- src/plugins/clangcodemodel/clangassistproposal.cpp | 2 +- src/plugins/clangcodemodel/clangassistproposal.h | 3 --- .../clangcodemodel/clangassistproposalmodel.cpp | 7 ------- .../clangcodemodel/clangassistproposalmodel.h | 13 ------------- 4 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/plugins/clangcodemodel/clangassistproposal.cpp b/src/plugins/clangcodemodel/clangassistproposal.cpp index 4bb34a97c1d..6904f9abfcb 100644 --- a/src/plugins/clangcodemodel/clangassistproposal.cpp +++ b/src/plugins/clangcodemodel/clangassistproposal.cpp @@ -42,7 +42,7 @@ ClangAssistProposal::ClangAssistProposal(int cursorPos, TextEditor::GenericPropo bool ClangAssistProposal::isCorrective() const { - return ClangAssistProposalModel::replaceDotForArrow(model()); + return false; } void ClangAssistProposal::makeCorrection(TextEditor::TextEditorWidget *editorWidget) diff --git a/src/plugins/clangcodemodel/clangassistproposal.h b/src/plugins/clangcodemodel/clangassistproposal.h index 6a0ada3d79e..198f7397422 100644 --- a/src/plugins/clangcodemodel/clangassistproposal.h +++ b/src/plugins/clangcodemodel/clangassistproposal.h @@ -45,9 +45,6 @@ public: virtual bool isCorrective() const; virtual void makeCorrection(TextEditor::TextEditorWidget *editorWidget); - -private: - bool m_replaceDotForArrow; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangassistproposalmodel.cpp b/src/plugins/clangcodemodel/clangassistproposalmodel.cpp index b07b2eb42e4..d4085b39298 100644 --- a/src/plugins/clangcodemodel/clangassistproposalmodel.cpp +++ b/src/plugins/clangcodemodel/clangassistproposalmodel.cpp @@ -39,13 +39,6 @@ namespace ClangCodeModel { namespace Internal { -bool ClangAssistProposalModel::replaceDotForArrow(TextEditor::IAssistProposalModel *model) -{ - auto clangAssistProposalModel = static_cast(model); - - return clangAssistProposalModel->m_replaceDotForArrow; -} - bool ClangAssistProposalModel::isSortable(const QString &/*prefix*/) const { return true; diff --git a/src/plugins/clangcodemodel/clangassistproposalmodel.h b/src/plugins/clangcodemodel/clangassistproposalmodel.h index 408ee990ebd..5f7b1f502a0 100644 --- a/src/plugins/clangcodemodel/clangassistproposalmodel.h +++ b/src/plugins/clangcodemodel/clangassistproposalmodel.h @@ -41,21 +41,8 @@ namespace Internal { class ClangAssistProposalModel : public TextEditor::GenericProposalModel { public: - ClangAssistProposalModel() - : m_sortable(false) - , m_completionOperator(CPlusPlus::T_EOF_SYMBOL) - , m_replaceDotForArrow(false) - {} - bool isSortable(const QString &prefix) const override; void sort(const QString &prefix) override; - - static bool replaceDotForArrow(IAssistProposalModel *model); - -private: - bool m_sortable; - unsigned m_completionOperator; - bool m_replaceDotForArrow; }; } // namespace Internal From 5f29a00c8984598e8679be15bea3e6568559469f Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 30 Nov 2015 20:32:47 +0100 Subject: [PATCH 32/47] Clang: Change temporary directory for clangbackend This is meant to 1. Work around a libclang bug on Windows (not deleting preamble files) 2. Delete left-over preamble files in case of a clangbackend crash The temporary diretory will be removed on Qt Creator exit. Task-number: QTCREATORBUG-10988 Change-Id: Ia5837c2a6ab2d55366d167dd591d87faaededf3e Reviewed-by: Marco Bubke Reviewed-by: Nikolai Kosjar --- src/libs/clangbackendipc/connectionclient.cpp | 25 ++++++++++++++++++- src/libs/clangbackendipc/connectionclient.h | 3 +++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/libs/clangbackendipc/connectionclient.cpp b/src/libs/clangbackendipc/connectionclient.cpp index f535604168f..0e043cb115e 100644 --- a/src/libs/clangbackendipc/connectionclient.cpp +++ b/src/libs/clangbackendipc/connectionclient.cpp @@ -37,11 +37,19 @@ #include #include +#include #include namespace ClangBackEnd { namespace { +const QTemporaryDir &temporaryDirectory() +{ + static QTemporaryDir temporaryDirectory(QDir::tempPath() + QStringLiteral("/qtc-clang-XXXXXX")); + + return temporaryDirectory; +} + QString currentProcessId() { return QString::number(QCoreApplication::applicationPid()); @@ -49,7 +57,7 @@ QString currentProcessId() QString connectionName() { - return QStringLiteral("ClangBackEnd-") + currentProcessId(); + return temporaryDirectory().path() + QStringLiteral("/ClangBackEnd-") + currentProcessId(); } } @@ -128,6 +136,20 @@ void ConnectionClient::setProcessAliveTimerInterval(int processTimerInterval) processAliveTimer.setInterval(processTimerInterval); } +QProcessEnvironment ConnectionClient::processEnvironment() const +{ + auto processEnvironment = QProcessEnvironment::systemEnvironment(); + + if (temporaryDirectory().isValid()) { + const QString temporaryDirectoryPath = temporaryDirectory().path(); + processEnvironment.insert(QStringLiteral("TMPDIR"), temporaryDirectoryPath); + processEnvironment.insert(QStringLiteral("TMP"), temporaryDirectoryPath); + processEnvironment.insert(QStringLiteral("TEMP"), temporaryDirectoryPath); + } + + return processEnvironment; +} + void ConnectionClient::startProcess() { TIME_SCOPE_DURATION("ConnectionClient::startProcess"); @@ -135,6 +157,7 @@ void ConnectionClient::startProcess() if (!isProcessIsRunning()) { connectProcessFinished(); connectStandardOutputAndError(); + process()->setProcessEnvironment(processEnvironment()); process()->start(processPath(), {connectionName()}); process()->waitForStarted(); resetProcessAliveTimer(); diff --git a/src/libs/clangbackendipc/connectionclient.h b/src/libs/clangbackendipc/connectionclient.h index bcd83d67673..147c9bd4f8d 100644 --- a/src/libs/clangbackendipc/connectionclient.h +++ b/src/libs/clangbackendipc/connectionclient.h @@ -35,6 +35,7 @@ #include "lineprefixer.h" #include +#include #include @@ -100,6 +101,8 @@ private: void ensureMessageIsWritten(); + QProcessEnvironment processEnvironment() const; + private: mutable std::unique_ptr process_; QLocalSocket localSocket; From a992a1064cae6f8f7e2ada90d8c73924f9695314 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 1 Dec 2015 14:08:37 +0100 Subject: [PATCH 33/47] Clang: Update document annotations only if document is visible So no reparsing is happen for invisible files. Change-Id: I8bf3fe8aed38b30ceeabc50ba2f216acc4b8b718 Reviewed-by: Nikolai Kosjar --- src/tools/clangbackend/ipcsource/clangipcserver.cpp | 1 + src/tools/clangbackend/ipcsource/translationunits.cpp | 2 -- tests/unit/unittest/translationunitstest.cpp | 7 ++++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index 30f84c09794..979eb3ff954 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -282,6 +282,7 @@ void ClangIpcServer::updateVisibleTranslationUnits(const UpdateVisibleTranslatio try { translationUnits.setUsedByCurrentEditor(message.currentEditorFilePath()); translationUnits.setVisibleInEditors(message.visibleEditorFilePaths()); + sendDocumentAnnotationsTimer.start(0); } catch (const std::exception &exception) { qWarning() << "Error in ClangIpcServer::updateVisibleTranslationUnits:" << exception.what(); } diff --git a/src/tools/clangbackend/ipcsource/translationunits.cpp b/src/tools/clangbackend/ipcsource/translationunits.cpp index afdcd15246c..c66be73d9bb 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.cpp +++ b/src/tools/clangbackend/ipcsource/translationunits.cpp @@ -171,8 +171,6 @@ DocumentAnnotationsSendState TranslationUnits::sendDocumentAnnotations() auto documentAnnotationsSendState = sendDocumentAnnotationsForCurrentEditor(); if (documentAnnotationsSendState == DocumentAnnotationsSendState::NoDocumentAnnotationsSent) documentAnnotationsSendState = sendDocumentAnnotationsForVisibleEditors(); - if (documentAnnotationsSendState == DocumentAnnotationsSendState::NoDocumentAnnotationsSent) - documentAnnotationsSendState = sendDocumentAnnotationsForAll(); return documentAnnotationsSendState; } diff --git a/tests/unit/unittest/translationunitstest.cpp b/tests/unit/unittest/translationunitstest.cpp index d8a44bff4e0..99c6d23c850 100644 --- a/tests/unit/unittest/translationunitstest.cpp +++ b/tests/unit/unittest/translationunitstest.cpp @@ -381,11 +381,11 @@ TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsIfThereIsNothingToSend) sendAllDocumentAnnotations(); } -TEST_F(TranslationUnits, SendDocumentAnnotationsAfterTranslationUnitCreation) +TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsAfterTranslationUnitCreation) { translationUnits.create({fileContainer, headerContainer}); - EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(2); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(0); sendAllDocumentAnnotations(); } @@ -394,10 +394,11 @@ TEST_F(TranslationUnits, DoNotSendDocumentAnnotationsAfterGettingDocumentAnnotat { translationUnits.create({fileContainer, headerContainer}); auto translationUnit = translationUnits.translationUnit(fileContainer); + translationUnit.setIsVisibleInEditor(true); translationUnit.diagnostics(); // Reset translationUnit.highlightingInformations(); // Reset - EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(1); + EXPECT_CALL(mockSendDocumentAnnotationsCallback, sendDocumentAnnotations()).Times(0); sendAllDocumentAnnotations(); } From 66e7b77d88eb83ef32896da7e23908fc704a1b66 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 1 Dec 2015 14:05:49 +0100 Subject: [PATCH 34/47] Squish: Update selection of code model Change-Id: Iee76086dfd886dd8d61db3cfe4600a5eedd36cb7 Reviewed-by: Christian Stenger --- tests/system/objects.map | 1 + tests/system/shared/clang.py | 30 +++++-------------- tests/system/shared/utils.py | 2 +- tests/system/suite_CSUP/tst_CSUP02/test.py | 7 ++--- tests/system/suite_CSUP/tst_CSUP03/test.py | 9 ++---- tests/system/suite_CSUP/tst_CSUP04/test.py | 9 ++---- tests/system/suite_CSUP/tst_CSUP05/test.py | 9 ++---- tests/system/suite_CSUP/tst_CSUP06/test.py | 20 ++++++------- .../suite_editors/tst_memberoperator/test.py | 11 +++---- 9 files changed, 33 insertions(+), 65 deletions(-) diff --git a/tests/system/objects.map b/tests/system/objects.map index 6e2c0b0b68b..294d54ac578 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -212,6 +212,7 @@ :Working Copy_Utils::BaseValidatingLineEdit {type='Utils::FancyLineEdit' unnamed='1' visible='1' window=':New Text File_ProjectExplorer::JsonWizard'} :WritePermissions_Core::Internal::ReadOnlyFilesDialog {name='Core__Internal__ReadOnlyFilesDialog' type='Core::ReadOnlyFilesDialog' visible='1' windowTitle='Files Without Write Permissions'} :addToVersionControlComboBox_QComboBox {name='addToVersionControlComboBox' type='QComboBox' visible='1'} +:clangSettingsGroupBox_QGroupBox {container=':qt_tabwidget_stackedwidget_QScrollArea' name='clangSettingsGroupBox' type='QGroupBox' visible='1'} :formFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Form file:_QLabel' name='formFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'} :frame.templateDescription_QTextBrowser {container=':New.frame_QFrame' name='templateDescription' type='QTextBrowser' visible='1'} :headerFileLineEdit_Utils::FileNameValidatingLineEdit {buddy=':Qt Gui Application.Header file:_QLabel' name='headerFileLineEdit' type='Utils::FileNameValidatingLineEdit' visible='1'} diff --git a/tests/system/shared/clang.py b/tests/system/shared/clang.py index b54eea6c498..4ed6e961df7 100644 --- a/tests/system/shared/clang.py +++ b/tests/system/shared/clang.py @@ -51,30 +51,14 @@ def __openCodeModelOptions__(): clickItem(":Options_QListView", "C++", 14, 15, 0, Qt.LeftButton) clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Code Model") -def iterateAvailableCodeModels(): +def selectClangCodeModel(clangLoaded, enable): + codeModelName = "built-in" + if clangLoaded and enable: + codeModelName = "Clang" + test.log("Testing code model: %s" % codeModelName) __openCodeModelOptions__() - cppChooser = findObject("{type='QComboBox' name='cppChooser' visible='1'}") - models = [str(cppChooser.currentText)] # Make sure default is first in list - if cppChooser.count > 1: - furtherModels = dumpItems(cppChooser.model()) - furtherModels.remove(models[0]) - models.extend(furtherModels) - clickButton(waitForObject(":Options.OK_QPushButton")) - return models - -def selectCodeModel(codeModel): - __openCodeModelOptions__() - expectedObjNames = ['cChooser', 'cppChooser', 'objcChooser', 'objcppChooser', 'hChooser'] - for exp in expectedObjNames: - test.verify(checkIfObjectExists("{type='QComboBox' name='%s' visible='1'}" % exp), - "Verifying whether combobox '%s' exists." % exp) - combo = findObject("{type='QComboBox' name='%s' visible='1'}" % exp) - try: - selectFromCombo(combo, codeModel) - except: - test.fatal("Could not find code model '%s'. Canceling dialog." % codeModel) - clickButton(waitForObject(":Options.Cancel_QPushButton")) - return + if clangLoaded: + ensureChecked(":clangSettingsGroupBox_QGroupBox", enable) test.verify(verifyChecked("{name='ignorePCHCheckBox' type='QCheckBox' visible='1'}"), "Verifying whether 'Ignore pre-compiled headers' is checked by default.") clickButton(waitForObject(":Options.OK_QPushButton")) diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 47b8fb04805..3f293ebf0df 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -70,7 +70,7 @@ def ensureChecked(objectName, shouldBeChecked = True, timeout=20000): except: # widgets not derived from QCheckbox don't have checkState() if not waitFor('widget.checked == shouldBeChecked', 1000): - clickButton(widget) + mouseClick(widget, 10, 6, 0, Qt.LeftButton) test.verify(waitFor("widget.checked == shouldBeChecked", 1000)) test.log("New state for QCheckBox: %s" % state, str(objectName)) diff --git a/tests/system/suite_CSUP/tst_CSUP02/test.py b/tests/system/suite_CSUP/tst_CSUP02/test.py index ca93b9f7214..ca5fd66b752 100644 --- a/tests/system/suite_CSUP/tst_CSUP02/test.py +++ b/tests/system/suite_CSUP/tst_CSUP02/test.py @@ -38,11 +38,8 @@ def main(): # create qt quick application # Step 1: Open test .pro project. createNewQtQuickApplication(tempDir(), "SampleApp") - models = iterateAvailableCodeModels() - for current in models: - if current != models[0]: - selectCodeModel(current) - test.log("Testing code model: %s" % current) + for useClang in set([False, clangLoaded]): + selectClangCodeModel(clangLoaded, useClang) # Step 2: Open .cpp file in Edit mode. if not openDocument("SampleApp.Sources.main\\.cpp"): test.fatal("Could not open main.cpp") diff --git a/tests/system/suite_CSUP/tst_CSUP03/test.py b/tests/system/suite_CSUP/tst_CSUP03/test.py index 074065babb8..3644363427c 100644 --- a/tests/system/suite_CSUP/tst_CSUP03/test.py +++ b/tests/system/suite_CSUP/tst_CSUP03/test.py @@ -66,7 +66,7 @@ def constructExpectedCode(original, codeLines, funcSuffix): return "\n".join(tmp) + "\n" def main(): - startCreatorTryingClang() + clangLoaded = startCreatorTryingClang() if not startedWithoutPluginError(): return projectName = createNewNonQtProject() @@ -84,11 +84,8 @@ def main(): "while with braces" : ["", "int dummy = 0;", "while (dummy < 10) {", "++dummy;"], "do while" : ["", "int dummy = 0;", "do", "++dummy;", "while (dummy < 10);"] } - models = iterateAvailableCodeModels() - for current in models: - if current != models[0]: - selectCodeModel(current) - test.log("Testing code model: %s" % current) + for useClang in set([False, clangLoaded]): + selectClangCodeModel(clangLoaded, useClang) openDocument("%s.Sources.main\\.cpp" % projectName) editor = getEditorForFileSuffix("main.cpp") if not editor: diff --git a/tests/system/suite_CSUP/tst_CSUP04/test.py b/tests/system/suite_CSUP/tst_CSUP04/test.py index b38412e60a0..d576eccaf69 100644 --- a/tests/system/suite_CSUP/tst_CSUP04/test.py +++ b/tests/system/suite_CSUP/tst_CSUP04/test.py @@ -40,18 +40,15 @@ def main(): # copy example project to temp directory templateDir = prepareTemplate(sourceExample) examplePath = os.path.join(templateDir, proFile) - startCreatorTryingClang() + clangLoaded = startCreatorTryingClang() if not startedWithoutPluginError(): return # open example project openQmakeProject(examplePath) # wait for parsing to complete progressBarWait(30000) - models = iterateAvailableCodeModels() - for current in models: - if current != models[0]: - selectCodeModel(current) - test.log("Testing code model: %s" % current) + for useClang in set([False, clangLoaded]): + selectClangCodeModel(clangLoaded, useClang) # open .cpp file in editor if not openDocument("propertyanimation.Sources.main\\.cpp"): test.fatal("Could not open main.cpp") diff --git a/tests/system/suite_CSUP/tst_CSUP05/test.py b/tests/system/suite_CSUP/tst_CSUP05/test.py index c3e51fbafef..366dc234c54 100644 --- a/tests/system/suite_CSUP/tst_CSUP05/test.py +++ b/tests/system/suite_CSUP/tst_CSUP05/test.py @@ -40,18 +40,15 @@ def main(): # copy example project to temp directory templateDir = prepareTemplate(sourceExample) examplePath = os.path.join(templateDir, proFile) - startCreatorTryingClang() + clangLoaded = startCreatorTryingClang() if not startedWithoutPluginError(): return # open example project openQmakeProject(examplePath) # wait for parsing to complete progressBarWait(30000) - models = iterateAvailableCodeModels() - for current in models: - if current != models[0]: - selectCodeModel(current) - test.log("Testing code model: %s" % current) + for useClang in set([False, clangLoaded]): + selectClangCodeModel(clangLoaded, useClang) # open .cpp file in editor if not openDocument("propertyanimation.Sources.main\\.cpp"): test.fatal("Could not open main.cpp") diff --git a/tests/system/suite_CSUP/tst_CSUP06/test.py b/tests/system/suite_CSUP/tst_CSUP06/test.py index c71fca6f4a8..76d38ee223b 100644 --- a/tests/system/suite_CSUP/tst_CSUP06/test.py +++ b/tests/system/suite_CSUP/tst_CSUP06/test.py @@ -165,23 +165,21 @@ def main(): templateDir = prepareTemplate(examplePath) examplePath = os.path.join(templateDir, "cplusplus-tools.pro") openQmakeProject(examplePath, Targets.DESKTOP_531_DEFAULT) - models = iterateAvailableCodeModels() - test.compare(len(models), 1 + clangLoaded, "Verifying number of available code models") - test.compare("Qt Creator Built-in", models[0], - "Verifying whether default is Qt Creator's builtin code model") - test.compare("Clang" in models, clangLoaded, - "Verifying whether clang code model can be chosen.") - for current in models: - if current != models[0]: - selectCodeModel(current) - test.log("Testing code model: %s" % current) + __openCodeModelOptions__() + clangSettingsGroupBox = findObject(":clangSettingsGroupBox_QGroupBox") + test.compare(clangSettingsGroupBox.enabled, clangLoaded, "Verifying number of available code models") + test.verify(not clangSettingsGroupBox.checked, + "Verifying whether default is Qt Creator's builtin code model") + clickButton(waitForObject(":Options.Cancel_QPushButton")) + for useClang in set([False, clangLoaded]): + selectClangCodeModel(clangLoaded, useClang) if not openDocument("cplusplus-tools.Sources.main\\.cpp"): earlyExit("Failed to open main.cpp.") return editor = getEditorForFileSuffix("main.cpp") if editor: checkIncludeCompletion(editor) - checkSymbolCompletion(editor, current == "Clang") + checkSymbolCompletion(editor, useClang) invokeMenuItem('File', 'Revert "main.cpp" to Saved') clickButton(waitForObject(":Revert to Saved.Proceed_QPushButton")) snooze(1) # 'Close "main.cpp"' might still be disabled diff --git a/tests/system/suite_editors/tst_memberoperator/test.py b/tests/system/suite_editors/tst_memberoperator/test.py index 7b0bbc9b9e9..292a1371894 100644 --- a/tests/system/suite_editors/tst_memberoperator/test.py +++ b/tests/system/suite_editors/tst_memberoperator/test.py @@ -31,15 +31,12 @@ source("../../shared/qtcreator.py") def main(): - startCreatorTryingClang() + clangLoaded = startCreatorTryingClang() if not startedWithoutPluginError(): return createProject_Qt_Console(tempDir(), "SquishProject") - models = iterateAvailableCodeModels() - for current in models: - if current != models[0]: - selectCodeModel(current) - test.log("Testing code model: %s" % current) + for useClang in set([False, clangLoaded]): + selectClangCodeModel(clangLoaded, useClang) selectFromLocator("main.cpp") cppwindow = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget") @@ -56,7 +53,7 @@ def main(): waitFor("object.exists(':popupFrame_TextEditor::GenericProposalWidget')", 1500) found = str(lineUnderCursor(cppwindow)).strip() exp = testData.field(record, "expected") - if current == "Clang" and exp[-2:] == "->": + if useClang and exp[-2:] == "->": test.xcompare(found, exp) # QTCREATORBUG-11581 else: test.compare(found, exp) From 1defeda8a3ec6e8683f93b5ceb2c3d8d57bc447a Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 19 Nov 2015 17:09:43 +0100 Subject: [PATCH 35/47] Doc: link from Adding Connections to examples in another topic Change-Id: I1bff533c217b75681e37a533e12df0fc2a9695c6 Reviewed-by: Tim Jenssen --- doc/src/qtquick/qtquick-connection-editor.qdoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/src/qtquick/qtquick-connection-editor.qdoc b/doc/src/qtquick/qtquick-connection-editor.qdoc index a84022136e8..4cdda7e8dbc 100644 --- a/doc/src/qtquick/qtquick-connection-editor.qdoc +++ b/doc/src/qtquick/qtquick-connection-editor.qdoc @@ -47,6 +47,9 @@ \endlist + For examples of adding connections, see + \l{Creating Scalable Buttons and Borders}. + \section1 Connecting Objects to Signals To connect objects to signals in QML, create \l{Connections} objects. From 0d7f166b1923ff088ae7d4955347da9b03de07e8 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 18 Nov 2015 15:56:55 +0100 Subject: [PATCH 36/47] ToolChainManager: Filter duplicate toolchains more aggressively Change-Id: I2a333cc54d3c77a1fd43001a94c212e36b2e5f39 Reviewed-by: BogDan Vatra Reviewed-by: Alessandro Portale --- .../projectexplorer/toolchainmanager.cpp | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp index e581617f131..4b8fda4ebd1 100644 --- a/src/plugins/projectexplorer/toolchainmanager.cpp +++ b/src/plugins/projectexplorer/toolchainmanager.cpp @@ -203,11 +203,21 @@ static QList intersectByEqual(const QList &a, const QL }); } -static QList makeUnique(const QList &a) +static QList makeUniqueByPointerEqual(const QList &a) { return QSet::fromList(a).toList(); } +static QList makeUniqueByEqual(const QList &a) +{ + QList result; + foreach (ToolChain *tc, a) { + if (!Utils::contains(result, [tc](ToolChain *rtc) { return *tc == *rtc; })) + result.append(tc); + } + return result; +} + namespace { struct ToolChainOperations @@ -223,12 +233,13 @@ static ToolChainOperations mergeToolChainLists(const QList &systemF const QList &userFileTcs, const QList &autodetectedTcs) { + const QList uniqueUserFileTcs = makeUniqueByEqual(userFileTcs); const QList manualUserTcs - = Utils::filtered(userFileTcs, [](ToolChain *t) { return !t->isAutoDetected(); }); + = Utils::filtered(uniqueUserFileTcs, [](ToolChain *t) { return !t->isAutoDetected(); }); // Remove systemFileTcs from autodetectedUserTcs based on id-matches: const QList autodetectedUserFileTcs - = Utils::filtered(userFileTcs, &ToolChain::isAutoDetected); + = Utils::filtered(uniqueUserFileTcs, &ToolChain::isAutoDetected); const QList autodetectedUserTcs = subtractById(autodetectedUserFileTcs, systemFileTcs); // Calculate a set of Tcs that were detected before (and saved to userFile) and that @@ -255,8 +266,8 @@ static ToolChainOperations mergeToolChainLists(const QList &systemF result.toRegister = result.toDemote + systemFileTcs + redetectedUserTcs + newlyAutodetectedTcs + validManualUserTcs; - result.toDelete = makeUnique(subtractByPointerEqual(systemFileTcs + userFileTcs + autodetectedTcs, - result.toRegister)); + result.toDelete = makeUniqueByPointerEqual(subtractByPointerEqual(systemFileTcs + userFileTcs + autodetectedTcs, + result.toRegister)); return result; } @@ -542,6 +553,9 @@ void ProjectExplorerPlugin::testToolChainManager_data() QTest::newRow("Auto: auto-redetect, user") << (TCList()) << (TCList() << auto1) << (TCList() << auto1_2) << (TCList()) << (TCList() << auto1); + QTest::newRow("Auto: auto-redetect, duplicate users") + << (TCList()) << (TCList() << auto1 << auto1c) << (TCList() << auto1_2) + << (TCList()) << (TCList() << auto1); QTest::newRow("Auto: (no) auto, invalid user") << (TCList()) << (TCList() << auto3i) << (TCList()) << (TCList()) << (TCList()); From 48a2e15c28447cebe0a5609aefe3c18ef64bf526 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Tue, 1 Dec 2015 13:57:22 +0200 Subject: [PATCH 37/47] TextEditor: Fix indentation of last line in selection On normal selection it should *not* be indented. On block selection it should. Task-number: QTCREATORBUG-15300 Change-Id: I40ca1c24c6e14d05ca3c2d92a7562aac0eabb4c7 Reviewed-by: Eike Ziller --- src/plugins/texteditor/textdocument.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index cc28f20dc5a..213f15cfccc 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -130,7 +130,7 @@ QTextCursor TextDocumentPrivate::indentOrUnindent(const QTextCursor &textCursor, bool modified = true; QTextBlock startBlock = m_document.findBlock(start); - QTextBlock endBlock = m_document.findBlock(end).next(); + QTextBlock endBlock = m_document.findBlock(blockSelection ? end : end - 1).next(); const bool oneLinePartial = (startBlock.next() == endBlock) && (start > startBlock.position() || end < endBlock.position() - 1); From 493a2a6189cf387c234e8e1b8fdfd359dda5baa1 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 2 Dec 2015 13:31:07 +0100 Subject: [PATCH 38/47] Clang: Fix slowness of code completion after opening the file Task-number: QTCREATORBUG-15429 Change-Id: I9a8a582fb3c59a960425f83eb8e7b436f15d1c1a Reviewed-by: Nikolai Kosjar --- ...gistertranslationunitsforeditormessage.cpp | 42 ++++++++++++++++--- ...registertranslationunitsforeditormessage.h | 8 +++- .../clangbackendipcintegration.cpp | 4 +- .../clangeditordocumentprocessor.cpp | 4 -- .../test/clangcodecompletion_test.cpp | 4 ++ .../clangbackend/ipcsource/clangipcserver.cpp | 22 +++++++++- .../clangbackend/ipcsource/clangipcserver.h | 2 + .../ipcsource/translationunits.cpp | 29 +++++++------ .../clangbackend/ipcsource/translationunits.h | 4 +- tests/unit/unittest/clangipcservertest.cpp | 15 +++++-- .../unittest/clientserverinprocesstest.cpp | 7 +++- .../unittest/clientserveroutsideprocess.cpp | 7 +++- .../unittest/readandwritemessageblocktest.cpp | 5 ++- tests/unit/unittest/translationunitstest.cpp | 10 +++++ 14 files changed, 126 insertions(+), 37 deletions(-) diff --git a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.cpp b/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.cpp index 1c1d0dff526..bfb4fee293a 100644 --- a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.cpp +++ b/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.cpp @@ -39,8 +39,12 @@ namespace ClangBackEnd { -RegisterTranslationUnitForEditorMessage::RegisterTranslationUnitForEditorMessage(const QVector &fileContainers) - : fileContainers_(fileContainers) +RegisterTranslationUnitForEditorMessage::RegisterTranslationUnitForEditorMessage(const QVector &fileContainers, + const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorFilePaths) + : fileContainers_(fileContainers), + currentEditorFilePath_(currentEditorFilePath), + visibleEditorFilePaths_(visibleEditorFilePaths) { } @@ -49,28 +53,45 @@ const QVector &RegisterTranslationUnitForEditorMessage::fileConta return fileContainers_; } +const Utf8String &RegisterTranslationUnitForEditorMessage::currentEditorFilePath() const +{ + return currentEditorFilePath_; +} + +const Utf8StringVector &RegisterTranslationUnitForEditorMessage::visibleEditorFilePaths() const +{ + return visibleEditorFilePaths_; +} + QDataStream &operator<<(QDataStream &out, const RegisterTranslationUnitForEditorMessage &message) { out << message.fileContainers_; - + out << message.currentEditorFilePath_; + out << message.visibleEditorFilePaths_; return out; } QDataStream &operator>>(QDataStream &in, RegisterTranslationUnitForEditorMessage &message) { in >> message.fileContainers_; + in >> message.currentEditorFilePath_; + in >> message.visibleEditorFilePaths_; return in; } bool operator==(const RegisterTranslationUnitForEditorMessage &first, const RegisterTranslationUnitForEditorMessage &second) { - return first.fileContainers_ == second.fileContainers_; + return first.fileContainers_ == second.fileContainers_ + && first.currentEditorFilePath_ == second.currentEditorFilePath_ + && first.visibleEditorFilePaths_ == second.visibleEditorFilePaths_; } bool operator<(const RegisterTranslationUnitForEditorMessage &first, const RegisterTranslationUnitForEditorMessage &second) { - return compareContainer(first.fileContainers_, second.fileContainers_); + return compareContainer(first.fileContainers_, second.fileContainers_) + && first.currentEditorFilePath_ < second.currentEditorFilePath_ + && compareContainer(first.visibleEditorFilePaths_, second.visibleEditorFilePaths_); } QDebug operator<<(QDebug debug, const RegisterTranslationUnitForEditorMessage &message) @@ -80,6 +101,11 @@ QDebug operator<<(QDebug debug, const RegisterTranslationUnitForEditorMessage &m for (const FileContainer &fileContainer : message.fileContainers()) debug.nospace() << fileContainer<< ", "; + debug.nospace() << message.currentEditorFilePath() << ", "; + + for (const Utf8String &visibleEditorFilePath : message.visibleEditorFilePaths()) + debug.nospace() << visibleEditorFilePath << ", "; + debug.nospace() << ")"; return debug; @@ -92,6 +118,12 @@ void PrintTo(const RegisterTranslationUnitForEditorMessage &message, ::std::ostr for (const FileContainer &fileContainer : message.fileContainers()) PrintTo(fileContainer, os); + *os << message.currentEditorFilePath().constData() << ", "; + + auto visiblePaths = message.visibleEditorFilePaths(); + + std::copy(visiblePaths.cbegin(), visiblePaths.cend(), std::ostream_iterator(*os, ", ")); + *os << ")"; } diff --git a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.h b/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.h index c8411daca37..74920ecab4b 100644 --- a/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.h +++ b/src/libs/clangbackendipc/cmbregistertranslationunitsforeditormessage.h @@ -47,12 +47,18 @@ class CMBIPC_EXPORT RegisterTranslationUnitForEditorMessage friend void PrintTo(const RegisterTranslationUnitForEditorMessage &message, ::std::ostream* os); public: RegisterTranslationUnitForEditorMessage() = default; - RegisterTranslationUnitForEditorMessage(const QVector &fileContainers); + RegisterTranslationUnitForEditorMessage(const QVector &fileContainers, + const Utf8String ¤tEditorFilePath, + const Utf8StringVector &visibleEditorFilePaths); const QVector &fileContainers() const; + const Utf8String ¤tEditorFilePath() const; + const Utf8StringVector &visibleEditorFilePaths() const; private: QVector fileContainers_; + Utf8String currentEditorFilePath_; + Utf8StringVector visibleEditorFilePaths_; }; CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const RegisterTranslationUnitForEditorMessage &message); diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 887522263fb..3471f84b191 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -670,7 +670,9 @@ void IpcCommunicator::registerTranslationUnitsForEditor(const FileContainers &fi if (m_sendMode == IgnoreSendRequests) return; - const RegisterTranslationUnitForEditorMessage message(fileContainers); + const RegisterTranslationUnitForEditorMessage message(fileContainers, + currentCppEditorDocumentFilePath(), + visibleCppEditorDocumentsFilePaths()); qCDebug(log) << ">>>" << message; m_ipcSender->registerTranslationUnitsForEditor(message); } diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp index 1485c944030..6dc870b3de2 100644 --- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp @@ -268,13 +268,9 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr if (projectPart->id() != m_projectPart->id()) { ipcCommunicator.unregisterTranslationUnitsForEditor({fileContainerWithArguments()}); ipcCommunicator.registerTranslationUnitsForEditor({fileContainerWithArguments(projectPart)}); - ipcCommunicator.updateTranslationUnitVisiblity(); - requestDocumentAnnotations(projectPart->id()); } } else { ipcCommunicator.registerTranslationUnitsForEditor({{fileContainerWithArguments(projectPart)}}); - ipcCommunicator.updateTranslationUnitVisiblity(); - requestDocumentAnnotations(projectPart->id()); } } diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 41d12cce5ea..02acb42c5ec 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -1063,6 +1063,8 @@ void ClangCodeCompletionTest::testCompleteProjectDependingCodeInGeneratedUiFile( void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderInOtherEditor() { + QSKIP("We don't reparse anymore before a code completion so we get wrong completion results."); + CppTools::Tests::TemporaryDir temporaryDir; const TestDocument sourceDocument("mysource.cpp", &temporaryDir); QVERIFY(sourceDocument.isCreatedAndHasValidCursorPosition()); @@ -1090,6 +1092,8 @@ void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderInOtherEdi void ClangCodeCompletionTest::testCompleteAfterModifyingIncludedHeaderByRefactoringActions() { + QSKIP("We don't reparse anymore before a code completion so we get wrong completion results."); + CppTools::Tests::TemporaryDir temporaryDir; const TestDocument sourceDocument("mysource.cpp", &temporaryDir); QVERIFY(sourceDocument.isCreatedAndHasValidCursorPosition()); diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index 979eb3ff954..8db5e823d48 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -116,9 +116,12 @@ void ClangIpcServer::registerTranslationUnitsForEditor(const ClangBackEnd::Regis TIME_SCOPE_DURATION("ClangIpcServer::registerTranslationUnitsForEditor"); try { - translationUnits.create(message.fileContainers()); + auto createdTranslationUnits = translationUnits.create(message.fileContainers()); unsavedFiles.createOrUpdate(message.fileContainers()); - sendDocumentAnnotationsTimer.start(0); + translationUnits.setUsedByCurrentEditor(message.currentEditorFilePath()); + translationUnits.setVisibleInEditors(message.visibleEditorFilePaths()); + startDocumentAnnotations(); + reparseVisibleDocuments(createdTranslationUnits); } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); } catch (const std::exception &exception) { @@ -299,4 +302,19 @@ void ClangIpcServer::startDocumentAnnotationsTimerIfFileIsNotATranslationUnit(co sendDocumentAnnotationsTimer.start(0); } +void ClangIpcServer::startDocumentAnnotations() +{ + DocumentAnnotationsSendState sendState = DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations; + + while (sendState == DocumentAnnotationsSendState::MaybeThereAreDocumentAnnotations) + sendState = translationUnits.sendDocumentAnnotations(); +} + +void ClangIpcServer::reparseVisibleDocuments(std::vector &translationUnits) +{ + for (TranslationUnit &translationUnit : translationUnits) + if (translationUnit.isVisibleInEditor()) + translationUnit.reparse(); +} + } diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.h b/src/tools/clangbackend/ipcsource/clangipcserver.h index f5f768552d9..8fcbddc7a47 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.h +++ b/src/tools/clangbackend/ipcsource/clangipcserver.h @@ -68,6 +68,8 @@ public: private: void startDocumentAnnotationsTimerIfFileIsNotATranslationUnit(const Utf8String &filePath); + void startDocumentAnnotations(); + void reparseVisibleDocuments(std::vector &translationUnits); private: ProjectParts projects; diff --git a/src/tools/clangbackend/ipcsource/translationunits.cpp b/src/tools/clangbackend/ipcsource/translationunits.cpp index c66be73d9bb..885eabaefae 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.cpp +++ b/src/tools/clangbackend/ipcsource/translationunits.cpp @@ -63,12 +63,16 @@ TranslationUnits::TranslationUnits(ProjectParts &projects, UnsavedFiles &unsaved { } -void TranslationUnits::create(const QVector &fileContainers) +std::vector TranslationUnits::create(const QVector &fileContainers) { checkIfTranslationUnitsDoesNotExists(fileContainers); + std::vector createdTranslationUnits; + for (const FileContainer &fileContainer : fileContainers) - createTranslationUnit(fileContainer); + createdTranslationUnits.push_back(createTranslationUnit(fileContainer)); + + return createdTranslationUnits; } void TranslationUnits::update(const QVector &fileContainers) @@ -258,18 +262,19 @@ const ClangFileSystemWatcher *TranslationUnits::clangFileSystemWatcher() const return &fileSystemWatcher; } -void TranslationUnits::createTranslationUnit(const FileContainer &fileContainer) +TranslationUnit TranslationUnits::createTranslationUnit(const FileContainer &fileContainer) { TranslationUnit::FileExistsCheck checkIfFileExists = fileContainer.hasUnsavedFileContent() ? TranslationUnit::DoNotCheckIfFileExists : TranslationUnit::CheckIfFileExists; - auto findIterator = findTranslationUnit(fileContainer); - if (findIterator == translationUnits_.end()) { - translationUnits_.push_back(TranslationUnit(fileContainer.filePath(), - projectParts.project(fileContainer.projectPartId()), - fileContainer.fileArguments(), - *this, - checkIfFileExists)); - translationUnits_.back().setDocumentRevision(fileContainer.documentRevision()); - } + + translationUnits_.emplace_back(fileContainer.filePath(), + projectParts.project(fileContainer.projectPartId()), + fileContainer.fileArguments(), + *this, + checkIfFileExists); + + translationUnits_.back().setDocumentRevision(fileContainer.documentRevision()); + + return translationUnits_.back(); } void TranslationUnits::updateTranslationUnit(const FileContainer &fileContainer) diff --git a/src/tools/clangbackend/ipcsource/translationunits.h b/src/tools/clangbackend/ipcsource/translationunits.h index 90df960a29b..49ed36e7e29 100644 --- a/src/tools/clangbackend/ipcsource/translationunits.h +++ b/src/tools/clangbackend/ipcsource/translationunits.h @@ -64,7 +64,7 @@ public: public: TranslationUnits(ProjectParts &projectParts, UnsavedFiles &unsavedFiles); - void create(const QVector &fileContainers); + std::vector create(const QVector &fileContainers); void update(const QVector &fileContainers); void remove(const QVector &fileContainers); @@ -96,7 +96,7 @@ public: const ClangFileSystemWatcher *clangFileSystemWatcher() const; private: - void createTranslationUnit(const FileContainer &fileContainer); + TranslationUnit createTranslationUnit(const FileContainer &fileContainer); void updateTranslationUnit(const FileContainer &fileContainer); std::vector::iterator findTranslationUnit(const FileContainer &fileContainer); std::vector::iterator findAllTranslationUnitWithFilePath(const Utf8String &filePath); diff --git a/tests/unit/unittest/clangipcservertest.cpp b/tests/unit/unittest/clangipcservertest.cpp index a95e42d53df..f12e8b5aae9 100644 --- a/tests/unit/unittest/clangipcservertest.cpp +++ b/tests/unit/unittest/clangipcservertest.cpp @@ -332,7 +332,9 @@ TEST_F(ClangIpcServer, GetProjectPartDoesNotExistUnregisterProjectPartInexisting TEST_F(ClangIpcServer, GetProjectPartDoesNotExistRegisterTranslationUnitWithInexistingProjectPart) { Utf8String inexistingProjectPartFilePath = Utf8StringLiteral("projectpartsdoesnotexist.pro"); - RegisterTranslationUnitForEditorMessage registerFileForEditorMessage({FileContainer(variableTestFilePath, inexistingProjectPartFilePath)}); + RegisterTranslationUnitForEditorMessage registerFileForEditorMessage({FileContainer(variableTestFilePath, inexistingProjectPartFilePath)}, + variableTestFilePath, + {variableTestFilePath}); ProjectPartsDoNotExistMessage projectPartsDoNotExistMessage({inexistingProjectPartFilePath}); EXPECT_CALL(mockIpcClient, projectPartsDoNotExist(projectPartsDoNotExistMessage)) @@ -398,9 +400,9 @@ TEST_F(ClangIpcServer, TicketNumberIsForwarded) clangServer.completeCode(completeCodeMessage); } -TEST_F(ClangIpcServer, TranslationUnitAfterCreationNeedsNoReparseAndHasNewDiagnostics) +TEST_F(ClangIpcServer, TranslationUnitAfterCreationNeedsNoReparseAndHasNoNewDiagnostics) { - ASSERT_THAT(clangServer, HasDirtyTranslationUnit(functionTestFilePath, projectPartId, 0U, false, true)); + ASSERT_THAT(clangServer, HasDirtyTranslationUnit(functionTestFilePath, projectPartId, 0U, false, false)); } TEST_F(ClangIpcServer, SetCurrentAndVisibleEditor) @@ -439,7 +441,12 @@ void ClangIpcServer::SetUp() void ClangIpcServer::registerFiles() { RegisterTranslationUnitForEditorMessage message({FileContainer(functionTestFilePath, projectPartId, unsavedContent(unsavedTestFilePath), true), - FileContainer(variableTestFilePath, projectPartId)}); + FileContainer(variableTestFilePath, projectPartId)}, + functionTestFilePath, + {functionTestFilePath, variableTestFilePath}); + + EXPECT_CALL(mockIpcClient, diagnosticsChanged(_)).Times(2); + EXPECT_CALL(mockIpcClient, highlightingChanged(_)).Times(2); clangServer.registerTranslationUnitsForEditor(message); } diff --git a/tests/unit/unittest/clientserverinprocesstest.cpp b/tests/unit/unittest/clientserverinprocesstest.cpp index b483fe10994..c8f74551d43 100644 --- a/tests/unit/unittest/clientserverinprocesstest.cpp +++ b/tests/unit/unittest/clientserverinprocesstest.cpp @@ -90,7 +90,8 @@ protected: void scheduleClientMessages(); protected: - ClangBackEnd::FileContainer fileContainer{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"), + Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp")}; + ClangBackEnd::FileContainer fileContainer{filePath, Utf8StringLiteral("projectPartId"), Utf8StringLiteral("unsaved content"), true, @@ -123,7 +124,9 @@ TEST_F(ClientServerInProcess, SendAliveMessage) TEST_F(ClientServerInProcess, SendRegisterTranslationUnitForEditorMessage) { - ClangBackEnd::RegisterTranslationUnitForEditorMessage message({fileContainer}); + ClangBackEnd::RegisterTranslationUnitForEditorMessage message({fileContainer}, + filePath, + {filePath}); EXPECT_CALL(mockIpcServer, registerTranslationUnitsForEditor(message)) .Times(1); diff --git a/tests/unit/unittest/clientserveroutsideprocess.cpp b/tests/unit/unittest/clientserveroutsideprocess.cpp index 0e04376585b..5173004c80f 100644 --- a/tests/unit/unittest/clientserveroutsideprocess.cpp +++ b/tests/unit/unittest/clientserveroutsideprocess.cpp @@ -115,8 +115,11 @@ TEST_F(ClientServerOutsideProcess, RestartProcessAfterTermination) TEST_F(ClientServerOutsideProcess, SendRegisterTranslationUnitForEditorMessage) { - ClangBackEnd::FileContainer fileContainer(Utf8StringLiteral("foo.cpp"), Utf8StringLiteral("projectId")); - ClangBackEnd::RegisterTranslationUnitForEditorMessage registerTranslationUnitForEditorMessage({fileContainer}); + auto filePath = Utf8StringLiteral("foo.cpp"); + ClangBackEnd::FileContainer fileContainer(filePath, Utf8StringLiteral("projectId")); + ClangBackEnd::RegisterTranslationUnitForEditorMessage registerTranslationUnitForEditorMessage({fileContainer}, + filePath, + {filePath}); EchoMessage echoMessage(QVariant::fromValue(registerTranslationUnitForEditorMessage)); EXPECT_CALL(mockIpcClient, echo(echoMessage)) diff --git a/tests/unit/unittest/readandwritemessageblocktest.cpp b/tests/unit/unittest/readandwritemessageblocktest.cpp index f319d1cabb6..ef958253dd2 100644 --- a/tests/unit/unittest/readandwritemessageblocktest.cpp +++ b/tests/unit/unittest/readandwritemessageblocktest.cpp @@ -79,7 +79,8 @@ protected: void readPartialMessage(); protected: - ClangBackEnd::FileContainer fileContainer{Utf8StringLiteral("foo.cpp"), + Utf8String filePath{Utf8StringLiteral("foo.cpp")}; + ClangBackEnd::FileContainer fileContainer{filePath, Utf8StringLiteral("projectPartId"), Utf8StringLiteral("unsaved content"), true, @@ -152,7 +153,7 @@ TEST_F(ReadAndWriteMessageBlock, CompareAliveMessage) TEST_F(ReadAndWriteMessageBlock, CompareRegisterTranslationUnitForEditorMessage) { - CompareMessage(ClangBackEnd::RegisterTranslationUnitForEditorMessage({fileContainer})); + CompareMessage(ClangBackEnd::RegisterTranslationUnitForEditorMessage({fileContainer}, filePath, {filePath})); } TEST_F(ReadAndWriteMessageBlock, CompareUpdateTranslationUnitForEditorMessage) diff --git a/tests/unit/unittest/translationunitstest.cpp b/tests/unit/unittest/translationunitstest.cpp index 99c6d23c850..32414739674 100644 --- a/tests/unit/unittest/translationunitstest.cpp +++ b/tests/unit/unittest/translationunitstest.cpp @@ -144,6 +144,16 @@ TEST_F(TranslationUnits, Add) IsTranslationUnit(filePath, projectPartId, 74u)); } +TEST_F(TranslationUnits, AddAndTestCreatedTranslationUnit) +{ + ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u); + + auto createdTranslationUnits = translationUnits.create({fileContainer}); + + ASSERT_THAT(createdTranslationUnits.front(), + IsTranslationUnit(filePath, projectPartId, 74u)); +} + TEST_F(TranslationUnits, ThrowForCreatingAnExistingTranslationUnit) { ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u); From 133b50ed13ca553db37d052ceefa73a3c277947a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 1 Dec 2015 15:05:31 +0100 Subject: [PATCH 39/47] Clang: Don't update the translation unit for changing the current editor It is generating reparsing steps. Change-Id: Ibbdb2f5dceffdf940bbdf0c9a9f0a706124078f9 Reviewed-by: Nikolai Kosjar --- .../clangcodemodel/clangmodelmanagersupport.cpp | 15 +-------------- .../clangcodemodel/clangmodelmanagersupport.h | 1 - 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 8dd11df681a..3b5384b20b2 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -102,21 +102,8 @@ CppTools::BaseEditorDocumentProcessor *ModelManagerSupportClang::editorDocumentP return new ClangEditorDocumentProcessor(this, baseTextDocument); } -void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *newCurrent) +void ModelManagerSupportClang::onCurrentEditorChanged(Core::IEditor *) { - // If we switch away from a cpp editor, update the backend about - // the document's unsaved content. - if (m_previousCppEditor && m_previousCppEditor->document()->isModified()) { - m_ipcCommunicator.updateTranslationUnitFromCppEditorDocument( - m_previousCppEditor->document()->filePath().toString()); - } - - // Remember previous editor - if (newCurrent && cppModelManager()->isCppEditor(newCurrent)) - m_previousCppEditor = newCurrent; - else - m_previousCppEditor.clear(); - m_ipcCommunicator.updateTranslationUnitVisiblity(); } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index bbc44f4a6dc..597dfff3884 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -104,7 +104,6 @@ private: private: IpcCommunicator m_ipcCommunicator; ClangCompletionAssistProvider m_completionAssistProvider; - QPointer m_previousCppEditor; }; class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider From ea278cdf342324f23aa2f49ce4e00397c090b106 Mon Sep 17 00:00:00 2001 From: Finn Brudal Date: Fri, 23 Oct 2015 11:47:25 +0200 Subject: [PATCH 40/47] TextEditor: Fixes crash when double clicking virtual function proposal Ensures that the DeferredDelete event is posted from the outermost loop level. Change-Id: Ib74d49d35811f35659ef272d6f0e0a4508f93076 Reviewed-by: David Schulz --- src/plugins/texteditor/codeassist/genericproposalwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp index 0c974729ccc..063bedb9565 100644 --- a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp +++ b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp @@ -440,9 +440,9 @@ void GenericProposalWidget::notifyActivation(int index) void GenericProposalWidget::abort() { + deleteLater(); if (isVisible()) close(); - deleteLater(); } bool GenericProposalWidget::updateAndCheck(const QString &prefix) From ff913b83aebb131ba0ffc9dc79968b8f147286e1 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 1 Dec 2015 14:02:39 +0100 Subject: [PATCH 41/47] Clang: Use revision from file container Change-Id: Ie084677fb910fc6e415afcdf7533369150162f8f Reviewed-by: Nikolai Kosjar --- src/plugins/clangcodemodel/clangbackendipcintegration.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 3471f84b191..635edb1ed45 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -512,12 +512,13 @@ CppTools::CppEditorDocumentHandle *cppDocument(const QString &filePath) return CppTools::CppModelManager::instance()->cppEditorDocument(filePath); } -bool documentHasChanged(const QString &filePath) +bool documentHasChanged(const QString &filePath, + uint revision) { auto *document = cppDocument(filePath); if (document) - return document->sendTracker().shouldSendRevision(document->revision()); + return document->sendTracker().shouldSendRevision(revision); return true; } @@ -562,7 +563,7 @@ void IpcCommunicator::updateTranslationUnitWithRevisionCheck(const FileContainer if (m_sendMode == IgnoreSendRequests) return; - if (documentHasChanged(fileContainer.filePath())) { + if (documentHasChanged(fileContainer.filePath(), fileContainer.documentRevision())) { updateTranslationUnitsForEditor({fileContainer}); setLastSentDocumentRevision(fileContainer.filePath(), fileContainer.documentRevision()); From f482ad6069f71cf24837a505f8ef4ccbf8ee20e8 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 2 Dec 2015 12:25:20 +0100 Subject: [PATCH 42/47] Clang: Use fontsettings in diagnostics Change-Id: I8438293a37a53532927520106d4ee5346237ebfe Reviewed-by: Nikolai Kosjar --- .../clangcodemodel/clangdiagnosticmanager.cpp | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp index 13544424bd8..1e94d55aef2 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp @@ -31,7 +31,9 @@ #include "clangdiagnosticfilter.h" #include "clangdiagnosticmanager.h" +#include #include +#include #include #include @@ -53,7 +55,7 @@ QTextEdit::ExtraSelection createExtraSelections(const QTextCharFormat &mainforma void addRangeSelections(const ClangBackEnd::DiagnosticContainer &diagnostic, QTextDocument *textDocument, - const QTextCharFormat &rangeFormat, + const QTextCharFormat &contextFormat, const QString &diagnosticText, QList &extraSelections) { @@ -62,7 +64,7 @@ void addRangeSelections(const ClangBackEnd::DiagnosticContainer &diagnostic, cursor.setPosition(int(range.start().offset())); cursor.setPosition(int(range.end().offset()), QTextCursor::KeepAnchor); - auto extraSelection = createExtraSelections(rangeFormat, cursor, diagnosticText); + auto extraSelection = createExtraSelections(contextFormat, cursor, diagnosticText); extraSelections.push_back(std::move(extraSelection)); } @@ -116,7 +118,7 @@ QString diagnosticText(const ClangBackEnd::DiagnosticContainer &diagnostic) void addSelections(const QVector &diagnostics, QTextDocument *textDocument, const QTextCharFormat &mainFormat, - const QTextCharFormat &rangeFormat, + const QTextCharFormat &contextFormat, QList &extraSelections) { for (auto &&diagnostic : diagnostics) { @@ -125,7 +127,7 @@ void addSelections(const QVector &diagnostics auto text = diagnosticText(diagnostic); auto extraSelection = createExtraSelections(mainFormat, cursor, text); - addRangeSelections(diagnostic, textDocument, rangeFormat, text, extraSelections); + addRangeSelections(diagnostic, textDocument, contextFormat, text, extraSelections); extraSelections.push_back(std::move(extraSelection)); } @@ -135,30 +137,25 @@ void addWarningSelections(const QVector &diag QTextDocument *textDocument, QList &extraSelections) { - QTextCharFormat warningFormat; - warningFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); - warningFormat.setUnderlineColor(QColor(180, 180, 0, 255)); + const auto fontSettings = TextEditor::TextEditorSettings::instance()->fontSettings(); - QTextCharFormat warningRangeFormat; - warningRangeFormat.setUnderlineStyle(QTextCharFormat::DotLine); - warningRangeFormat.setUnderlineColor(QColor(180, 180, 0, 255)); + QTextCharFormat warningFormat = fontSettings.toTextCharFormat(TextEditor::C_WARNING); - addSelections(diagnostics, textDocument, warningFormat, warningRangeFormat, extraSelections); + QTextCharFormat warningContextFormat = fontSettings.toTextCharFormat(TextEditor::C_WARNING_CONTEXT); + + addSelections(diagnostics, textDocument, warningFormat, warningContextFormat, extraSelections); } void addErrorSelections(const QVector &diagnostics, QTextDocument *textDocument, QList &extraSelections) { - QTextCharFormat errorFormat; - errorFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); - errorFormat.setUnderlineColor(QColor(255, 0, 0, 255)); + const auto fontSettings = TextEditor::TextEditorSettings::instance()->fontSettings(); - QTextCharFormat errorRangeFormat; - errorRangeFormat.setUnderlineStyle(QTextCharFormat::DotLine); - errorRangeFormat.setUnderlineColor(QColor(255, 0, 0, 255)); + QTextCharFormat errorFormat = fontSettings.toTextCharFormat(TextEditor::C_ERROR); + QTextCharFormat errorContextFormat = fontSettings.toTextCharFormat(TextEditor::C_ERROR_CONTEXT); - addSelections(diagnostics, textDocument, errorFormat, errorRangeFormat, extraSelections); + addSelections(diagnostics, textDocument, errorFormat, errorContextFormat, extraSelections); } } // anonymous From 03056a6d6419eee8ab7eee1a8ebaf29f752b31ee Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 2 Dec 2015 14:29:38 +0100 Subject: [PATCH 43/47] Clang: Make document annotations timer configurable ...by environment variable. Change-Id: If20589e84dea2366fd9b6b273259ce29eddb965b Reviewed-by: Marco Bubke --- .../clangbackend/ipcsource/clangipcserver.cpp | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index 8db5e823d48..c8bd3634e72 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -66,7 +66,29 @@ namespace ClangBackEnd { namespace { -const int delayedDocumentAnnotationsTimerInterval = 3000; + +int getIntervalFromEnviromentVariable() +{ + const QByteArray userIntervalAsByteArray = qgetenv("QTC_CLANG_DELAYED_REPARSE_TIMEOUT"); + + bool isConversionOk = false; + const int intervalAsInt = userIntervalAsByteArray.toInt(&isConversionOk); + + if (isConversionOk) + return intervalAsInt; + else + return -1; +} + +int delayedDocumentAnnotationsTimerInterval() +{ + static const int defaultInterval = 3000; + static const int userDefinedInterval = getIntervalFromEnviromentVariable(); + static const int interval = userDefinedInterval >= 0 ? userDefinedInterval : defaultInterval; + + return interval; +} + } ClangIpcServer::ClangIpcServer() @@ -138,7 +160,7 @@ void ClangIpcServer::updateTranslationUnitsForEditor(const UpdateTranslationUnit if (newerFileContainers.size() > 0) { translationUnits.update(newerFileContainers); unsavedFiles.createOrUpdate(newerFileContainers); - sendDocumentAnnotationsTimer.start(delayedDocumentAnnotationsTimerInterval); + sendDocumentAnnotationsTimer.start(delayedDocumentAnnotationsTimerInterval()); } } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); @@ -196,7 +218,7 @@ void ClangIpcServer::registerUnsavedFilesForEditor(const RegisterUnsavedFilesFor try { unsavedFiles.createOrUpdate(message.fileContainers()); translationUnits.updateTranslationUnitsWithChangedDependencies(message.fileContainers()); - sendDocumentAnnotationsTimer.start(delayedDocumentAnnotationsTimerInterval); + sendDocumentAnnotationsTimer.start(delayedDocumentAnnotationsTimerInterval()); } catch (const ProjectPartDoNotExistException &exception) { client()->projectPartsDoNotExist(ProjectPartsDoNotExistMessage(exception.projectPartIds())); } catch (const std::exception &exception) { From a08336fcc2962976a4edd423ab48629b3f38882e Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 1 Dec 2015 13:21:02 +0100 Subject: [PATCH 44/47] Clang: Don't send multiple completions for the same position If we send already a completion we should test if there is already one sent for the same position. Change-Id: Ie88f89bff0e1da1c5e747827a45154c7ccaecabc Reviewed-by: Nikolai Kosjar Reviewed-by: Marco Bubke --- .../clangbackendipcintegration.cpp | 10 ++++ .../clangbackendipcintegration.h | 4 ++ .../clangcompletionassistprocessor.cpp | 59 ++++++++++++++----- .../clangcompletionassistprocessor.h | 2 +- .../texteditor/codeassist/codeassistant.cpp | 12 +--- 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 635edb1ed45..63cd16daf90 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -137,6 +137,11 @@ void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *t } } +bool IpcReceiver::isExpectingCodeCompletedMessage() const +{ + return !m_assistProcessorsTable.isEmpty(); +} + void IpcReceiver::alive() { qCDebug(log) << "<<< AliveMessage"; @@ -446,6 +451,11 @@ void IpcCommunicator::updateTranslationUnitVisiblity() updateTranslationUnitVisiblity(currentCppEditorDocumentFilePath(), visibleCppEditorDocumentsFilePaths()); } +bool IpcCommunicator::isNotWaitingForCompletion() const +{ + return !m_ipcReceiver.isExpectingCodeCompletedMessage(); +} + void IpcCommunicator::updateTranslationUnitVisiblity(const Utf8String ¤tEditorFilePath, const Utf8StringVector &visibleEditorsFilePaths) { diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h index 160de329ef9..2f045f2abe2 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h @@ -76,6 +76,8 @@ public: void deleteAndClearWaitingAssistProcessors(); void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget); + bool isExpectingCodeCompletedMessage() const; + private: void alive() override; void echo(const ClangBackEnd::EchoMessage &message) override; @@ -152,6 +154,8 @@ public: void registerFallbackProjectPart(); void updateTranslationUnitVisiblity(); + bool isNotWaitingForCompletion() const; + public: // for tests IpcSenderInterface *setIpcSender(IpcSenderInterface *ipcSender); void killBackendProcess(); diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index 2f6b17ba82e..fe437f52fca 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -342,13 +342,16 @@ IAssistProposal *ClangCompletionAssistProcessor::startCompletionHelper() case ClangCompletionContextAnalyzer::PassThroughToLibClang: { m_addSnippets = m_completionOperator == T_EOF_SYMBOL; m_sentRequestType = NormalCompletion; - sendCompletionRequest(analyzer.positionForClang(), modifiedFileContent); + const bool requestSent = sendCompletionRequest(analyzer.positionForClang(), + modifiedFileContent); + setPerformWasApplicable(requestSent); break; } case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: { m_sentRequestType = FunctionHintCompletion; m_functionName = analyzer.functionName(); - sendCompletionRequest(analyzer.positionForClang(), QByteArray()); + const bool requestSent = sendCompletionRequest(analyzer.positionForClang(), QByteArray()); + setPerformWasApplicable(requestSent); break; } default: @@ -702,15 +705,34 @@ bool shouldSendDocumentForCompletion(const QString &filePath, return true; } -void setLastCompletionPositionAndDocumentRevision(const QString &filePath, - int completionPosition) +bool shouldSendCodeCompletion(const QString &filePath, + int completionPosition) { auto *document = cppDocument(filePath); if (document) { - document->sendTracker().setLastCompletionPosition(completionPosition); - document->sendTracker().setLastSentRevision(document->revision()); + auto &sendTracker = document->sendTracker(); + return sendTracker.shouldSendCompletion(completionPosition); } + + return true; +} + +void setLastDocumentRevision(const QString &filePath) +{ + auto *document = cppDocument(filePath); + + if (document) + document->sendTracker().setLastSentRevision(int(document->revision())); +} + +void setLastCompletionPosition(const QString &filePath, + int completionPosition) +{ + auto *document = cppDocument(filePath); + + if (document) + document->sendTracker().setLastCompletionPosition(completionPosition); } QString projectPartIdForEditorDocument(const QString &filePath) @@ -726,7 +748,7 @@ QString projectPartIdForEditorDocument(const QString &filePath) } } -void ClangCompletionAssistProcessor::sendCompletionRequest(int position, +bool ClangCompletionAssistProcessor::sendCompletionRequest(int position, const QByteArray &customFileContent) { int line, column; @@ -735,17 +757,22 @@ void ClangCompletionAssistProcessor::sendCompletionRequest(int position, const QString filePath = m_interface->fileName(); - if (shouldSendDocumentForCompletion(filePath, position)) { - sendFileContent(customFileContent); - setLastCompletionPositionAndDocumentRevision(filePath, position); + auto &ipcCommunicator = m_interface->ipcCommunicator(); + + if (shouldSendCodeCompletion(filePath, position) + || ipcCommunicator.isNotWaitingForCompletion()) { + if (shouldSendDocumentForCompletion(filePath, position)) { + sendFileContent(customFileContent); + setLastDocumentRevision(filePath); + } + + const QString projectPartId = projectPartIdForEditorDocument(filePath); + ipcCommunicator.completeCode(this, filePath, uint(line), uint(column), projectPartId); + setLastCompletionPosition(filePath, position); + return true; } - const QString projectPartId = projectPartIdForEditorDocument(filePath); - m_interface->ipcCommunicator().completeCode(this, - filePath, - uint(line), - uint(column), - projectPartId); + return false; } TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal() const diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h index 4cecf8a31ed..6a8abddcb71 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h @@ -84,7 +84,7 @@ private: UnsavedFileContentInfo unsavedFileContent(const QByteArray &customFileContent) const; void sendFileContent(const QByteArray &customFileContent); - void sendCompletionRequest(int position, const QByteArray &customFileContent); + bool sendCompletionRequest(int position, const QByteArray &customFileContent); void handleAvailableCompletions(const CodeCompletions &completions); bool handleAvailableFunctionHintCompletions(const CodeCompletions &completions); diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp index cc247d1323b..59fe46e5e3b 100644 --- a/src/plugins/texteditor/codeassist/codeassistant.cpp +++ b/src/plugins/texteditor/codeassist/codeassistant.cpp @@ -263,14 +263,8 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason, case IAssistProvider::Asynchronous: { processor->setAsyncCompletionAvailableHandler( [this, processor, reason](IAssistProposal *newProposal){ - if (m_asyncProcessor != processor) { - delete newProposal->model(); - delete newProposal; - return; - } - - invalidateCurrentRequestData(); QTC_CHECK(newProposal); + invalidateCurrentRequestData(); displayProposal(newProposal, reason); emit q->finished(); @@ -282,10 +276,10 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason, delete processor; } else if (!processor->performWasApplicable()) { delete processor; + } else { // ...async request was triggered + m_asyncProcessor = processor; } - // ...otherwise the async request was triggered - m_asyncProcessor = processor; break; } } // switch From 79d1d5b9e0c4f63ffdbbeae721d3a0cbd58ff521 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 2 Dec 2015 13:15:26 +0100 Subject: [PATCH 45/47] CppEditor: Reset process document timer back to 150ms ...since the clangbackend has its own timer now. Change-Id: Icef3ea820da751617a3fe4b6f090ac244d0ddef8 Reviewed-by: Marco Bubke --- src/plugins/cppeditor/cppeditordocument.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index 3c52ad0ef34..e74aa05c46b 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -63,8 +63,7 @@ CppTools::CppModelManager *mm() namespace CppEditor { namespace Internal { -enum { processDocumentIntervalInMs = 150, - clangProcessDocumentIntervalInMs = 500 }; +enum { processDocumentIntervalInMs = 150 }; class CppEditorDocumentHandleImpl : public CppTools::CppEditorDocumentHandle { @@ -292,10 +291,7 @@ void CppEditorDocument::releaseResources() void CppEditorDocument::initializeTimer() { m_processorTimer.setSingleShot(true); - if (mm()->isClangCodeModelActive()) - m_processorTimer.setInterval(clangProcessDocumentIntervalInMs); - else - m_processorTimer.setInterval(processDocumentIntervalInMs); + m_processorTimer.setInterval(processDocumentIntervalInMs); connect(&m_processorTimer, &QTimer::timeout, From 475b11aad150c68d9bb54c066f22313bf1d2ac17 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 2 Dec 2015 16:00:11 +0100 Subject: [PATCH 46/47] Clang: Fix recovering on clangbackend crash The translation unit was updated, but not re-registered. Handle the editor documents this way: 1. Reset all ClangEditorDocumentProcessors (this will send an unregister message, but that's not problematic). 2. For the visible editor documents, run their processors so that the translation units will be re-registered. 3. For the invisible editor documents, mark them dirty. Once the user makes an invisible document visible again, the processor will run and also re-register the translation unit. Change-Id: I23693ac197bd34a183f3a0020eb5372268636599 Reviewed-by: Marco Bubke --- .../clangbackendipcintegration.cpp | 21 +++++++++++++------ .../clangbackendipcintegration.h | 4 +++- src/plugins/cpptools/cppmodelmanager.h | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp index 63cd16daf90..0e664aee807 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp @@ -476,15 +476,24 @@ void IpcCommunicator::registerCurrentProjectParts() registerProjectsParts(projectInfo.projectParts()); } -void IpcCommunicator::registerCurrentCppEditorDocuments() +void IpcCommunicator::restoreCppEditorDocuments() +{ + resetCppEditorDocumentProcessors(); + registerVisibleCppEditorDocumentAndMarkInvisibleDirty(); +} + +void IpcCommunicator::resetCppEditorDocumentProcessors() { using namespace CppTools; const auto cppEditorDocuments = CppModelManager::instance()->cppEditorDocuments(); - foreach (const CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments) { - if (cppEditorDocument->processor()->baseTextDocument()->isModified()) - updateTranslationUnitFromCppEditorDocument(cppEditorDocument->filePath()); - } + foreach (CppEditorDocumentHandle *cppEditorDocument, cppEditorDocuments) + cppEditorDocument->resetProcessor(); +} + +void IpcCommunicator::registerVisibleCppEditorDocumentAndMarkInvisibleDirty() +{ + CppTools::CppModelManager::instance()->updateCppEditorDocuments(); } void IpcCommunicator::registerCurrentCodeModelUiHeaders() @@ -657,8 +666,8 @@ void IpcCommunicator::initializeBackendWithCurrentData() { registerFallbackProjectPart(); registerCurrentProjectParts(); - registerCurrentCppEditorDocuments(); registerCurrentCodeModelUiHeaders(); + restoreCppEditorDocuments(); updateTranslationUnitVisiblity(); emit backendReinitialized(); diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h index 2f045f2abe2..3d6a299c517 100644 --- a/src/plugins/clangcodemodel/clangbackendipcintegration.h +++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h @@ -169,7 +169,9 @@ private: void initializeBackend(); void initializeBackendWithCurrentData(); void registerCurrentProjectParts(); - void registerCurrentCppEditorDocuments(); + void restoreCppEditorDocuments(); + void resetCppEditorDocumentProcessors(); + void registerVisibleCppEditorDocumentAndMarkInvisibleDirty(); void registerCurrentCodeModelUiHeaders(); diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 1c4b91ebf0f..4c10343edac 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -91,6 +91,7 @@ public: QFuture updateSourceFiles(const QSet &sourceFiles, ProgressNotificationMode mode = ReservedProgressNotification); + void updateCppEditorDocuments() const; WorkingCopy workingCopy() const; QByteArray codeModelConfiguration() const; @@ -209,7 +210,6 @@ private: void initializeModelManagerSupports(); void delayedGC(); void recalculateProjectPartMappings(); - void updateCppEditorDocuments() const; void replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot); void removeFilesFromSnapshot(const QSet &removedFiles); From e4be9edc4d538465338b8981294aa414a43b7255 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 2 Dec 2015 16:52:47 +0100 Subject: [PATCH 47/47] Clang: Reduce document annotations timer Change-Id: If220ec7c84d41a47fc0f55dcbc55e62f0b7f05bd Reviewed-by: Marco Bubke --- src/tools/clangbackend/ipcsource/clangipcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clangbackend/ipcsource/clangipcserver.cpp b/src/tools/clangbackend/ipcsource/clangipcserver.cpp index c8bd3634e72..7165ed24a51 100644 --- a/src/tools/clangbackend/ipcsource/clangipcserver.cpp +++ b/src/tools/clangbackend/ipcsource/clangipcserver.cpp @@ -82,7 +82,7 @@ int getIntervalFromEnviromentVariable() int delayedDocumentAnnotationsTimerInterval() { - static const int defaultInterval = 3000; + static const int defaultInterval = 1500; static const int userDefinedInterval = getIntervalFromEnviromentVariable(); static const int interval = userDefinedInterval >= 0 ? userDefinedInterval : defaultInterval;