From 7b970a3a04bd4fefe2dfa632d6f6949c67402516 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 4 Aug 2015 15:52:22 +0200 Subject: [PATCH 01/19] QbsProjectManager: Support an equivalent of QML_IMPORT_PATH. Task-number: QTCREATORBUG-14849 Change-Id: I26f69b5c6c421b5eb965c96d75df15d16e960237 Reviewed-by: Joerg Bornemann --- src/libs/qmljs/qmljslink.cpp | 2 ++ src/plugins/qbsprojectmanager/qbsproject.cpp | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index d9dc7f2ba95..d91ef336f95 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -440,6 +440,8 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf "Import paths:\n" "%1\n\n" "For qmake projects, use the QML_IMPORT_PATH variable to add import paths.\n" + "For qbs projects, declare and set a qmlImportPaths property in your product " + "to add import paths.\n" "For qmlproject projects, use the importPaths property to add import paths.").arg( importPaths.join(QLatin1Char('\n')))); } diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 5d88012f3dc..738d512a830 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -857,6 +857,13 @@ void QbsProject::updateQmlJsCodeModel() QmlJS::ModelManagerInterface::ProjectInfo projectInfo = modelManager->defaultProjectInfoForProject(this); + foreach (const qbs::ProductData &product, m_projectData.allProducts()) { + static const QString propertyName = QLatin1String("qmlImportPaths"); + foreach (const QString &path, product.properties().value(propertyName).toStringList()) { + projectInfo.importPaths.maybeInsert(Utils::FileName::fromString(path), + QmlJS::Dialect::Qml); + } + } setProjectLanguage(ProjectExplorer::Constants::LANG_QMLJS, !projectInfo.sourceFiles.isEmpty()); modelManager->updateProjectInfo(projectInfo, this); From 818d90e0aec168ca30f05a2c720aa8d2278e6d4a Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 4 Aug 2015 16:13:52 +0200 Subject: [PATCH 02/19] Doc: fix a changed check box label Tools > Options > Text Editor > Display > Always Open Links in Next Split changed to "Always open links in another split". Change-Id: If363b6c14868a730641370098432cb9c0d45fe59 Reviewed-by: Eike Ziller --- doc/src/editors/creator-coding-edit-mode.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/editors/creator-coding-edit-mode.qdoc b/doc/src/editors/creator-coding-edit-mode.qdoc index 6793f96cfd5..32aef63c31a 100644 --- a/doc/src/editors/creator-coding-edit-mode.qdoc +++ b/doc/src/editors/creator-coding-edit-mode.qdoc @@ -168,8 +168,8 @@ \key {Ctrl+E,F2} to follow the symbol in the next split. If necessary, the view is automatically split. To change the default behavior, select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > - \uicontrol Display, and then select - \uicontrol {Always Open Links in Next Split}. Additional symbols are + \uicontrol Display > \uicontrol {Always open links in another split}. + Additional symbols are displayed and switching between definition and declaration is done in another split. If you change the default behavior, the shortcuts for opening link targets in the next split are used to open them in the current split. From 2afdfeeb3899055d7103e98c1916987da1c108ff Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 4 Aug 2015 15:46:12 +0200 Subject: [PATCH 03/19] Doc: update paths to Qt Designer plugins Change-Id: I6f07633322ec87c7358e1afc70670f295491722a Reviewed-by: Eike Ziller --- doc/src/widgets/qtdesigner-plugins.qdoc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/src/widgets/qtdesigner-plugins.qdoc b/doc/src/widgets/qtdesigner-plugins.qdoc index cc4052056af..3925e86e3ea 100644 --- a/doc/src/widgets/qtdesigner-plugins.qdoc +++ b/doc/src/widgets/qtdesigner-plugins.qdoc @@ -50,19 +50,20 @@ and integrated into \QC. The correct folder to place the plugins depends on whether you use the standalone \QD or the integrated \QD. - The integrated \QD fetches plugins from the \c {%SDK%\bin\designer} folder - on Windows and Linux. For information about how to configure plugins on - OS X, see \l{Configuring Qt Designer Plugins on OS X}. + The integrated \QD fetches plugins from the \c {\bin\plugins\designer} + directory in the \QC installation directory on Windows and Linux. For + information about how to configure plugins on OS X, see + \l{Configuring Qt Designer Plugins on OS X}. - To check which plugins - were loaded successfully and which failed, choose \uicontrol{Tools > Form Editor > - About Qt Designer Plugins}. + To check which plugins were loaded successfully and which failed, choose + \uicontrol Tools > \uicontrol {Form Editor} > + \uicontrol {About Qt Designer Plugins}. The standalone \QD is part of the Qt library used for building projects, - located under \c {%SDK%\qt}. Therefore, it fetches plugins from the - following folder: \c {%SDK%\qt\plugins\designer}. To check which plugins - were loaded successfully and which failed, choose \uicontrol{Help > - About Plugins}. + located in \c {\\bin} in the Qt installation + directory. It fetches plugins from the \c {\plugins\designer} subdirectory + of \c bin. To check which plugins were loaded successfully and which failed, + choose \uicontrol Help > \uicontrol {About Plugins}. \section2 Configuring Qt Designer Plugins on OS X From 0fd213357e4a0e11230e16e4cf25190d6039f30a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 4 Aug 2015 15:04:41 +0200 Subject: [PATCH 04/19] Clang: Tests for code completion Reparsing in Clang is broken in master. We need to test what is working in which version. Change-Id: I620acd4a0a5adc951951e0fc3c0a4096ac9844fe Reviewed-by: Nikolai Kosjar --- tests/unit/unittest/codecompletiontest.cpp | 201 +++++++++++++----- .../unit/unittest/data/complete_completer.cpp | 101 --------- .../unittest/data/complete_completer_main.cpp | 28 +++ .../data/complete_completer_main_unsaved.cpp | 28 +++ .../data/complete_completer_unsaved.cpp | 100 --------- .../data/complete_forwarding_header_1.h | 6 + .../data/complete_forwarding_header_2.h | 7 + .../unittest/data/complete_target_header.h | 7 + .../data/complete_target_header_changed.h | 8 + .../data/complete_target_header_unsaved.h | 8 + 10 files changed, 239 insertions(+), 255 deletions(-) delete mode 100644 tests/unit/unittest/data/complete_completer.cpp create mode 100644 tests/unit/unittest/data/complete_completer_main.cpp create mode 100644 tests/unit/unittest/data/complete_completer_main_unsaved.cpp delete mode 100644 tests/unit/unittest/data/complete_completer_unsaved.cpp create mode 100644 tests/unit/unittest/data/complete_forwarding_header_1.h create mode 100644 tests/unit/unittest/data/complete_forwarding_header_2.h create mode 100644 tests/unit/unittest/data/complete_target_header.h create mode 100644 tests/unit/unittest/data/complete_target_header_changed.h create mode 100644 tests/unit/unittest/data/complete_target_header_unsaved.h diff --git a/tests/unit/unittest/codecompletiontest.cpp b/tests/unit/unittest/codecompletiontest.cpp index 62bbbb6b9ca..87658687175 100644 --- a/tests/unit/unittest/codecompletiontest.cpp +++ b/tests/unit/unittest/codecompletiontest.cpp @@ -28,107 +28,200 @@ ** ****************************************************************************/ -#include "gtest/gtest.h" -#include "gmock/gmock-matchers.h" -#include "gtest-qt-printing.h" - #include #include +#include #include #include #include -#include #include +#include +#include +#include +#include +#include "gtest-qt-printing.h" using ::testing::ElementsAreArray; using ::testing::Contains; using ::testing::AllOf; using ::testing::Not; +using ::testing::PrintToString; using ClangBackEnd::CodeCompletion; using ClangBackEnd::CodeCompleter; namespace { +MATCHER_P2(IsCodeCompletion, text, completionKind, + std::string(negation ? "isn't" : "is") + " code completion with text " + + PrintToString(text) + " and kind " + PrintToString(completionKind) + ) +{ + if (arg.text() != text) { + *result_listener << "text is " + PrintToString(arg.text()) + " and not " + PrintToString(text); + return false; + } + + if (arg.completionKind() != completionKind) { + *result_listener << "kind is " + PrintToString(arg.completionKind()) + " and not " + PrintToString(completionKind); + return false; + } + + return true; +} + class CodeCompleter : public ::testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); +protected: + void SetUp(); + void copyTargetHeaderToTemporaryIncludeDirecory(); + void copyChangedTargetHeaderToTemporaryIncludeDirecory(); + static Utf8String readFileContent(const QString &fileName); protected: - static ClangBackEnd::ProjectPart projectPart; - static ClangBackEnd::UnsavedFiles unsavedFiles; - static ClangBackEnd::TranslationUnit translationUnit; - static ClangBackEnd::CodeCompleter completer; + QTemporaryDir includeDirectory; + QString targetHeaderPath{includeDirectory.path() + QStringLiteral("/complete_target_header.h")}; + ClangBackEnd::ProjectPart projectPart{Utf8StringLiteral("projectPartId")}; + ClangBackEnd::UnsavedFiles unsavedFiles; + ClangBackEnd::TranslationUnit translationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_completer_main.cpp"), + unsavedFiles, + projectPart}; + ClangBackEnd::CodeCompleter completer{translationUnit}; + ClangBackEnd::FileContainer unsavedMainFileContainer{translationUnit.filePath(), + projectPart.projectPartId(), + readFileContent(QStringLiteral("/complete_completer_main_unsaved.cpp")), + true}; + ClangBackEnd::FileContainer unsavedTargetHeaderFileContainer{targetHeaderPath, + projectPart.projectPartId(), + readFileContent(QStringLiteral("/complete_target_header_unsaved.h")), + true}; }; -ClangBackEnd::ProjectPart CodeCompleter::projectPart(Utf8StringLiteral("projectPartId")); -ClangBackEnd::UnsavedFiles CodeCompleter::unsavedFiles; -ClangBackEnd::TranslationUnit CodeCompleter::translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_completer.cpp"), unsavedFiles, projectPart); -ClangBackEnd::CodeCompleter CodeCompleter::completer = translationUnit; - -void CodeCompleter::SetUpTestCase() +Utf8String CodeCompleter::readFileContent(const QString &fileName) { - QFile unsavedFileContentFile(QStringLiteral(TESTDATA_DIR) + QStringLiteral("/complete_completer_unsaved.cpp")); - unsavedFileContentFile.open(QIODevice::ReadOnly); + QFile readFileContentFile(QStringLiteral(TESTDATA_DIR) + fileName); + bool hasOpened = readFileContentFile.open(QIODevice::ReadOnly | QIODevice::Text); - const Utf8String unsavedFileContent = Utf8String::fromByteArray(unsavedFileContentFile.readAll()); - const ClangBackEnd::FileContainer unsavedDataFileContainer(translationUnit.filePath(), - projectPart.projectPartId(), - unsavedFileContent, - true); + EXPECT_TRUE(hasOpened); - unsavedFiles.createOrUpdate({unsavedDataFileContainer}); + return Utf8String::fromByteArray(readFileContentFile.readAll()); } -void CodeCompleter::TearDownTestCase() +void CodeCompleter::copyTargetHeaderToTemporaryIncludeDirecory() { - translationUnit.reset(); - completer = ClangBackEnd::CodeCompleter(); + QFile::remove(targetHeaderPath); + bool hasCopied = QFile::copy(QStringLiteral(TESTDATA_DIR "/complete_target_header.h"), + targetHeaderPath); + EXPECT_TRUE(hasCopied); } +void CodeCompleter::copyChangedTargetHeaderToTemporaryIncludeDirecory() +{ + QFile::remove(targetHeaderPath); + bool hasCopied = QFile::copy(QStringLiteral(TESTDATA_DIR "/complete_target_header_changed.h"), + targetHeaderPath); + EXPECT_TRUE(hasCopied); +} + +void CodeCompleter::SetUp() +{ + EXPECT_TRUE(includeDirectory.isValid()); + + Utf8String includePath(QStringLiteral("-I") + includeDirectory.path()); + projectPart.setArguments({includePath}); + + copyTargetHeaderToTemporaryIncludeDirecory(); + + translationUnit.cxTranslationUnit(); // initialize translation unit so we check changes +} TEST_F(CodeCompleter, FunctionInUnsavedFile) { - ASSERT_THAT(completer.complete(100, 1), - AllOf(Contains(CodeCompletion(Utf8StringLiteral("functionWithArguments"), - 0, - CodeCompletion::FunctionCompletionKind)), - Contains(CodeCompletion(Utf8StringLiteral("function"), - 0, - CodeCompletion::FunctionCompletionKind)), - Contains(CodeCompletion(Utf8StringLiteral("newFunction"), - 0, - CodeCompletion::FunctionCompletionKind)), - Contains(CodeCompletion(Utf8StringLiteral("f"), - 0, - CodeCompletion::FunctionCompletionKind)), - Not(Contains(CodeCompletion(Utf8StringLiteral("otherFunction"), - 0, - CodeCompletion::FunctionCompletionKind))))); + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + AllOf(Contains(IsCodeCompletion(Utf8StringLiteral("FunctionWithArguments"), + CodeCompletion::FunctionCompletionKind)), + Contains(IsCodeCompletion(Utf8StringLiteral("Function"), + CodeCompletion::FunctionCompletionKind)), + Contains(IsCodeCompletion(Utf8StringLiteral("UnsavedFunction"), + CodeCompletion::FunctionCompletionKind)), + Contains(IsCodeCompletion(Utf8StringLiteral("f"), + CodeCompletion::FunctionCompletionKind)), + Not(Contains(IsCodeCompletion(Utf8StringLiteral("SavedFunction"), + CodeCompletion::FunctionCompletionKind))))); } +TEST_F(CodeCompleter, VariableInUnsavedFile) +{ + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("VariableInUnsavedFile"), + CodeCompletion::VariableCompletionKind))); +} + +TEST_F(CodeCompleter, GlobalVariableInUnsavedFile) +{ + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("GlobalVariableInUnsavedFile"), + CodeCompletion::VariableCompletionKind))); +} TEST_F(CodeCompleter, Macro) { - ASSERT_THAT(completer.complete(100, 1), - Contains(CodeCompletion(Utf8StringLiteral("Macro"), - 0, - CodeCompletion::PreProcessorCompletionKind))); + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("Macro"), + CodeCompletion::PreProcessorCompletionKind))); } TEST_F(CodeCompleter, Keyword) { - ASSERT_THAT(completer.complete(100, 1), - Contains(CodeCompletion(Utf8StringLiteral("switch"), - 0, - CodeCompletion::KeywordCompletionKind))); + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("switch"), + CodeCompletion::KeywordCompletionKind))); } - +TEST_F(CodeCompleter, FunctionInIncludedHeader) +{ + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeader"), + CodeCompletion::FunctionCompletionKind))); } +TEST_F(CodeCompleter, FunctionInUnsavedIncludedHeader) +{ + unsavedFiles.createOrUpdate({unsavedTargetHeaderFileContainer}); + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderUnsaved"), + CodeCompletion::FunctionCompletionKind))); +} + +TEST_F(CodeCompleter, FunctionInChangedIncludedHeader) +{ + copyChangedTargetHeaderToTemporaryIncludeDirecory(); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderChanged"), + CodeCompletion::FunctionCompletionKind))); +} + +TEST_F(CodeCompleter, FunctionInChangedIncludedHeaderWithUnsavedContentInMainFile) +{ + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + copyChangedTargetHeaderToTemporaryIncludeDirecory(); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderChanged"), + CodeCompletion::FunctionCompletionKind))); +} + +} diff --git a/tests/unit/unittest/data/complete_completer.cpp b/tests/unit/unittest/data/complete_completer.cpp deleted file mode 100644 index a764b7adb4e..00000000000 --- a/tests/unit/unittest/data/complete_completer.cpp +++ /dev/null @@ -1,101 +0,0 @@ -void function() -{ - -} - -class Foo; -void functionWithArguments(int i, char *c, const Foo &ref) -{ - -} - -void otherFunction() -{ - -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void f() -{ - -} diff --git a/tests/unit/unittest/data/complete_completer_main.cpp b/tests/unit/unittest/data/complete_completer_main.cpp new file mode 100644 index 00000000000..877ce23d286 --- /dev/null +++ b/tests/unit/unittest/data/complete_completer_main.cpp @@ -0,0 +1,28 @@ +#include "complete_forwarding_header_1.h" + +void Function() +{ + +} + +class Foo; +void FunctionWithArguments(int i, char *c, const Foo &ref) +{ + +} + +void SavedFunction() +{ + +} + + + + + + + +void f() +{ + +} diff --git a/tests/unit/unittest/data/complete_completer_main_unsaved.cpp b/tests/unit/unittest/data/complete_completer_main_unsaved.cpp new file mode 100644 index 00000000000..38af12b8583 --- /dev/null +++ b/tests/unit/unittest/data/complete_completer_main_unsaved.cpp @@ -0,0 +1,28 @@ +#include "complete_forwarding_header_2.h" + +void Function() +{ + +} + +class Foo; +void FunctionWithArguments(int i, char *c, const Foo &ref) +{ + +} + +void UnsavedFunction() +{ + +} + +#define Macro + +int GlobalVariableInUnsavedFile; + +void f() +{ + int VariableInUnsavedFile; + + +} diff --git a/tests/unit/unittest/data/complete_completer_unsaved.cpp b/tests/unit/unittest/data/complete_completer_unsaved.cpp deleted file mode 100644 index 9ec3fed8f47..00000000000 --- a/tests/unit/unittest/data/complete_completer_unsaved.cpp +++ /dev/null @@ -1,100 +0,0 @@ -void function() -{ - -} - -class Foo; -void functionWithArguments(int i, char *c, const Foo &ref) -{ - -} - -void newFunction() -{ - -} - -#define Macro - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void f() -{ - -} diff --git a/tests/unit/unittest/data/complete_forwarding_header_1.h b/tests/unit/unittest/data/complete_forwarding_header_1.h new file mode 100644 index 00000000000..4905abf3e87 --- /dev/null +++ b/tests/unit/unittest/data/complete_forwarding_header_1.h @@ -0,0 +1,6 @@ +#ifndef COMPLETE_FORWARDING_HEADER_1_H +#define COMPLETE_FORWARDING_HEADER_1_H + +#include + +#endif // COMPLETE_FORWARDING_HEADER_1_H diff --git a/tests/unit/unittest/data/complete_forwarding_header_2.h b/tests/unit/unittest/data/complete_forwarding_header_2.h new file mode 100644 index 00000000000..dd0c3bc2912 --- /dev/null +++ b/tests/unit/unittest/data/complete_forwarding_header_2.h @@ -0,0 +1,7 @@ +#ifndef COMPLETE_FORWARDING_HEADER_2_H +#define COMPLETE_FORWARDING_HEADER_2_H + +#include + +#endif // COMPLETE_FORWARDING_HEADER_2_H + diff --git a/tests/unit/unittest/data/complete_target_header.h b/tests/unit/unittest/data/complete_target_header.h new file mode 100644 index 00000000000..7d0ba1c8455 --- /dev/null +++ b/tests/unit/unittest/data/complete_target_header.h @@ -0,0 +1,7 @@ +#ifndef COMPLETE_TARGET_HEADER_H +#define COMPLETE_TARGET_HEADER_H + +void FunctionInIncludedHeader(); + +#endif // COMPLETE_TARGET_HEADER_H + diff --git a/tests/unit/unittest/data/complete_target_header_changed.h b/tests/unit/unittest/data/complete_target_header_changed.h new file mode 100644 index 00000000000..d631afd91b7 --- /dev/null +++ b/tests/unit/unittest/data/complete_target_header_changed.h @@ -0,0 +1,8 @@ +#ifndef COMPLETE_TARGET_HEADER_CHANGED_H +#define COMPLETE_TARGET_HEADER_CHANGED_H + +void FunctionInIncludedHeader(); +void FunctionInIncludedHeaderChanged(); + +#endif // COMPLETE_TARGET_HEADER_CHANGED_H + diff --git a/tests/unit/unittest/data/complete_target_header_unsaved.h b/tests/unit/unittest/data/complete_target_header_unsaved.h new file mode 100644 index 00000000000..904a861870e --- /dev/null +++ b/tests/unit/unittest/data/complete_target_header_unsaved.h @@ -0,0 +1,8 @@ +#ifndef COMPLETE_TARGET_HEADER_UNSAVED_H +#define COMPLETE_TARGET_HEADER_UNSAVED_H + +void FunctionInIncludedHeader(); +void FunctionInIncludedHeaderUnsaved(); + +#endif // COMPLETE_TARGET_HEADER_UNSAVED_H + From eff1d9f21f0f43b5c6a1678188eee1930ff17167 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 4 Aug 2015 16:29:05 +0200 Subject: [PATCH 05/19] Doc: fix tab name Tools > C++ > Inspect C++ Code Model > Project Parts > Include Paths is now "Header Paths". Change-Id: I0ec53ec2988df2a563b2a5212a6cc31152146e51 Reviewed-by: Nikolai Kosjar --- doc/src/editors/creator-coding-edit-mode.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/editors/creator-coding-edit-mode.qdoc b/doc/src/editors/creator-coding-edit-mode.qdoc index 32aef63c31a..f80aec704d5 100644 --- a/doc/src/editors/creator-coding-edit-mode.qdoc +++ b/doc/src/editors/creator-coding-edit-mode.qdoc @@ -197,5 +197,5 @@ \QC underlines semantic errors in olive in the C++ code editor. To check the correct paths for includes that are not resolved or that are resolved to the - wrong file, select \uicontrol {Project Parts} > \uicontrol {Include Paths}. + wrong file, select \uicontrol {Project Parts} > \uicontrol {Header Paths}. */ From adefa318aed92ee0440ec098c9f0ae67e1f1168c Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 14 Jul 2015 10:35:49 +0200 Subject: [PATCH 06/19] Tests: Emit coreAboutToClose() before exiting Now address sanitizer will not show false positives. Change-Id: Ieeb4dc31697920ed1ca542f5647f4cb0b23a29ab Task-number: QTCREATORBUG-14713 Reviewed-by: Eike Ziller --- src/libs/extensionsystem/pluginmanager.cpp | 16 ++++------------ src/libs/extensionsystem/pluginmanager.h | 1 + src/libs/extensionsystem/pluginmanager_p.h | 2 -- src/plugins/coreplugin/icore.cpp | 4 ++++ 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 441af54b5af..e310efe6f2b 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -847,7 +847,6 @@ void PluginManagerPrivate::nextDelayedInitialize() \internal */ PluginManagerPrivate::PluginManagerPrivate(PluginManager *pluginManager) : - m_failedTests(0), delayedInitializeTimer(0), shutdownEventLoop(0), m_profileElapsedMS(0), @@ -1127,6 +1126,7 @@ void PluginManagerPrivate::startTests() return; } + int failedTests = 0; foreach (const PluginManagerPrivate::TestSpec &testSpec, testSpecs) { IPlugin *plugin = testSpec.pluginSpec->plugin(); if (!plugin) @@ -1144,10 +1144,10 @@ void PluginManagerPrivate::startTests() ? generateCompleteTestPlan(plugin, testObjects) : generateCustomTestPlan(plugin, testObjects, testSpec.testFunctionsOrObjects); - m_failedTests += executeTestPlan(testPlan); + failedTests += executeTestPlan(testPlan); } - if (!testSpecs.isEmpty()) - QTimer::singleShot(1, this, SLOT(exitWithNumberOfFailedTests())); + + QTimer::singleShot(0, this, [failedTests]() { emit m_instance->testsFinished(failedTests); }); } #endif @@ -1270,14 +1270,6 @@ void PluginManagerPrivate::asyncShutdownFinished() shutdownEventLoop->exit(); } -/*! - \internal -*/ -void PluginManagerPrivate::exitWithNumberOfFailedTests() -{ - QCoreApplication::exit(m_failedTests); -} - /*! \internal */ diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h index 7b0ee066f4b..cbf0a2fe4df 100644 --- a/src/libs/extensionsystem/pluginmanager.h +++ b/src/libs/extensionsystem/pluginmanager.h @@ -158,6 +158,7 @@ signals: void pluginsChanged(); void initializationDone(); + void testsFinished(int failedTests); public slots: void remoteArguments(const QString &serializedArguments, QObject *socket); diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index f219d5c0dae..eb293977f45 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -102,7 +102,6 @@ public: QHash pluginCategories; QList pluginSpecs; QList testSpecs; - int m_failedTests; QStringList pluginPaths; QString pluginIID; QList allObjects; // ### make this a QList > > ? @@ -138,7 +137,6 @@ public: private slots: void nextDelayedInitialize(); void asyncShutdownFinished(); - void exitWithNumberOfFailedTests(); private: PluginCollection *defaultCollection; diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index a99fab23c52..982c3b9298b 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -323,6 +323,10 @@ ICore::ICore(MainWindow *mainwindow) // Save settings once after all plugins are initialized: connect(PluginManager::instance(), SIGNAL(initializationDone()), this, SLOT(saveSettings())); + connect(PluginManager::instance(), &PluginManager::testsFinished, [this] (int failedTests) { + emit coreAboutToClose(); + QCoreApplication::exit(failedTests); + }); connect(m_mainwindow, SIGNAL(newItemDialogRunningChanged()), this, SIGNAL(newItemDialogRunningChanged())); } From 414fa3c51d8eed07292f376bc170130bb928c0a4 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 5 Aug 2015 10:18:47 +0200 Subject: [PATCH 07/19] qbs build: Fix application install dir for OS X. The "Qt Creator" executable was put into the root dir instead of "Qt Creator.app/Contents/MacOS". Change-Id: Id353812076e36928d650f5cc3e6968f60c68d64b Reviewed-by: Joerg Bornemann --- src/app/app.qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/app.qbs b/src/app/app.qbs index c47fde658c0..6f585d6ce61 100644 --- a/src/app/app.qbs +++ b/src/app/app.qbs @@ -56,6 +56,6 @@ QtcProduct { Group { fileTagsFilter: product.type qbs.install: true - qbs.installDir: project.ide_app_path + qbs.installDir: project.ide_bin_path } } From 885e6dbac2bb3fb311b2a3ca0a7e7a98b77784c9 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 4 Aug 2015 17:51:12 +0200 Subject: [PATCH 08/19] Clang: Add convenience script to check clang completions This one is useful for inspecting the completions we get from clang (e.g. for checking if the bug is in clang or in our code, or to compare the completions of different clang versions). Change-Id: If9dfe1b58a2b087ef6b92485e10ff272badf75c8 Reviewed-by: Marco Bubke --- scripts/clangCompleteAt.sh | 150 +++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100755 scripts/clangCompleteAt.sh diff --git a/scripts/clangCompleteAt.sh b/scripts/clangCompleteAt.sh new file mode 100755 index 00000000000..a588e9aa7f2 --- /dev/null +++ b/scripts/clangCompleteAt.sh @@ -0,0 +1,150 @@ +#!/bin/sh + +################################################################################ +# Copyright (C) 2015 The Qt Company Ltd. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of The Qt Company Ltd, nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ + +# --- helpers ----------------------------------------------------------------- + +printUsage() +{ + echo "Usage: $0 [-v] [-c clang-executable] file line column" + echo + echo "Options:" + echo " -v Run c-index-test instead of clang to get more details." + echo " -c clang-executable Use the provided clang-executable." + echo + echo "The clang executable is determined by this order:" + echo " 1. Use clang from the -c option." + echo " 2. Use clang from environment variable CLANG_FOR_COMPLETION." + echo " 3. Use clang from \$PATH." + echo + echo "Path to c-index-test will be determined with the help of the clang executable." +} + +# There is no readlink on cygwin. +hasReadLink() +{ + return $(command -v readlink >/dev/null 2>&1) +} + +checkIfFileExistsOrDie() +{ + [ ! -f "$1" ] && echo "'$1' is not a file or does not exist." && exit 1 +} + +checkIfFileExistsAndIsExecutableOrDie() +{ + checkIfFileExistsOrDie "$1" + [ ! -x "$1" ] && echo "'$1' is not executable." && exit 2 +} + +findClangOrDie() +{ + if [ -z "$CLANG_EXEC" ]; then + if [ -n "${CLANG_FOR_COMPLETION}" ]; then + CLANG_EXEC=${CLANG_FOR_COMPLETION} + else + CLANG_EXEC=$(which clang) + fi + fi + hasReadLink && CLANG_EXEC=$(readlink -e "$CLANG_EXEC") + checkIfFileExistsAndIsExecutableOrDie "$CLANG_EXEC" +} + +findCIndexTestOrDie() +{ + if [ -n "$RUN_WITH_CINDEXTEST" ]; then + CINDEXTEST_EXEC=$(echo $CLANG_EXEC | sed -e 's/clang/c-index-test/g') + hasReadLink && CINDEXTEST_EXEC=$(readlink -e "$CINDEXTEST_EXEC") + checkIfFileExistsAndIsExecutableOrDie "$CINDEXTEST_EXEC" + fi +} + +printClangVersion() +{ + command="${CLANG_EXEC} --version" + echo "Command: $command" + eval $command +} + +runCodeCompletion() +{ + if [ -n "${CINDEXTEST_EXEC}" ]; then + command="${CINDEXTEST_EXEC} -code-completion-at=${FILE}:${LINE}:${COLUMN} ${FILE}" + else + command="${CLANG_EXEC} -cc1 -code-completion-at ${FILE}:${LINE}:${COLUMN} ${FILE}" + fi + echo "Command: $command" + eval $command +} + +# --- Process arguments ------------------------------------------------------- + +CLANG_EXEC= +RUN_WITH_CINDEXTEST= + +FILE= +LINE= +COLUMN= + +while [ -n "$1" ]; do + param=$1 + shift + case $param in + -h | -help | --help) + printUsage + exit 0 + ;; + -v | -verbose | --verbose) + RUN_WITH_CINDEXTEST=1 + ;; + -c | -clang | --clang) + CLANG_EXEC=$1 + shift + ;; + *) + break; + ;; + esac +done + +[ "$#" -ne 2 ] && printUsage && exit 1 +checkIfFileExistsOrDie "$param" +FILE=$param +LINE=$1 +COLUMN=$2 + +# --- main -------------------------------------------------------------------- + +findClangOrDie +findCIndexTestOrDie + +printClangVersion +echo +runCodeCompletion + From 66ba8fe6c59fda5ae19a559a5242abc71e19ab0e Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 5 Aug 2015 12:11:05 +0200 Subject: [PATCH 09/19] Clang: Disable test CodeCompletionsExtractor.Constructor It is caused by clang. Change-Id: Iaf760f590289a2f2a344f25879141bc37fed6881 Reviewed-by: Nikolai Kosjar --- tests/unit/unittest/codecompletionsextractortest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/unittest/codecompletionsextractortest.cpp b/tests/unit/unittest/codecompletionsextractortest.cpp index 38a1190a3d3..eed59dde0a2 100644 --- a/tests/unit/unittest/codecompletionsextractortest.cpp +++ b/tests/unit/unittest/codecompletionsextractortest.cpp @@ -366,7 +366,7 @@ TEST_F(CodeCompletionsExtractor, Enumerator) CodeCompletion::Available)); } -TEST_F(CodeCompletionsExtractor, Constructor) +TEST_F(CodeCompletionsExtractor, DISABLED_Constructor) { ClangCodeCompleteResults completeResults(getResults(constructorTranslationUnit, 20)); From 8c3c882a8a50b141c6dc3d62763cfd6094068c64 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 5 Aug 2015 12:07:20 +0200 Subject: [PATCH 10/19] Clang: Fix parsing of enable_if_t Task-number: QTCREATORBUG-11864 Change-Id: Ifd0d3482bc4f4373394734d4b173304db32a6a2d Reviewed-by: Nikolai Kosjar --- .../completionchunkstotextconverter.cpp | 24 +++++++++++++++--- .../completionchunkstotextconverter.h | 4 +++ .../test/clangcodecompletion_test.cpp | 4 +-- .../completionchunkstotextconvertertest.cpp | 25 ++++++++++++++----- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/plugins/clangcodemodel/completionchunkstotextconverter.cpp b/src/plugins/clangcodemodel/completionchunkstotextconverter.cpp index f8f76989f14..3b4f5b62777 100644 --- a/src/plugins/clangcodemodel/completionchunkstotextconverter.cpp +++ b/src/plugins/clangcodemodel/completionchunkstotextconverter.cpp @@ -79,6 +79,16 @@ void CompletionChunksToTextConverter::setAddExtraVerticalSpaceBetweenBraces(bool m_addExtraVerticalSpaceBetweenBraces = addExtraVerticalSpaceBetweenBraces; } +void CompletionChunksToTextConverter::setAddHtmlTags(bool addHtmlTags) +{ + m_addHtmlTags = addHtmlTags; +} + +void CompletionChunksToTextConverter::setAddOptional(bool addOptional) +{ + m_addOptional = addOptional; +} + const QString &CompletionChunksToTextConverter::text() const { return m_text; @@ -99,6 +109,7 @@ QString CompletionChunksToTextConverter::convertToFunctionSignature(const ClangB CompletionChunksToTextConverter converter; converter.setAddPlaceHolderText(true); converter.setAddResultType(true); + converter.setAddOptional(true); converter.parseChunks(codeCompletionChunks); @@ -120,6 +131,9 @@ QString CompletionChunksToTextConverter::convertToToolTip(const ClangBackEnd::Co converter.setAddPlaceHolderText(true); converter.setAddSpaces(true); converter.setAddExtraVerticalSpaceBetweenBraces(true); + converter.setAddOptional(true); + converter.setAddHtmlTags(true); + converter.setAddResultType(true); converter.parseChunks(codeCompletionChunks); @@ -158,11 +172,15 @@ void CompletionChunksToTextConverter::parseText(const Utf8String &text) void CompletionChunksToTextConverter::parseOptional(const ClangBackEnd::CodeCompletionChunk &optionalCodeCompletionChunk) { - m_text += QStringLiteral(""); + if (m_addOptional) { + if (m_addHtmlTags) + m_text += QStringLiteral(""); - m_text += convertToFunctionSignature(optionalCodeCompletionChunk.optionalChunks()); + m_text += convertToFunctionSignature(optionalCodeCompletionChunk.optionalChunks()); - m_text += QStringLiteral(""); + if (m_addHtmlTags) + m_text += QStringLiteral(""); + } } void CompletionChunksToTextConverter::parsePlaceHolder(const ClangBackEnd::CodeCompletionChunk &codeCompletionChunk) diff --git a/src/plugins/clangcodemodel/completionchunkstotextconverter.h b/src/plugins/clangcodemodel/completionchunkstotextconverter.h index 68c2bbcd149..174479d3640 100644 --- a/src/plugins/clangcodemodel/completionchunkstotextconverter.h +++ b/src/plugins/clangcodemodel/completionchunkstotextconverter.h @@ -52,6 +52,8 @@ public: void setAddResultType(bool addResultType); void setAddSpaces(bool addSpaces); void setAddExtraVerticalSpaceBetweenBraces(bool addExtraVerticalSpaceBetweenBraces); + void setAddHtmlTags(bool addHtmlTags); + void setAddOptional(bool addOptional); const QString &text() const; const std::vector &placeholderPositions() const; @@ -83,6 +85,8 @@ private: bool m_addResultType = false; bool m_addSpaces = false; bool m_addExtraVerticalSpaceBetweenBraces = false; + bool m_addHtmlTags = false; + bool m_addOptional = false; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp index 3b5cbef89aa..215c434d69c 100644 --- a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -868,8 +868,8 @@ void ClangCodeCompletionTest::testCompleteFunctions() QVERIFY(hasItem(t.proposal, "void f()")); QVERIFY(hasItem(t.proposal, "void f(int a)")); QVERIFY(hasItem(t.proposal, "void f(const QString &s)")); - QVERIFY(hasItem(t.proposal, "void f(char c, int optional)")); // TODO: No default argument? - QVERIFY(hasItem(t.proposal, "void f(char c, int optional1, int optional2)")); // TODO: No default argument? + QVERIFY(hasItem(t.proposal, "void f(char c, int optional)")); // TODO: No default argument? + QVERIFY(hasItem(t.proposal, "void f(char c, int optional1, int optional2)")); // TODO: No default argument? QVERIFY(hasItem(t.proposal, "void f(const TType *t)")); QVERIFY(hasItem(t.proposal, "TType f(bool)")); } diff --git a/tests/unit/unittest/completionchunkstotextconvertertest.cpp b/tests/unit/unittest/completionchunkstotextconvertertest.cpp index ff52c90311e..4a2e2d737bd 100644 --- a/tests/unit/unittest/completionchunkstotextconvertertest.cpp +++ b/tests/unit/unittest/completionchunkstotextconvertertest.cpp @@ -81,6 +81,9 @@ protected: CodeCompletionChunk ifName{CodeCompletionChunk::TypedText, Utf8StringLiteral("if")}; CodeCompletionChunk horizontalSpace{CodeCompletionChunk::HorizontalSpace, Utf8StringLiteral(" ")}; CodeCompletionChunk optional{CodeCompletionChunk::Optional, Utf8String(), {comma, functionArgumentY, comma, functionArgumentZ}}; + CodeCompletionChunk enableIfT{CodeCompletionChunk::TypedText, Utf8StringLiteral("enable_if_t")}; + CodeCompletionChunk enableIfTCondition{CodeCompletionChunk::Placeholder, Utf8StringLiteral("_Cond")}; + CodeCompletionChunk enableIfTType{CodeCompletionChunk::Placeholder, Utf8StringLiteral("_Tp")}; }; TEST_F(CompletionChunksToTextConverter, ParseIsClearingText) @@ -117,12 +120,9 @@ TEST_F(CompletionChunksToTextConverter, ConvertFunctionWithParameters) TEST_F(CompletionChunksToTextConverter, ConvertFunctionWithOptionalParameter) { CodeCompletionChunks completionChunks({integerResultType, functionName, leftParen, functionArgumentX, optional,rightParen}); - converter.setAddResultType(true); - converter.setAddPlaceHolderText(true); - converter.parseChunks(completionChunks); - - ASSERT_THAT(converter.text(), QStringLiteral("int Function(char x, int y, int z)")); + ASSERT_THAT(Converter::convertToToolTip(completionChunks), + QStringLiteral("int Function (char x, int y, int z)")); } TEST_F(CompletionChunksToTextConverter, ConvertVariable) @@ -227,7 +227,6 @@ TEST_F(CompletionChunksToTextConverter, ElseIf) statements, verticalSpace, rightBrace}); - setupConverterForKeywords(); converter.parseChunks(completionChunks); @@ -235,6 +234,20 @@ TEST_F(CompletionChunksToTextConverter, ElseIf) ASSERT_THAT(converter.text(), QStringLiteral("else if {\n\n}")); } +TEST_F(CompletionChunksToTextConverter, EnableIfT) +{ + CodeCompletionChunks completionChunks({enableIfT, + leftAngle, + enableIfTCondition, + CodeCompletionChunk(CodeCompletionChunk::Optional, Utf8String(), {comma, enableIfTType}), + rightAngle}); + setupConverterForKeywords(); + + converter.parseChunks(completionChunks); + + ASSERT_THAT(converter.text(), QStringLiteral("enable_if_t<>")); +} + void CompletionChunksToTextConverter::setupConverterForKeywords() { converter.setAddPlaceHolderPositions(true); From ea4b2859e74df4d5678af98b8202dba7001840b7 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 5 Aug 2015 11:18:24 +0200 Subject: [PATCH 11/19] Doc: code completion does not consider case by default "None" is now the default option. Change-Id: I68ed2ca418efb4dc58ad7f3637a19fbfd81cbb5e Reviewed-by: Nikolai Kosjar --- doc/src/editors/creator-editors.qdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 22e93118fb5..43b3b2399d3 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -787,9 +787,9 @@ Select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > \uicontrol Completion. - By default, code completion considers only the first letter case-sensitive. - To apply full or no case-sensitivity, select the option in the - \uicontrol {Case-sensitivity} field. + By default, code completion does not consider case. To apply full or + first-letter case-sensitivity, select \uicontrol Full or + \uicontrol {First Letter} in the \uicontrol {Case-sensitivity} field. \section2 Summary of Available Types From a7b9bcf48079ac62633b81e937b125b24c610fd9 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 5 Aug 2015 11:48:21 +0200 Subject: [PATCH 12/19] Doc: fix a group name in "Indenting Text and Code" "Typing" should be "Tabs and Indentation". Change-Id: I27917375ae0004dc11a33f355941e948402af5ba Reviewed-by: Eike Ziller --- doc/src/editors/creator-editors.qdoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 43b3b2399d3..38bbc50f3eb 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -1291,7 +1291,8 @@ \section2 Specifying Tabs and Indentation - You can specify tab policy and tab size in the \uicontrol Typing group. In + You can specify tab policy and tab size in the + \uicontrol {Tabs and Indentation} group. In the \uicontrol {Tab policy} field, select whether to use only spaces or only tabs for indentation, or to use a mixture of them. From cc9102369f2a43302a1fcaa0c9a4c49388e419d6 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 5 Aug 2015 15:00:43 +0200 Subject: [PATCH 13/19] Doc: update information about Clang Code Model Plugin Change-Id: Iee70665c116604a8e3ea37d72cdbfccb53960187 Reviewed-by: Nikolai Kosjar --- doc/src/editors/creator-clang-codemodel.qdoc | 25 ++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/doc/src/editors/creator-clang-codemodel.qdoc b/doc/src/editors/creator-clang-codemodel.qdoc index ed50ef8d57a..5effcc64583 100644 --- a/doc/src/editors/creator-clang-codemodel.qdoc +++ b/doc/src/editors/creator-clang-codemodel.qdoc @@ -55,19 +55,20 @@ \endlist - An IDE needs a parser for the language and the semantic analyzes. The only - difference between a code model and a compiler is that a code model does not - generate an executable. + An IDE needs a parser for the language and the semantic analyzes. - As \l{http://clang.llvm.org/}{Clang} is a compiler, as well as a code model, - it provides accurate information. The feedback you get through warning and - error markers is the same as the compiler will give you, not an incomplete + \section1 Using Clang Code Model + + The \l{http://clang.llvm.org/}{Clang} project provides libraries for parsing + C and C++ source files. The feedback you get through warning and + error markers is the same as a compiler will give you, not an incomplete set or a close approximation, as when using the built-in \QC code model. Clang focuses on detailed information for diagnostics, which is really useful if the code contains typos, for example. - Also, Clang already supports C++98/03, C89 and C99, Objective-C (and - Objective-C++), and C++11 support is in active development. + Clang keeps up with the development of the C++ language. At the time of this + writing, it supports C++98/03, C++11, C++14, C89, C99, Objective-C, and + Objective-C++. On the downside, for large projects using Clang as code model is slower than using the built-in code model. Clang does not need to generate object files, @@ -84,14 +85,14 @@ \list - \li Highlighting \li Code completion + \li Syntactic and semantic highlighting \endlist To use the plugin, you must build it and configure it in \QC. - \section1 Building Clang Code Model Plugin + \section2 Building Clang Code Model Plugin \list 1 @@ -138,7 +139,7 @@ \li Installed via package manager on Linux: - \c {LLVM_INSTALL_DIR=/usr/lib/llvm-3.4} + \c {LLVM_INSTALL_DIR=/usr/lib/llvm-3.6} \li Manually built on Unix in release mode: @@ -154,7 +155,7 @@ \endlist - \section1 Configuring Clang Code Model Plugin + \section2 Configuring Clang Code Model Plugin \list 1 From 658ab5c6805075420434afddc9588e0bcee2f875 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 5 Aug 2015 14:20:22 +0200 Subject: [PATCH 14/19] Locator: Fix wrong use of localized string in settings It was accidentally overwriting the text of a label with the text intended for the tool tip. Change-Id: Ie6e52413660d7959399029c10b7fafb3197ee2f6 Reviewed-by: Leena Miettinen --- src/plugins/coreplugin/locator/directoryfilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/locator/directoryfilter.cpp b/src/plugins/coreplugin/locator/directoryfilter.cpp index bce79a63893..8b719ca3dd2 100644 --- a/src/plugins/coreplugin/locator/directoryfilter.cpp +++ b/src/plugins/coreplugin/locator/directoryfilter.cpp @@ -100,7 +100,7 @@ bool DirectoryFilter::openConfigDialog(QWidget *parent, bool &needsRefresh) m_ui.prefixLabel->setText(ILocatorFilter::msgPrefixLabel()); m_ui.prefixLabel->setToolTip(ILocatorFilter::msgPrefixToolTip()); m_ui.defaultFlag->setText(ILocatorFilter::msgIncludeByDefault()); - m_ui.defaultFlag->setText(ILocatorFilter::msgIncludeByDefaultToolTip()); + m_ui.defaultFlag->setToolTip(ILocatorFilter::msgIncludeByDefaultToolTip()); connect(m_ui.addButton, &QPushButton::clicked, this, &DirectoryFilter::addDirectory, Qt::DirectConnection); connect(m_ui.editButton, &QPushButton::clicked, From a269acbb9e05209d2793c217e1b81e6e36dd4af0 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 5 Aug 2015 13:27:58 +0200 Subject: [PATCH 15/19] Doc: fix UI text related to searching - Regular Expressions > Use Regular Expressions - "Highlight search results on the scrollbar" is in the Display tab Change-Id: If3df17d9fd00f5fc0945ee979be81f9b62f78ac8 Reviewed-by: Eike Ziller --- doc/src/editors/creator-editors.qdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 38bbc50f3eb..9589bc9e497 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -1417,7 +1417,7 @@ \li To search only whole words, select \uicontrol {Whole Words Only}. \li To search using regular expressions, select - \uicontrol {Regular Expressions}. Regular expressions used in \QC + \uicontrol {Use Regular Expressions}. Regular expressions used in \QC are modeled on Perl regular expressions. For more information on using regular expressions, see the documentation for the QRegularExpression Class. @@ -1445,7 +1445,7 @@ The \uicontrol {Preserve Case when Replacing} option can be selected to preserve the case of the original text when replacing. This option is not - compatible with the \uicontrol {Regular Expressions} search option, and will + compatible with the \uicontrol {Use Regular Expressions} search option, and will thus be disabled when regular expressions are used. When the option is used, the case of the occurrence will be conserved, according to the following rules: @@ -1470,7 +1470,7 @@ The locations of search hits, breakpoints, and bookmarks in your document are highlighted on the editor scroll bar. To turn highlighting off, select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} > - \uicontrol {Highlight search results on the scrollbar}. + \uicontrol Display > \uicontrol {Highlight search results on the scrollbar}. \section1 Advanced Search From 707d49d2fb423e280507f08fa816b5703de4e1e3 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 5 Aug 2015 16:51:38 +0200 Subject: [PATCH 16/19] QbsProjectManager: Un-break MSVC. Commit aad5ca12c4 was over-eager, wrongly assuming the presence of cpp.cxxCompilerName for MSVC and also not taking into account that we don't set cpp.compilerVersion* from Qt Creator. Task-number: QBS-846 Change-Id: Id6a88c18f2c460ef66f0339aeb999b7fc0321225 Reviewed-by: Jake Petroules --- .../qbsprojectmanager/defaultpropertyprovider.cpp | 12 +++++++++++- src/plugins/qbsprojectmanager/qbsconstants.h | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp index 336ee55b6af..f3e6badb4d8 100644 --- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp +++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp @@ -230,13 +230,23 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor const QString toolchainPrefix = extractToolchainPrefix(&compilerName); if (!toolchainPrefix.isEmpty()) data.insert(QLatin1String(CPP_TOOLCHAINPREFIX), toolchainPrefix); - data.insert(QLatin1String(CPP_CXXCOMPILERNAME), compilerName); + if (toolchain.contains(QLatin1String("msvc"))) + data.insert(QLatin1String(CPP_COMPILERNAME), compilerName); + else + data.insert(QLatin1String(CPP_CXXCOMPILERNAME), compilerName); if (targetAbi.os() != ProjectExplorer::Abi::WindowsOS || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { data.insert(QLatin1String(CPP_LINKERNAME), compilerName); } data.insert(QLatin1String(CPP_TOOLCHAINPATH), cxxFileInfo.absolutePath()); + // TODO: Remove this once compiler version properties are set for MSVC + if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2013Flavor + || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2015Flavor) { + const QLatin1String flags("/FS"); + data.insert(QLatin1String(CPP_PLATFORMCFLAGS), flags); + data.insert(QLatin1String(CPP_PLATFORMCXXFLAGS), flags); + } return data; } diff --git a/src/plugins/qbsprojectmanager/qbsconstants.h b/src/plugins/qbsprojectmanager/qbsconstants.h index 666a7dc5773..b9ad484e443 100644 --- a/src/plugins/qbsprojectmanager/qbsconstants.h +++ b/src/plugins/qbsprojectmanager/qbsconstants.h @@ -41,8 +41,11 @@ const char QBS_ARCHITECTURE[] = "qbs.architecture"; const char QBS_TOOLCHAIN[] = "qbs.toolchain"; const char CPP_TOOLCHAINPATH[] = "cpp.toolchainInstallPath"; const char CPP_TOOLCHAINPREFIX[] = "cpp.toolchainPrefix"; +const char CPP_COMPILERNAME[] = "cpp.compilerName"; const char CPP_CXXCOMPILERNAME[] = "cpp.cxxCompilerName"; const char CPP_LINKERNAME[] = "cpp.linkerName"; +const char CPP_PLATFORMCFLAGS[] = "cpp.platformCFlags"; +const char CPP_PLATFORMCXXFLAGS[] = "cpp.platformCxxFlags"; const char CPP_PLATFORMPATH[] = "cpp.platformPath"; const char CPP_XCODESDKNAME[] = "cpp.xcodeSdkName"; const char CPP_XCODESDKVERSION[] = "cpp.xcodeSdkVersion"; From bde090ae9bb83286fc10d04bac91c6d85d23d7e8 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 5 Aug 2015 16:59:53 +0200 Subject: [PATCH 17/19] Clang: Let clangcodemodel/README point to the corresponding *.qdoc Change-Id: I5526ed6ea6840ccecd8890adf6ef454e45ba98f9 Reviewed-by: Leena Miettinen --- src/plugins/clangcodemodel/README | 60 +------------------------------ 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/src/plugins/clangcodemodel/README b/src/plugins/clangcodemodel/README index 0485e71076b..84e2a30d8e0 100644 --- a/src/plugins/clangcodemodel/README +++ b/src/plugins/clangcodemodel/README @@ -1,59 +1 @@ -The ClangCodeModel plugin -========================= - -The ClangCodeModel plugin integrates the clang frontend into Qt Creator. Clang -is "a C language family frontend for LLVM". You can find more information at -http://clang.llvm.org/. - -At the time of writing the plugin can replace the following functionality of -the built-in code model: - * Highlighting - * Completion - -All other functionality relies on the built-in code model (indexing, quick -fixes, follow symbol, find usages, ...). - -Setup -===== - -Compile the plugin ------------------- - -1. Get libclang - -You need to have libclang (and thus llvm) installed on your system. Either -build llvm/clang yourself [1], install some ready-to-use package [2] or use the -package manager of your system. - - [1] http://clang.llvm.org/get_started.html - See http://llvm.org/docs/GettingStarted.html#git-mirror for git mirrors. - [2] http://llvm.org/releases/ or http://llvm.org/builds/ - -If you are building llvm/clang yourself, make sure to build it in release mode. - -2. Set LLVM_INSTALL_DIR and (re)build Qt Creator - -Point the LLVM_INSTALL_DIR variable to the build/installation directory of -llvm, e.g.: - - Installed via package manager on GNU/Linux: - LLVM_INSTALL_DIR=/usr/lib/llvm-3.4 - Manually build on Unix in release mode: - LLVM_INSTALL_DIR=$HOME/llvm-build/Release+Asserts - Installed a snapshot on Windows: - LLVM_INSTALL_DIR=C:\llvm - -Set the variable either as part of the build environment or pass it directly to -qmake and rebuild Qt Creator. - -Enable the plugin ------------------ - -Enable the "ClangCodeModel" plugin in the dialog "Menu: Help -> About Plugins" -and restart Qt Creator. - -Select the file types you want to use the ClangCodeModel for in "Menu: Tools -> -Options -> C++ -> Tab: Code Model". For the next opened file matching the -selected file types the ClangCodeModel will be used (see limitations at the -start of this README). - +See ../../../doc/src/editors/creator-clang-codemodel.qdoc From 775661fafb04b712bc4c327dce3c5caf2184cf2b Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 5 Aug 2015 13:22:33 +0200 Subject: [PATCH 18/19] Clang: Ignore clang include directories from the toolchain Change-Id: I23a91f1511fad81de0abdd8c8d47dc23f0e0ae43 Task-number: QTCREATORBUG-14856 Reviewed-by: Erik Verbruggen --- src/plugins/clangcodemodel/clangutils.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index 02f448644fe..f0f68030fc9 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -147,7 +148,17 @@ private: bool excludeHeaderPath(const QString &path) const override { - return path.contains(QLatin1String("lib/gcc/i686-apple-darwin")); + if (path.contains(QLatin1String("lib/gcc/i686-apple-darwin"))) + return true; + + // We already provide a custom clang include path matching the used libclang version, + // so better ignore the clang include paths from the system as this might lead to an + // unfavorable order with regard to include_next. + static QRegExp clangIncludeDir(QLatin1String(".*/lib/clang/\\d+\\.\\d+\\.\\d+/include")); + if (clangIncludeDir.exactMatch(path)) + return true; + + return false; } void addResourceDirOptions() From 053b2b649fb8d7587d7d7469666d47bdda3da021 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 6 Aug 2015 09:33:41 +0200 Subject: [PATCH 19/19] Doc: "Include by default" locator option ...has replaced the "Limit to prefix" option. Change-Id: I23e2d7ea9e16933566edb992aa50f6f0c4df3d11 Reviewed-by: Eike Ziller --- doc/images/qtcreator-add-online-doc.png | Bin 8710 -> 11457 bytes .../qtcreator-navigate-customfilter.png | Bin 5905 -> 7539 bytes doc/src/editors/creator-editors.qdoc | 9 +++++---- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/images/qtcreator-add-online-doc.png b/doc/images/qtcreator-add-online-doc.png index ca9e148b42a41b4f196ac97717e194655a0c5cc2..c607de32d8e0c2ccc302b1218f2f1693d2c26b9c 100644 GIT binary patch literal 11457 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 literal 8710 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 z z<(k`W23^@@lTmu=b@!J#o!p()>lds^?EU=x{;%J@6^C_7`SqRqc79>mb@HUe>hJoq zSa^;9F8DLm!^R_Re&kEuyx%7eG^(w!=!`P=e7S1c12w~68ZOGq5EFt zT^vdiC)fVD`uyHcVV`HbCmtF7oEFU;oYTE$ZuXgMK0Cd|dp@T2KFZoucf@@CfQTX9Q!V&%RYzKk?EUIq&opvT|XEPZpS` z&k3XdW{&x~eu-UK7LjkxN*Z517k|Gz_)U+i!cCV6ips}Lf*X8J$JDSXc0%tv3aK7G4%*7L8U8nXGHEEkEw~s`KZMTs?Vm&#s=;o4>s%D-m(o&95x%@4Km^ zsaIOO^!k?F@nr#9zs_e)Ic$Iac4)+l4d1>Tv$kGzS$Og0cjEUttz#{AAFcn9K65$K z%}X4mpG`IyrgBaAo4E3pq(X9ra^#b<`~N!ry%V!SCb{V7EB@0jRi*seQttg(d~4^= zfS;M{yRzr~DqMU0%TJ>gsg-rV^o=CkRhjqlSZH&rZ&Cy`fgp9M+02u6jiCPB!5-5I sJd^gy7};0!1*tdqr138fi}}ag#uOTI{N%PO1_lNOPgg&ebxsLQ06PsYH2?qr diff --git a/doc/src/editors/creator-editors.qdoc b/doc/src/editors/creator-editors.qdoc index 9589bc9e497..1ee685c844d 100644 --- a/doc/src/editors/creator-editors.qdoc +++ b/doc/src/editors/creator-editors.qdoc @@ -2533,8 +2533,8 @@ \li Specify the prefix string. - \li To show only results matching this filter, select - \uicontrol {Limit to prefix}. + \li To implicitly include the filter even when not typing a prefix as a + part of the search string, select \uicontrol {Include by default}. \li Specify other available options. For more information, see \l{Adding Web Search Engines}. @@ -2602,8 +2602,9 @@ \li Specify the prefix string. - To show only results matching this filter, select - \uicontrol {Limit to prefix}. + To implicitly include the filter even when not typing a prefix + as a part of the search string, select + \uicontrol {Include by default}. \image qtcreator-navigate-customfilter.png