From 5988fd0f5cae56999aa389405e1fa3e0394962ed Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 15 Jun 2016 12:29:24 +0200 Subject: [PATCH 01/20] AutoTest: Add minimum support for debugging tests This adds another context menu entry for items on the test tree to allow debugging of a single test. Task-number: QTCREATORBUG-16070 Change-Id: I98f56b0f22c94ad71f0b91d690383043ed27f1c7 Reviewed-by: hjk Reviewed-by: David Schulz --- src/plugins/autotest/autotest.pro | 3 +- src/plugins/autotest/autotest.qbs | 4 +- .../autotest/autotest_dependencies.pri | 3 +- src/plugins/autotest/autotestplugin.cpp | 4 +- src/plugins/autotest/gtest/gtesttreeitem.cpp | 5 ++ src/plugins/autotest/gtest/gtesttreeitem.h | 2 + .../autotest/qtest/qttestconfiguration.cpp | 4 +- .../autotest/qtest/qttestconfiguration.h | 12 ++- src/plugins/autotest/qtest/qttesttreeitem.cpp | 12 +++ src/plugins/autotest/qtest/qttesttreeitem.h | 2 + src/plugins/autotest/testconfiguration.cpp | 8 +- src/plugins/autotest/testconfiguration.h | 5 +- src/plugins/autotest/testnavigationwidget.cpp | 41 ++++++++-- src/plugins/autotest/testnavigationwidget.h | 4 +- src/plugins/autotest/testresultspane.cpp | 4 +- src/plugins/autotest/testrunconfiguration.h | 48 ++++++++++++ src/plugins/autotest/testrunner.cpp | 78 ++++++++++++++++++- src/plugins/autotest/testrunner.h | 11 ++- src/plugins/autotest/testtreeitem.h | 2 + 19 files changed, 227 insertions(+), 25 deletions(-) create mode 100644 src/plugins/autotest/testrunconfiguration.h diff --git a/src/plugins/autotest/autotest.pro b/src/plugins/autotest/autotest.pro index 18d665b3758..a3061ccf6c8 100644 --- a/src/plugins/autotest/autotest.pro +++ b/src/plugins/autotest/autotest.pro @@ -91,7 +91,8 @@ HEADERS += \ quick/quicktest_utils.h \ quick/quicktestvisitors.h \ quick/quicktestframework.h \ - testframeworkmanager.h + testframeworkmanager.h \ + testrunconfiguration.h RESOURCES += \ autotest.qrc diff --git a/src/plugins/autotest/autotest.qbs b/src/plugins/autotest/autotest.qbs index b3b55a294a0..dd8070571a4 100644 --- a/src/plugins/autotest/autotest.qbs +++ b/src/plugins/autotest/autotest.qbs @@ -10,6 +10,7 @@ QtcPlugin { Depends { name: "QmlJS" } Depends { name: "QmlJSTools" } Depends { name: "Utils" } + Depends { name: "Debugger" } pluginTestDepends: [ "QbsProjectManager", @@ -71,7 +72,8 @@ QtcPlugin { "itestparser.h", "itestframework.h", "testframeworkmanager.cpp", - "testframeworkmanager.h" + "testframeworkmanager.h", + "testrunconfiguration.h" ] Group { diff --git a/src/plugins/autotest/autotest_dependencies.pri b/src/plugins/autotest/autotest_dependencies.pri index ab2e02f054d..1580d58e099 100644 --- a/src/plugins/autotest/autotest_dependencies.pri +++ b/src/plugins/autotest/autotest_dependencies.pri @@ -4,7 +4,8 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ projectexplorer \ cpptools \ - qmljstools + qmljstools \ + debugger QTC_LIB_DEPENDS += \ cplusplus \ diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp index 9e053f1b096..05764ab3c25 100644 --- a/src/plugins/autotest/autotestplugin.cpp +++ b/src/plugins/autotest/autotestplugin.cpp @@ -162,7 +162,7 @@ void AutotestPlugin::onRunAllTriggered() TestRunner *runner = TestRunner::instance(); TestTreeModel *model = TestTreeModel::instance(); runner->setSelectedTests(model->getAllTestCases()); - runner->prepareToRunTests(); + runner->prepareToRunTests(TestRunner::Run); } void AutotestPlugin::onRunSelectedTriggered() @@ -170,7 +170,7 @@ void AutotestPlugin::onRunSelectedTriggered() TestRunner *runner = TestRunner::instance(); TestTreeModel *model = TestTreeModel::instance(); runner->setSelectedTests(model->getSelectedTests()); - runner->prepareToRunTests(); + runner->prepareToRunTests(TestRunner::Run); } void AutotestPlugin::updateMenuItemsEnabledState() diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index 99f81a83583..1ed9f2cf3fd 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -133,6 +133,11 @@ TestConfiguration *GTestTreeItem::testConfiguration() const return config; } +TestConfiguration *GTestTreeItem::debugConfiguration() const +{ + return testConfiguration(); +} + // used as key inside getAllTestCases()/getSelectedTestCases() for Google Tests class ProFileWithDisplayName { diff --git a/src/plugins/autotest/gtest/gtesttreeitem.h b/src/plugins/autotest/gtest/gtesttreeitem.h index 41e188b27ac..0fabfa4bf9a 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.h +++ b/src/plugins/autotest/gtest/gtesttreeitem.h @@ -53,7 +53,9 @@ public: QVariant data(int column, int role) const override; bool canProvideTestConfiguration() const override { return type() != Root; } + bool canProvideDebugConfiguration() const override { return type() != Root; } TestConfiguration *testConfiguration() const override; + TestConfiguration *debugConfiguration() const override; QList getAllTestConfigurations() const override; QList getSelectedTestConfigurations() const override; TestTreeItem *find(const TestParseResult *result) override; diff --git a/src/plugins/autotest/qtest/qttestconfiguration.cpp b/src/plugins/autotest/qtest/qttestconfiguration.cpp index 004e01b833b..bb726eab111 100644 --- a/src/plugins/autotest/qtest/qttestconfiguration.cpp +++ b/src/plugins/autotest/qtest/qttestconfiguration.cpp @@ -38,7 +38,9 @@ TestOutputReader *QtTestConfiguration::outputReader(const QFutureInterface &fi, QProcess *app) const override; QStringList argumentsForTestRunner(const TestSettings &settings) const override; + void setRunMode(RunMode mode) { m_runMode = mode; } + +private: + RunMode m_runMode; }; } // namespace Internal diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp index df520b2f0e3..3a8c75b9e8b 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.cpp +++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp @@ -84,6 +84,11 @@ bool QtTestTreeItem::canProvideTestConfiguration() const } } +bool QtTestTreeItem::canProvideDebugConfiguration() const +{ + return canProvideTestConfiguration(); +} + TestConfiguration *QtTestTreeItem::testConfiguration() const { ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); @@ -128,6 +133,13 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const return config; } +TestConfiguration *QtTestTreeItem::debugConfiguration() const +{ + QtTestConfiguration *config = static_cast(testConfiguration()); + config->setRunMode(QtTestConfiguration::Debug); + return config; +} + QList QtTestTreeItem::getAllTestConfigurations() const { QList result; diff --git a/src/plugins/autotest/qtest/qttesttreeitem.h b/src/plugins/autotest/qtest/qttesttreeitem.h index 929144fe452..a53f0befa9b 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.h +++ b/src/plugins/autotest/qtest/qttesttreeitem.h @@ -40,7 +40,9 @@ public: QVariant data(int column, int role) const override; bool canProvideTestConfiguration() const override; + bool canProvideDebugConfiguration() const override; TestConfiguration *testConfiguration() const override; + TestConfiguration *debugConfiguration() const override; QList getAllTestConfigurations() const override; QList getSelectedTestConfigurations() const override; TestTreeItem *find(const TestParseResult *result) override; diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index 0dd8d0f283c..f5c24c49bb4 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -25,6 +25,8 @@ #include "testconfiguration.h" #include "testoutputreader.h" +#include "testrunconfiguration.h" +#include "testrunner.h" #include "testsettings.h" #include @@ -84,7 +86,7 @@ static bool isLocal(RunConfiguration *runConfiguration) return DeviceTypeKitInformation::deviceTypeId(kit) == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE; } -void TestConfiguration::completeTestInformation() +void TestConfiguration::completeTestInformation(int runMode) { QTC_ASSERT(!m_proFile.isEmpty(), return); @@ -99,6 +101,7 @@ void TestConfiguration::completeTestInformation() QString buildDir; Project *targetProject = 0; Utils::Environment env; + Target *runConfigTarget = 0; bool hasDesktopTarget = false; bool guessedRunConfiguration = false; setProject(0); @@ -152,6 +155,7 @@ void TestConfiguration::completeTestInformation() workDir = Utils::FileUtils::normalizePathName(stdRunnable.workingDirectory); env = stdRunnable.environment; hasDesktopTarget = true; + runConfigTarget = rc->target(); break; } } @@ -182,6 +186,8 @@ void TestConfiguration::completeTestInformation() setEnvironment(env); setProject(project); setGuessedConfiguration(guessedRunConfiguration); + if (!guessedRunConfiguration && runMode == TestRunner::Debug) + m_runConfig = new TestRunConfiguration(runConfigTarget); } } diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h index 05c9bde5995..2ea58b84cf6 100644 --- a/src/plugins/autotest/testconfiguration.h +++ b/src/plugins/autotest/testconfiguration.h @@ -44,6 +44,7 @@ namespace Internal { class TestOutputReader; class TestResult; +class TestRunConfiguration; struct TestSettings; using TestResultPtr = QSharedPointer; @@ -55,7 +56,7 @@ public: explicit TestConfiguration(); virtual ~TestConfiguration(); - void completeTestInformation(); + void completeTestInformation(int runMode); void setTestCases(const QStringList &testCases); void setTestCaseCount(int count); @@ -79,6 +80,7 @@ public: QString displayName() const { return m_displayName; } Utils::Environment environment() const { return m_environment; } ProjectExplorer::Project *project() const { return m_project.data(); } + TestRunConfiguration *runConfiguration() const { return m_runConfig; } bool guessedConfiguration() const { return m_guessedConfiguration; } virtual TestOutputReader *outputReader(const QFutureInterface &fi, @@ -97,6 +99,7 @@ private: Utils::Environment m_environment; QPointer m_project; bool m_guessedConfiguration = false; + TestRunConfiguration *m_runConfig = 0; }; } // namespace Internal diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp index 92182cc04a4..39f616b1c2d 100644 --- a/src/plugins/autotest/testnavigationwidget.cpp +++ b/src/plugins/autotest/testnavigationwidget.cpp @@ -120,6 +120,7 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event) QMenu menu; QAction *runThisTest = 0; + QAction *debugThisTest = 0; const QModelIndexList list = m_view->selectionModel()->selectedIndexes(); if (list.size() == 1) { const QModelIndex index = list.first(); @@ -131,7 +132,17 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event) runThisTest = new QAction(tr("Run This Test"), &menu); runThisTest->setEnabled(enabled); connect(runThisTest, &QAction::triggered, - this, &TestNavigationWidget::onRunThisTestTriggered); + this, [this] () { + onRunThisTestTriggered(TestRunner::Run); + }); + } + if (item->canProvideDebugConfiguration()) { + debugThisTest = new QAction(tr("Debug This Test"), &menu); + debugThisTest->setEnabled(enabled); + connect(debugThisTest, &QAction::triggered, + this, [this] () { + onRunThisTestTriggered(TestRunner::Debug); + }); } } } @@ -152,10 +163,13 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event) deselectAll->setEnabled(enabled && hasTests); rescan->setEnabled(enabled); - if (runThisTest) { + if (runThisTest) menu.addAction(runThisTest); + if (debugThisTest) + menu.addAction(debugThisTest); + if (runThisTest || debugThisTest) menu.addSeparator(); - } + menu.addAction(runAll); menu.addAction(runSelected); menu.addSeparator(); @@ -260,21 +274,32 @@ void TestNavigationWidget::initializeFilterMenu() m_filterMenu->addAction(action); } -void TestNavigationWidget::onRunThisTestTriggered() +void TestNavigationWidget::onRunThisTestTriggered(TestRunner::Mode runMode) { const QModelIndexList selected = m_view->selectionModel()->selectedIndexes(); - // paranoia if (selected.isEmpty()) return; - const QModelIndex sourceIndex = m_sortFilterModel->mapToSource(selected.first()); + const QModelIndex &sourceIndex = m_sortFilterModel->mapToSource(selected.first()); if (!sourceIndex.isValid()) return; TestTreeItem *item = static_cast(sourceIndex.internalPointer()); - if (TestConfiguration *configuration = item->testConfiguration()) { + TestConfiguration *configuration; + switch (runMode) { + case TestRunner::Run: + configuration = item->testConfiguration(); + break; + case TestRunner::Debug: + configuration = item->debugConfiguration(); + break; + default: + configuration = 0; + } + + if (configuration) { TestRunner *runner = TestRunner::instance(); runner->setSelectedTests( {configuration} ); - runner->prepareToRunTests(); + runner->prepareToRunTests(runMode); } } diff --git a/src/plugins/autotest/testnavigationwidget.h b/src/plugins/autotest/testnavigationwidget.h index 7bc900e2ce3..d64bf661e95 100644 --- a/src/plugins/autotest/testnavigationwidget.h +++ b/src/plugins/autotest/testnavigationwidget.h @@ -25,6 +25,8 @@ #pragma once +#include "testrunner.h" + #include #include @@ -74,7 +76,7 @@ private slots: private: void initializeFilterMenu(); - void onRunThisTestTriggered(); + void onRunThisTestTriggered(TestRunner::Mode runMode); TestTreeModel *m_model; TestTreeSortFilterModel *m_sortFilterModel; diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp index 71e15940f18..78b8a8971aa 100644 --- a/src/plugins/autotest/testresultspane.cpp +++ b/src/plugins/autotest/testresultspane.cpp @@ -397,14 +397,14 @@ void TestResultsPane::onRunAllTriggered() { TestRunner *runner = TestRunner::instance(); runner->setSelectedTests(TestTreeModel::instance()->getAllTestCases()); - runner->prepareToRunTests(); + runner->prepareToRunTests(TestRunner::Run); } void TestResultsPane::onRunSelectedTriggered() { TestRunner *runner = TestRunner::instance(); runner->setSelectedTests(TestTreeModel::instance()->getSelectedTests()); - runner->prepareToRunTests(); + runner->prepareToRunTests(TestRunner::Run); } void TestResultsPane::initializeFilterMenu() diff --git a/src/plugins/autotest/testrunconfiguration.h b/src/plugins/autotest/testrunconfiguration.h new file mode 100644 index 00000000000..ef471fc2369 --- /dev/null +++ b/src/plugins/autotest/testrunconfiguration.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +namespace Autotest { +namespace Internal { + +class TestRunConfiguration : public ProjectExplorer::RunConfiguration +{ +public: + TestRunConfiguration(ProjectExplorer::Target *parent) + : ProjectExplorer::RunConfiguration(parent, "AutoTest.TestRunConfig") + { + setDefaultDisplayName(tr("AutoTest Debug")); + addExtraAspects(); + } + +private: + QWidget *createConfigurationWidget() { return 0; } +}; + +} // namespace Internal +} // namespace Autotest diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 78990a9ab88..1802d278bf4 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -28,6 +28,7 @@ #include "autotestconstants.h" #include "autotestplugin.h" #include "testresultspane.h" +#include "testrunconfiguration.h" #include "testsettings.h" #include "testoutputreader.h" @@ -38,6 +39,7 @@ #include #include #include +#include #include @@ -45,6 +47,9 @@ #include #include +#include +#include + namespace Autotest { namespace Internal { @@ -125,7 +130,7 @@ static void performTestRun(QFutureInterface &futureInterface, QEventLoop eventLoop; int testCaseCount = 0; foreach (TestConfiguration *config, selectedTests) { - config->completeTestInformation(); + config->completeTestInformation(TestRunner::Run); if (config->project()) { testCaseCount += config->testCaseCount(); } else { @@ -208,8 +213,9 @@ static void performTestRun(QFutureInterface &futureInterface, futureInterface.setProgressValue(testCaseCount); } -void TestRunner::prepareToRunTests() +void TestRunner::prepareToRunTests(Mode mode) { + m_runMode = mode; ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings = ProjectExplorer::ProjectExplorerPlugin::projectExplorerSettings(); if (projectExplorerSettings.buildBeforeDeploy && !projectExplorerSettings.saveBeforeBuild) { @@ -251,7 +257,7 @@ void TestRunner::prepareToRunTests() } if (!projectExplorerSettings.buildBeforeDeploy) { - runTests(); + runOrDebugTests(); } else { if (project->hasActiveBuildSettings()) { buildProject(project); @@ -272,6 +278,70 @@ void TestRunner::runTests() Core::ProgressManager::addTask(future, tr("Running Tests"), Autotest::Constants::TASK_INDEX); } +void TestRunner::debugTests() +{ + // TODO improve to support more than one test configuration + QTC_ASSERT(m_selectedTests.size() == 1, onFinished();return); + + TestConfiguration *config = m_selectedTests.first(); + config->completeTestInformation(Debug); + if (!config->runConfiguration()) { + emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, + TestRunner::tr("Failed to get run configuration.")))); + onFinished(); + return; + } + + const QString &commandFilePath = executableFilePath(config->targetFile(), + config->environment().toProcessEnvironment()); + if (commandFilePath.isEmpty()) { + emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, + TestRunner::tr("Could not find command \"%1\". (%2)") + .arg(config->targetFile()) + .arg(config->displayName())))); + onFinished(); + return; + } + + Debugger::DebuggerStartParameters sp; + sp.inferior.executable = commandFilePath; + sp.inferior.commandLineArguments = config->argumentsForTestRunner( + *AutotestPlugin::instance()->settings()).join(' '); + sp.inferior.environment = config->environment(); + sp.inferior.workingDirectory = config->workingDirectory(); + sp.displayName = config->displayName(); + + QString errorMessage; + Debugger::DebuggerRunControl *runControl = Debugger::createDebuggerRunControl( + sp, config->runConfiguration(), &errorMessage); + + if (!runControl) { + emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, + TestRunner::tr("Failed to create run configuration.\n%1").arg(errorMessage)))); + onFinished(); + return; + } + + connect(runControl, &Debugger::DebuggerRunControl::finished, this, &TestRunner::onFinished); + ProjectExplorer::ProjectExplorerPlugin::startRunControl( + runControl, ProjectExplorer::Constants::DEBUG_RUN_MODE); + +} + +void TestRunner::runOrDebugTests() +{ + switch (m_runMode) { + case Run: + runTests(); + break; + case Debug: + debugTests(); + break; + default: + QTC_ASSERT(false, return); // unexpected run mode + } +} + void TestRunner::buildProject(ProjectExplorer::Project *project) { ProjectExplorer::BuildManager *buildManager = ProjectExplorer::BuildManager::instance(); @@ -290,7 +360,7 @@ void TestRunner::buildFinished(bool success) this, &TestRunner::buildFinished); if (success) { - runTests(); + runOrDebugTests(); } else { emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, tr("Build failed. Canceling test run.")))); diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h index aca76ac5ced..b79840b2653 100644 --- a/src/plugins/autotest/testrunner.h +++ b/src/plugins/autotest/testrunner.h @@ -44,6 +44,12 @@ class TestRunner : public QObject Q_OBJECT public: + enum Mode + { + Run, + Debug + }; + static TestRunner* instance(); ~TestRunner(); @@ -57,7 +63,7 @@ signals: void testResultReady(const TestResultPtr &result); public slots: - void prepareToRunTests(); + void prepareToRunTests(Mode mode); private slots: void buildProject(ProjectExplorer::Project *project); @@ -66,11 +72,14 @@ private slots: private: void runTests(); + void debugTests(); + void runOrDebugTests(); explicit TestRunner(QObject *parent = 0); QFutureWatcher m_futureWatcher; QList m_selectedTests; bool m_executingTests; + Mode m_runMode = Run; // temporarily used if building before running is necessary QMetaObject::Connection m_buildConnect; diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index 325898c595d..0404bb46dcf 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -102,7 +102,9 @@ public: TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath); virtual bool canProvideTestConfiguration() const { return false; } + virtual bool canProvideDebugConfiguration() const { return false; } virtual TestConfiguration *testConfiguration() const { return 0; } + virtual TestConfiguration *debugConfiguration() const { return 0; } virtual QList getAllTestConfigurations() const; virtual QList getSelectedTestConfigurations() const; virtual bool lessThan(const TestTreeItem *other, SortMode mode) const; From 5a78fcb434619bf035eafbc2fcd6c27dc29a8dc9 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 14 Jun 2016 08:00:32 +0200 Subject: [PATCH 02/20] Editor: Restrict deletion of automatically inserted characters. Remove automatically inserted characters only when the cursor wasn't explicitly moved or the editor hasn't lost the focus after the completion. Change-Id: I9e995dc4ce79194b073b1bce3fa4dbc025a09a94 Reviewed-by: Christian Stenger Reviewed-by: David Schulz --- src/plugins/texteditor/completionsettings.cpp | 5 ++ src/plugins/texteditor/completionsettings.h | 1 + .../texteditor/completionsettingspage.cpp | 3 + .../texteditor/completionsettingspage.ui | 60 +++++++++++++++++-- src/plugins/texteditor/texteditor.cpp | 6 +- 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/plugins/texteditor/completionsettings.cpp b/src/plugins/texteditor/completionsettings.cpp index a012e407c2f..61c9f203a87 100644 --- a/src/plugins/texteditor/completionsettings.cpp +++ b/src/plugins/texteditor/completionsettings.cpp @@ -41,6 +41,7 @@ static const char autoSplitStringsKey[] = "AutoSplitStrings"; static const char animateAutoCompleteKey[] = "AnimateAutoComplete"; static const char highlightAutoCompleteKey[] = "HighlightAutoComplete"; static const char skipAutoCompleteKey[] = "SkipAutoComplete"; +static const char autoRemoveKey[] = "AutoRemove"; using namespace TextEditor; @@ -60,6 +61,7 @@ void CompletionSettings::toSettings(QSettings *s) const s->setValue(animateAutoCompleteKey, m_animateAutoComplete); s->setValue(highlightAutoCompleteKey, m_highlightAutoComplete); s->setValue(skipAutoCompleteKey, m_skipAutoCompletedText); + s->setValue(autoRemoveKey, m_autoRemove); s->endGroup(); } @@ -94,6 +96,8 @@ void CompletionSettings::fromSettings(QSettings *s) s->value(highlightAutoCompleteKey, m_highlightAutoComplete).toBool(); m_skipAutoCompletedText = s->value(skipAutoCompleteKey, m_skipAutoCompletedText).toBool(); + m_autoRemove = + s->value(autoRemoveKey, m_autoRemove).toBool(); s->endGroup(); } @@ -112,5 +116,6 @@ bool CompletionSettings::equals(const CompletionSettings &cs) const && m_animateAutoComplete == cs.m_animateAutoComplete && m_highlightAutoComplete == cs.m_highlightAutoComplete && m_skipAutoCompletedText == cs.m_skipAutoCompletedText + && m_autoRemove == cs.m_autoRemove ; } diff --git a/src/plugins/texteditor/completionsettings.h b/src/plugins/texteditor/completionsettings.h index 7ca5535b3eb..9fa75e6152f 100644 --- a/src/plugins/texteditor/completionsettings.h +++ b/src/plugins/texteditor/completionsettings.h @@ -69,6 +69,7 @@ public: bool m_animateAutoComplete = true; bool m_highlightAutoComplete = true; bool m_skipAutoCompletedText = true; + bool m_autoRemove = true; }; inline bool operator==(const CompletionSettings &t1, const CompletionSettings &t2) { return t1.equals(t2); } diff --git a/src/plugins/texteditor/completionsettingspage.cpp b/src/plugins/texteditor/completionsettingspage.cpp index 1c5d4e2ddea..b824926028d 100644 --- a/src/plugins/texteditor/completionsettingspage.cpp +++ b/src/plugins/texteditor/completionsettingspage.cpp @@ -105,6 +105,7 @@ QWidget *CompletionSettingsPage::widget() m_page->animateAutoComplete->setChecked(m_completionSettings.m_animateAutoComplete); m_page->highlightAutoComplete->setChecked(m_completionSettings.m_highlightAutoComplete); m_page->skipAutoComplete->setChecked(m_completionSettings.m_skipAutoCompletedText); + m_page->removeAutoComplete->setChecked(m_completionSettings.m_autoRemove); m_page->enableDoxygenCheckBox->setChecked(m_commentsSettings.m_enableDoxygen); m_page->generateBriefCheckBox->setChecked(m_commentsSettings.m_generateBrief); @@ -112,6 +113,7 @@ QWidget *CompletionSettingsPage::widget() m_page->generateBriefCheckBox->setEnabled(m_page->enableDoxygenCheckBox->isChecked()); m_page->skipAutoComplete->setEnabled(m_page->highlightAutoComplete->isChecked()); + m_page->removeAutoComplete->setEnabled(m_page->highlightAutoComplete->isChecked()); } return m_widget; } @@ -182,6 +184,7 @@ void CompletionSettingsPage::settingsFromUi(CompletionSettings &completion, Comm completion.m_animateAutoComplete = m_page->animateAutoComplete->isChecked(); completion.m_highlightAutoComplete = m_page->highlightAutoComplete->isChecked(); completion.m_skipAutoCompletedText = m_page->skipAutoComplete->isChecked(); + completion.m_autoRemove = m_page->removeAutoComplete->isChecked(); comment.m_enableDoxygen = m_page->enableDoxygenCheckBox->isChecked(); comment.m_generateBrief = m_page->generateBriefCheckBox->isChecked(); diff --git a/src/plugins/texteditor/completionsettingspage.ui b/src/plugins/texteditor/completionsettingspage.ui index b5bf12a0a0e..7eda07d2aed 100644 --- a/src/plugins/texteditor/completionsettingspage.ui +++ b/src/plugins/texteditor/completionsettingspage.ui @@ -7,7 +7,7 @@ 0 0 551 - 465 + 493 @@ -270,6 +270,39 @@ In addition, Shift+Enter inserts an escape character at the cursor position and + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + Remove the automatically inserted character if the trigger is deleted by backspace after the completion. + + + Remove automatically inserted text on backspace + + + true + + + + + @@ -361,6 +394,7 @@ In addition, Shift+Enter inserts an escape character at the cursor position and animateAutoComplete highlightAutoComplete skipAutoComplete + removeAutoComplete enableDoxygenCheckBox generateBriefCheckBox leadingAsterisksCheckBox @@ -374,12 +408,12 @@ In addition, Shift+Enter inserts an escape character at the cursor position and setEnabled(bool) - 195 - 383 + 216 + 411 - 320 - 410 + 378 + 438 @@ -399,5 +433,21 @@ In addition, Shift+Enter inserts an escape character at the cursor position and + + highlightAutoComplete + toggled(bool) + removeAutoComplete + setEnabled(bool) + + + 223 + 275 + + + 226 + 333 + + + diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 5f0ecb647b3..70e70585890 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -456,6 +456,7 @@ public: bool m_animateAutoComplete = true; bool m_highlightAutoComplete = true; bool m_skipAutoCompletedText = true; + bool m_removeAutoCompletedText = true; bool m_keepAutoCompletionHighlight = false; QTextCursor m_autoCompleteHighlightPos; @@ -5365,8 +5366,10 @@ void TextEditorWidgetPrivate::handleBackspaceKey() const TabSettings &tabSettings = m_document->tabSettings(); const TypingSettings &typingSettings = m_document->typingSettings(); - if (typingSettings.m_autoIndent && m_autoCompleter->autoBackspace(cursor)) + if (typingSettings.m_autoIndent && (m_autoCompleteHighlightPos == cursor) + && m_removeAutoCompletedText && m_autoCompleter->autoBackspace(cursor)) { return; + } bool handled = false; if (typingSettings.m_smartBackspaceBehavior == TypingSettings::BackspaceNeverIndents) { @@ -6571,6 +6574,7 @@ void TextEditorWidget::setCompletionSettings(const CompletionSettings &completio d->m_animateAutoComplete = completionSettings.m_animateAutoComplete; d->m_highlightAutoComplete = completionSettings.m_highlightAutoComplete; d->m_skipAutoCompletedText = completionSettings.m_skipAutoCompletedText; + d->m_removeAutoCompletedText = completionSettings.m_autoRemove; } void TextEditorWidget::setExtraEncodingSettings(const ExtraEncodingSettings &extraEncodingSettings) From b928a1ce46a810941a54c42b20f4692f2db2ebb0 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 21 Jun 2016 10:34:23 +0200 Subject: [PATCH 03/20] CppEditor: Extract determineGetterSetterNames() ...and make it a bit more readable since we are going to make some changes there. Change-Id: Ic1d0c47a36ef4547a4842508c2404e9fc12f5220 Reviewed-by: David Schulz --- src/plugins/cppeditor/cppquickfixes.cpp | 35 +++++++++++++++++-------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 157032953dd..604243d6d39 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -2832,17 +2832,7 @@ public: } m_variableString = QString::fromUtf8(variableId->chars(), variableId->size()); - m_baseName = memberBaseName(m_variableString); - if (m_baseName.isEmpty()) - m_baseName = QLatin1String("value"); - - m_getterName = !(m_baseName == m_variableString - || hasClassMemberWithGetPrefix(m_classSpecifier->symbol)) - ? m_baseName - : QString::fromLatin1("get%1%2") - .arg(m_baseName.left(1).toUpper()).arg(m_baseName.mid(1)); - m_setterName = QString::fromLatin1("set%1%2") - .arg(m_baseName.left(1).toUpper()).arg(m_baseName.mid(1)); + determineGetterSetterNames(); // Check if the class has already a getter and/or a setter. // This is only a simple check which should suffice not triggering the @@ -2909,6 +2899,8 @@ public: updateDescriptionAndPriority(); } + void determineGetterSetterNames(); + // Clones "other" in order to prevent all the initial detection made in the ctor. GenerateGetterSetterOperation(const CppQuickFixInterface &interface, GenerateGetterSetterOperation *other, OperationType type) @@ -5968,5 +5960,26 @@ void ExtraRefactoringOperations::match(const CppQuickFixInterface &interface, } } +void GenerateGetterSetterOperation::determineGetterSetterNames() +{ + m_baseName = memberBaseName(m_variableString); + if (m_baseName.isEmpty()) + m_baseName = QLatin1String("value"); + + // Getter Name + const bool hasValidBaseName = m_baseName != m_variableString; + const bool getPrefixIsAlreadyUsed = hasClassMemberWithGetPrefix(m_classSpecifier->symbol); + if (hasValidBaseName && !getPrefixIsAlreadyUsed) { + m_getterName = m_baseName; + } else { + const QString baseNameWithCapital = m_baseName.left(1).toUpper() + m_baseName.mid(1); + m_getterName = QLatin1String("get") + baseNameWithCapital; + } + + // Setter Name + const QString baseNameWithCapital = m_baseName.left(1).toUpper() + m_baseName.mid(1); + m_setterName = QLatin1String("set") + baseNameWithCapital; +} + } // namespace Internal } // namespace CppEditor From 1ea640433736d599a2ec0cb716924db1560f59a3 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Tue, 21 Jun 2016 11:16:39 +0200 Subject: [PATCH 04/20] CppTools: Allow prefering getter names with "get" prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We default to "foo()" for e.g. a member variable "m_foo", but other coding styles require "getFoo()". Task-number: QTCREATORBUG-16452 Change-Id: I9ccfdf88e4c469bc1c06fde855ad754faf2bd238 Reviewed-by: André Hartmann --- src/plugins/cppeditor/cppeditorplugin.h | 1 + src/plugins/cppeditor/cppquickfix_test.cpp | 79 +++++++++++++++++++ src/plugins/cppeditor/cppquickfixes.cpp | 3 +- src/plugins/cpptools/cppcodestylesettings.cpp | 64 +++++++++------ src/plugins/cpptools/cppcodestylesettings.h | 5 ++ .../cpptools/cppcodestylesettingspage.cpp | 4 + .../cpptools/cppcodestylesettingspage.ui | 27 +++++++ 7 files changed, 156 insertions(+), 27 deletions(-) diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index eb59a3a0792..35c7fca23ec 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -117,6 +117,7 @@ private slots: void test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp(); void test_quickfix_GenerateGetterSetter_onlyGetter(); + void test_quickfix_GenerateGetterSetter_onlyGetter_DontPreferGetterWithGet(); void test_quickfix_GenerateGetterSetter_onlySetter(); void test_quickfix_GenerateGetterSetter_offerGetterWhenSetterPresent(); void test_quickfix_GenerateGetterSetter_offerSetterWhenGetterPresent(); diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index ddd2b5097d4..742106252a5 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -1890,6 +1890,85 @@ void CppEditorPlugin::test_quickfix_GenerateGetterSetter_onlySetter() QuickFixOperationTest(testDocuments, &factory, ProjectPartHeaderPaths(), 2); } +class CppCodeStyleSettingsChanger { +public: + CppCodeStyleSettingsChanger(const CppCodeStyleSettings &settings); + ~CppCodeStyleSettingsChanger(); // Restore original + + static CppCodeStyleSettings currentSettings(); + +private: + void setSettings(const CppCodeStyleSettings &settings); + + CppCodeStyleSettings m_originalSettings; +}; + +CppCodeStyleSettingsChanger::CppCodeStyleSettingsChanger(const CppCodeStyleSettings &settings) +{ + m_originalSettings = currentSettings(); + setSettings(settings); +} + +CppCodeStyleSettingsChanger::~CppCodeStyleSettingsChanger() +{ + setSettings(m_originalSettings); +} + +void CppCodeStyleSettingsChanger::setSettings(const CppCodeStyleSettings &settings) +{ + QVariant variant; + variant.setValue(settings); + + CppCodeStylePreferences *preferences = CppToolsSettings::instance()->cppCodeStyle(); + preferences->currentDelegate()->setValue(variant); +} + +CppCodeStyleSettings CppCodeStyleSettingsChanger::currentSettings() +{ + CppCodeStylePreferences *preferences = CppToolsSettings::instance()->cppCodeStyle(); + return preferences->currentDelegate()->value().value(); +} + +void CppEditorPlugin::test_quickfix_GenerateGetterSetter_onlyGetter_DontPreferGetterWithGet() +{ + CppCodeStyleSettings modifiedSettings = CppCodeStyleSettingsChanger::currentSettings(); + modifiedSettings.preferGetterNameWithoutGetPrefix = false; + CppCodeStyleSettingsChanger changer(modifiedSettings); + + QList testDocuments; + QByteArray original; + QByteArray expected; + + // Header File + original = + "class Foo\n" + "{\n" + "public:\n" + " int m_bar@;\n" + "};\n"; + expected = + "class Foo\n" + "{\n" + "public:\n" + " int m_bar@;\n" + " int getBar() const;\n" + "};\n"; + testDocuments << QuickFixTestDocument::create("file.h", original, expected); + + // Source File + original.resize(0); + expected = + "\n" + "int Foo::getBar() const\n" + "{\n" + " return m_bar;\n" + "}\n"; + testDocuments << QuickFixTestDocument::create("file.cpp", original, expected); + + GenerateGetterSetter factory; + QuickFixOperationTest(testDocuments, &factory, ProjectPartHeaderPaths(), 1); +} + /// Checks: Offer a "generate getter" quick fix if there is a setter void CppEditorPlugin::test_quickfix_GenerateGetterSetter_offerGetterWhenSetterPresent() { diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 604243d6d39..cb9df1eb314 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -5967,9 +5967,10 @@ void GenerateGetterSetterOperation::determineGetterSetterNames() m_baseName = QLatin1String("value"); // Getter Name + const CppCodeStyleSettings settings = CppCodeStyleSettings::currentProjectCodeStyle(); const bool hasValidBaseName = m_baseName != m_variableString; const bool getPrefixIsAlreadyUsed = hasClassMemberWithGetPrefix(m_classSpecifier->symbol); - if (hasValidBaseName && !getPrefixIsAlreadyUsed) { + if (settings.preferGetterNameWithoutGetPrefix && hasValidBaseName && !getPrefixIsAlreadyUsed) { m_getterName = m_baseName; } else { const QString baseNameWithCapital = m_baseName.left(1).toUpper() + m_baseName.mid(1); diff --git a/src/plugins/cpptools/cppcodestylesettings.cpp b/src/plugins/cpptools/cppcodestylesettings.cpp index a0d618225c6..06d396e59c8 100644 --- a/src/plugins/cpptools/cppcodestylesettings.cpp +++ b/src/plugins/cpptools/cppcodestylesettings.cpp @@ -59,6 +59,7 @@ static const char bindStarToLeftSpecifierKey[] = "BindStarToLeftSpecifier"; static const char bindStarToRightSpecifierKey[] = "BindStarToRightSpecifier"; static const char extraPaddingForConditionsIfConfusingAlignKey[] = "ExtraPaddingForConditionsIfConfusingAlign"; static const char alignAssignmentsKey[] = "AlignAssignments"; +static const char shortGetterNameKey[] = "ShortGetterName"; using namespace CppTools; @@ -85,6 +86,7 @@ CppCodeStyleSettings::CppCodeStyleSettings() : , bindStarToRightSpecifier(false) , extraPaddingForConditionsIfConfusingAlign(true) , alignAssignments(false) + , preferGetterNameWithoutGetPrefix(true) { } @@ -121,6 +123,7 @@ void CppCodeStyleSettings::toMap(const QString &prefix, QVariantMap *map) const map->insert(prefix + QLatin1String(bindStarToRightSpecifierKey), bindStarToRightSpecifier); map->insert(prefix + QLatin1String(extraPaddingForConditionsIfConfusingAlignKey), extraPaddingForConditionsIfConfusingAlign); map->insert(prefix + QLatin1String(alignAssignmentsKey), alignAssignments); + map->insert(prefix + QLatin1String(shortGetterNameKey), preferGetterNameWithoutGetPrefix); } void CppCodeStyleSettings::fromMap(const QString &prefix, const QVariantMap &map) @@ -165,6 +168,8 @@ void CppCodeStyleSettings::fromMap(const QString &prefix, const QVariantMap &map extraPaddingForConditionsIfConfusingAlign).toBool(); alignAssignments = map.value(prefix + QLatin1String(alignAssignmentsKey), alignAssignments).toBool(); + preferGetterNameWithoutGetPrefix = map.value(prefix + QLatin1String(shortGetterNameKey), + preferGetterNameWithoutGetPrefix).toBool(); } bool CppCodeStyleSettings::equals(const CppCodeStyleSettings &rhs) const @@ -188,7 +193,37 @@ bool CppCodeStyleSettings::equals(const CppCodeStyleSettings &rhs) const && bindStarToLeftSpecifier == rhs.bindStarToLeftSpecifier && bindStarToRightSpecifier == rhs.bindStarToRightSpecifier && extraPaddingForConditionsIfConfusingAlign == rhs.extraPaddingForConditionsIfConfusingAlign - && alignAssignments == rhs.alignAssignments; + && alignAssignments == rhs.alignAssignments + && preferGetterNameWithoutGetPrefix == rhs.preferGetterNameWithoutGetPrefix + ; +} + +CppCodeStyleSettings CppCodeStyleSettings::currentProjectCodeStyle() +{ + ProjectExplorer::Project *project = ProjectExplorer::ProjectTree::currentProject(); + if (!project) + return currentGlobalCodeStyle(); + + ProjectExplorer::EditorConfiguration *editorConfiguration = project->editorConfiguration(); + QTC_ASSERT(editorConfiguration, return currentGlobalCodeStyle()); + + TextEditor::ICodeStylePreferences *codeStylePreferences + = editorConfiguration->codeStyle(Constants::CPP_SETTINGS_ID); + QTC_ASSERT(codeStylePreferences, return currentGlobalCodeStyle()); + + CppCodeStylePreferences *cppCodeStylePreferences + = dynamic_cast(codeStylePreferences); + QTC_ASSERT(cppCodeStylePreferences, return currentGlobalCodeStyle()); + + return cppCodeStylePreferences->currentCodeStyleSettings(); +} + +CppCodeStyleSettings CppCodeStyleSettings::currentGlobalCodeStyle() +{ + CppCodeStylePreferences *cppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle(); + QTC_ASSERT(cppCodeStylePreferences, return CppCodeStyleSettings()); + + return cppCodeStylePreferences->currentCodeStyleSettings(); } static void configureOverviewWithCodeStyleSettings(CPlusPlus::Overview &overview, @@ -207,37 +242,14 @@ static void configureOverviewWithCodeStyleSettings(CPlusPlus::Overview &overview CPlusPlus::Overview CppCodeStyleSettings::currentProjectCodeStyleOverview() { - ProjectExplorer::Project *project = ProjectExplorer::ProjectTree::currentProject(); - if (!project) - return currentGlobalCodeStyleOverview(); - - ProjectExplorer::EditorConfiguration *editorConfiguration = project->editorConfiguration(); - QTC_ASSERT(editorConfiguration, return currentGlobalCodeStyleOverview()); - - TextEditor::ICodeStylePreferences *codeStylePreferences - = editorConfiguration->codeStyle(Constants::CPP_SETTINGS_ID); - QTC_ASSERT(codeStylePreferences, return currentGlobalCodeStyleOverview()); - - CppCodeStylePreferences *cppCodeStylePreferences - = dynamic_cast(codeStylePreferences); - QTC_ASSERT(cppCodeStylePreferences, return currentGlobalCodeStyleOverview()); - - CppCodeStyleSettings settings = cppCodeStylePreferences->currentCodeStyleSettings(); - CPlusPlus::Overview overview; - configureOverviewWithCodeStyleSettings(overview, settings); + configureOverviewWithCodeStyleSettings(overview, currentProjectCodeStyle()); return overview; } CPlusPlus::Overview CppCodeStyleSettings::currentGlobalCodeStyleOverview() { CPlusPlus::Overview overview; - - CppCodeStylePreferences *cppCodeStylePreferences = CppToolsSettings::instance()->cppCodeStyle(); - QTC_ASSERT(cppCodeStylePreferences, return overview); - - CppCodeStyleSettings settings = cppCodeStylePreferences->currentCodeStyleSettings(); - - configureOverviewWithCodeStyleSettings(overview, settings); + configureOverviewWithCodeStyleSettings(overview, currentGlobalCodeStyle()); return overview; } diff --git a/src/plugins/cpptools/cppcodestylesettings.h b/src/plugins/cpptools/cppcodestylesettings.h index 60dcc2fbf60..f69d72d0ab8 100644 --- a/src/plugins/cpptools/cppcodestylesettings.h +++ b/src/plugins/cpptools/cppcodestylesettings.h @@ -80,6 +80,8 @@ public: // b bool alignAssignments; + bool preferGetterNameWithoutGetPrefix; + void toSettings(const QString &category, QSettings *s) const; void fromSettings(const QString &category, const QSettings *s); @@ -90,6 +92,9 @@ public: bool operator==(const CppCodeStyleSettings &s) const { return equals(s); } bool operator!=(const CppCodeStyleSettings &s) const { return !equals(s); } + static CppCodeStyleSettings currentProjectCodeStyle(); + static CppCodeStyleSettings currentGlobalCodeStyle(); + /*! Returns an Overview configured by the current project's code style. If no current project is available or an error occurs when getting the diff --git a/src/plugins/cpptools/cppcodestylesettingspage.cpp b/src/plugins/cpptools/cppcodestylesettingspage.cpp index 8af93ff100b..46d6ee69850 100644 --- a/src/plugins/cpptools/cppcodestylesettingspage.cpp +++ b/src/plugins/cpptools/cppcodestylesettingspage.cpp @@ -321,6 +321,8 @@ CppCodeStylePreferencesWidget::CppCodeStylePreferencesWidget(QWidget *parent) this, &CppCodeStylePreferencesWidget::slotCodeStyleSettingsChanged); connect(m_ui->bindStarToRightSpecifier, &QCheckBox::toggled, this, &CppCodeStylePreferencesWidget::slotCodeStyleSettingsChanged); + connect(m_ui->preferGetterNamesWithoutGet, &QCheckBox::toggled, + this, &CppCodeStylePreferencesWidget::slotCodeStyleSettingsChanged); m_ui->categoryTab->setCurrentIndex(0); @@ -380,6 +382,7 @@ CppCodeStyleSettings CppCodeStylePreferencesWidget::cppCodeStyleSettings() const set.bindStarToRightSpecifier = m_ui->bindStarToRightSpecifier->isChecked(); set.extraPaddingForConditionsIfConfusingAlign = m_ui->extraPaddingConditions->isChecked(); set.alignAssignments = m_ui->alignAssignments->isChecked(); + set.preferGetterNameWithoutGetPrefix = m_ui->preferGetterNamesWithoutGet->isChecked(); return set; } @@ -413,6 +416,7 @@ void CppCodeStylePreferencesWidget::setCodeStyleSettings(const CppCodeStyleSetti m_ui->bindStarToRightSpecifier->setChecked(s.bindStarToRightSpecifier); m_ui->extraPaddingConditions->setChecked(s.extraPaddingForConditionsIfConfusingAlign); m_ui->alignAssignments->setChecked(s.alignAssignments); + m_ui->preferGetterNamesWithoutGet->setChecked(s.preferGetterNameWithoutGetPrefix); m_blockUpdates = wasBlocked; if (preview) updatePreview(); diff --git a/src/plugins/cpptools/cppcodestylesettingspage.ui b/src/plugins/cpptools/cppcodestylesettingspage.ui index 0206b965497..99342596081 100644 --- a/src/plugins/cpptools/cppcodestylesettingspage.ui +++ b/src/plugins/cpptools/cppcodestylesettingspage.ui @@ -484,6 +484,33 @@ if they would align to the next line + + + Getter and Setter + + + + + + Prefer getter names without "get" + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + From eba6da37c65488f86c60ce3970f13b2b143c2a5a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 21 Jun 2016 16:33:48 +0200 Subject: [PATCH 05/20] Clang: Fix aliasing Task-number: QTCREATORBUG-15888 Change-Id: I0f2e28e9e0da53481c03707ab0a9abf728c7419f Reviewed-by: hjk Reviewed-by: Tim Jenssen --- .../clangbackendipc/clangbackendipc_global.h | 4 +-- .../cmbcodecompletedmessage.cpp | 13 +++++----- .../clangbackendipc/cmbcodecompletedmessage.h | 3 --- src/libs/clangbackendipc/codecompletion.cpp | 24 +++++++---------- src/libs/clangbackendipc/codecompletion.h | 4 --- .../clangbackendipc/codecompletionchunk.cpp | 13 +++++----- .../clangbackendipc/codecompletionchunk.h | 3 --- .../clangbackendipc/diagnosticcontainer.cpp | 13 +++++----- .../clangbackendipc/diagnosticcontainer.h | 3 --- .../highlightingmarkcontainer.cpp | 26 ++++++++++++++++--- src/libs/clangbackendipc/messageenvelop.h | 8 ++++-- 11 files changed, 58 insertions(+), 56 deletions(-) diff --git a/src/libs/clangbackendipc/clangbackendipc_global.h b/src/libs/clangbackendipc/clangbackendipc_global.h index 03b3493d70e..c19484e8106 100644 --- a/src/libs/clangbackendipc/clangbackendipc_global.h +++ b/src/libs/clangbackendipc/clangbackendipc_global.h @@ -43,7 +43,7 @@ namespace ClangBackEnd { -enum class DiagnosticSeverity // one to one mapping of the clang enum numbers +enum class DiagnosticSeverity : quint32 // one to one mapping of the clang enum numbers { Ignored = 0, Note = 1, @@ -75,7 +75,7 @@ enum class HighlightingType : quint8 Declaration }; -enum class CompletionCorrection +enum class CompletionCorrection : quint32 { NoCorrection, DotToArrowCorrection diff --git a/src/libs/clangbackendipc/cmbcodecompletedmessage.cpp b/src/libs/clangbackendipc/cmbcodecompletedmessage.cpp index ea857646f5e..3097585b388 100644 --- a/src/libs/clangbackendipc/cmbcodecompletedmessage.cpp +++ b/src/libs/clangbackendipc/cmbcodecompletedmessage.cpp @@ -56,15 +56,10 @@ quint64 CodeCompletedMessage::ticketNumber() const return ticketNumber_; } -quint32 &CodeCompletedMessage::neededCorrectionAsInt() -{ - return reinterpret_cast(neededCorrection_); -} - QDataStream &operator<<(QDataStream &out, const CodeCompletedMessage &message) { out << message.codeCompletions_; - out << quint32(message.neededCorrection_); + out << static_cast(message.neededCorrection_); out << message.ticketNumber_; return out; @@ -72,10 +67,14 @@ QDataStream &operator<<(QDataStream &out, const CodeCompletedMessage &message) QDataStream &operator>>(QDataStream &in, CodeCompletedMessage &message) { + quint32 neededCorrection; + in >> message.codeCompletions_; - in >> message.neededCorrectionAsInt(); + in >> neededCorrection; in >> message.ticketNumber_; + message.neededCorrection_ = static_cast(neededCorrection); + return in; } diff --git a/src/libs/clangbackendipc/cmbcodecompletedmessage.h b/src/libs/clangbackendipc/cmbcodecompletedmessage.h index 8fe9c5dbea8..d3cc6baf265 100644 --- a/src/libs/clangbackendipc/cmbcodecompletedmessage.h +++ b/src/libs/clangbackendipc/cmbcodecompletedmessage.h @@ -49,9 +49,6 @@ public: quint64 ticketNumber() const; -private: - quint32 &neededCorrectionAsInt(); - private: CodeCompletions codeCompletions_; quint64 ticketNumber_ = 0; diff --git a/src/libs/clangbackendipc/codecompletion.cpp b/src/libs/clangbackendipc/codecompletion.cpp index 8ad39d080e4..b043007bb97 100644 --- a/src/libs/clangbackendipc/codecompletion.cpp +++ b/src/libs/clangbackendipc/codecompletion.cpp @@ -115,24 +115,14 @@ const Utf8String &CodeCompletion::briefComment() const return briefComment_; } -quint32 &CodeCompletion::completionKindAsInt() -{ - return reinterpret_cast(completionKind_); -} - -quint32 &CodeCompletion::availabilityAsInt() -{ - return reinterpret_cast(availability_); -} - QDataStream &operator<<(QDataStream &out, const CodeCompletion &message) { out << message.text_; out << message.briefComment_; out << message.chunks_; out << message.priority_; - out << message.completionKind_; - out << message.availability_; + out << static_cast(message.completionKind_); + out << static_cast(message.availability_); out << message.hasParameters_; return out; @@ -140,14 +130,20 @@ QDataStream &operator<<(QDataStream &out, const CodeCompletion &message) QDataStream &operator>>(QDataStream &in, CodeCompletion &message) { + quint32 completionKind; + quint32 availability; + in >> message.text_; in >> message.briefComment_; in >> message.chunks_; in >> message.priority_; - in >> message.completionKindAsInt(); - in >> message.availabilityAsInt(); + in >> completionKind; + in >> availability; in >> message.hasParameters_; + message.completionKind_ = static_cast(completionKind); + message.availability_ = static_cast(availability); + return in; } diff --git a/src/libs/clangbackendipc/codecompletion.h b/src/libs/clangbackendipc/codecompletion.h index ec8984a89ac..114d7c54890 100644 --- a/src/libs/clangbackendipc/codecompletion.h +++ b/src/libs/clangbackendipc/codecompletion.h @@ -103,10 +103,6 @@ public: void setBriefComment(const Utf8String &briefComment); const Utf8String &briefComment() const; -private: - quint32 &completionKindAsInt(); - quint32 &availabilityAsInt(); - private: Utf8String text_; Utf8String briefComment_; diff --git a/src/libs/clangbackendipc/codecompletionchunk.cpp b/src/libs/clangbackendipc/codecompletionchunk.cpp index 7e1cb790133..1211b2cf1bb 100644 --- a/src/libs/clangbackendipc/codecompletionchunk.cpp +++ b/src/libs/clangbackendipc/codecompletionchunk.cpp @@ -56,14 +56,9 @@ bool CodeCompletionChunk::isOptional() const return isOptional_; } -quint8 &CodeCompletionChunk::kindAsInt() -{ - return reinterpret_cast(kind_); -} - QDataStream &operator<<(QDataStream &out, const CodeCompletionChunk &chunk) { - out << quint8(chunk.kind_); + out << static_cast(chunk.kind_); out << chunk.text_; out << chunk.isOptional_; @@ -72,10 +67,14 @@ QDataStream &operator<<(QDataStream &out, const CodeCompletionChunk &chunk) QDataStream &operator>>(QDataStream &in, CodeCompletionChunk &chunk) { - in >> chunk.kindAsInt(); + quint8 kind; + + in >> kind; in >> chunk.text_; in >> chunk.isOptional_; + chunk.kind_ = static_cast(kind); + return in; } diff --git a/src/libs/clangbackendipc/codecompletionchunk.h b/src/libs/clangbackendipc/codecompletionchunk.h index 897e9f222a9..d004181cf9d 100644 --- a/src/libs/clangbackendipc/codecompletionchunk.h +++ b/src/libs/clangbackendipc/codecompletionchunk.h @@ -77,9 +77,6 @@ public: const Utf8String &text() const; bool isOptional() const; -private: - quint8 &kindAsInt(); - private: Utf8String text_; Kind kind_ = Invalid; diff --git a/src/libs/clangbackendipc/diagnosticcontainer.cpp b/src/libs/clangbackendipc/diagnosticcontainer.cpp index 1161a773265..b7bf9d9d09e 100644 --- a/src/libs/clangbackendipc/diagnosticcontainer.cpp +++ b/src/libs/clangbackendipc/diagnosticcontainer.cpp @@ -97,11 +97,6 @@ const QVector &DiagnosticContainer::children() const return children_; } -quint32 &DiagnosticContainer::severityAsInt() -{ - return reinterpret_cast(severity_); -} - QDataStream &operator<<(QDataStream &out, const DiagnosticContainer &container) { out << container.text_; @@ -109,7 +104,7 @@ QDataStream &operator<<(QDataStream &out, const DiagnosticContainer &container) out << container.enableOption_; out << container.disableOption_; out << container.location_; - out << quint32(container.severity_); + out << static_cast(container.severity_); out << container.ranges_; out << container.fixIts_; out << container.children_; @@ -119,16 +114,20 @@ QDataStream &operator<<(QDataStream &out, const DiagnosticContainer &container) QDataStream &operator>>(QDataStream &in, DiagnosticContainer &container) { + quint32 severity; + in >> container.text_; in >> container.category_; in >> container.enableOption_; in >> container.disableOption_; in >> container.location_; - in >> container.severityAsInt(); + in >> severity; in >> container.ranges_; in >> container.fixIts_; in >> container.children_; + container.severity_ = static_cast(severity); + return in; } diff --git a/src/libs/clangbackendipc/diagnosticcontainer.h b/src/libs/clangbackendipc/diagnosticcontainer.h index b1192f393bd..a44efbabcbb 100644 --- a/src/libs/clangbackendipc/diagnosticcontainer.h +++ b/src/libs/clangbackendipc/diagnosticcontainer.h @@ -61,9 +61,6 @@ public: const QVector &fixIts() const; const QVector &children() const; -private: - quint32 &severityAsInt(); - private: SourceLocationContainer location_; QVector ranges_; diff --git a/src/libs/clangbackendipc/highlightingmarkcontainer.cpp b/src/libs/clangbackendipc/highlightingmarkcontainer.cpp index 441bc5203de..2678bc4d43c 100644 --- a/src/libs/clangbackendipc/highlightingmarkcontainer.cpp +++ b/src/libs/clangbackendipc/highlightingmarkcontainer.cpp @@ -74,14 +74,21 @@ HighlightingTypes HighlightingMarkContainer::types() const return types_; } +QDataStream &operator<<(QDataStream &out, HighlightingType highlightingType) +{ + out << static_cast(highlightingType); + + return out; +} + QDataStream &operator<<(QDataStream &out, HighlightingTypes highlightingTypes) { - out << reinterpret_cast(highlightingTypes.mainHighlightingType); + out << highlightingTypes.mainHighlightingType; out << highlightingTypes.mixinHighlightingTypes.size(); for (HighlightingType type : highlightingTypes.mixinHighlightingTypes) - out << reinterpret_cast(type); + out << type; return out; } @@ -96,16 +103,27 @@ QDataStream &operator<<(QDataStream &out, const HighlightingMarkContainer &conta return out; } +QDataStream &operator>>(QDataStream &in, HighlightingType &highlightingType) +{ + quint8 highlightingTypeInt; + + in >> highlightingTypeInt; + + highlightingType = static_cast(highlightingTypeInt); + + return in; +} + QDataStream &operator>>(QDataStream &in, HighlightingTypes &highlightingTypes) { - in >> reinterpret_cast(highlightingTypes.mainHighlightingType); + in >> highlightingTypes.mainHighlightingType ; quint8 size; in >> size; for (int counter = 0; counter < size; ++counter) { HighlightingType type; - in >> reinterpret_cast(type); + in >> type; highlightingTypes.mixinHighlightingTypes.push_back(type); } diff --git a/src/libs/clangbackendipc/messageenvelop.h b/src/libs/clangbackendipc/messageenvelop.h index 008a4c00372..0f4d18d5228 100644 --- a/src/libs/clangbackendipc/messageenvelop.h +++ b/src/libs/clangbackendipc/messageenvelop.h @@ -79,7 +79,7 @@ public: friend QDataStream &operator<<(QDataStream &out, const MessageEnvelop &messageEnvelop) { - out << reinterpret_cast(messageEnvelop.messageType_); + out << static_cast(messageEnvelop.messageType_); out << messageEnvelop.data; return out; @@ -88,9 +88,13 @@ public: friend QDataStream &operator>>(QDataStream &in, MessageEnvelop &messageEnvelop) { - in >> reinterpret_cast(messageEnvelop.messageType_); + quint8 messageType; + + in >> messageType; in >> messageEnvelop.data; + messageEnvelop.messageType_ = static_cast(messageType); + return in; } From c8ef91f7892c3c12ddd92d7ca5b4bdc9936c7f07 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 15 Jun 2016 07:56:24 +0200 Subject: [PATCH 06/20] Revert "TextEditor: Do not delete both quotes on backspace" We have a more intelligent placing of double quotes, that should eliminate some of the incorrect/unwanted placed closing quotes. Additionally we introduced an animation and highlight of automatically inserted text. So it should be definitely clear that the closing quote is going to be removed. If there is still someone who gets annoyed by this reintroduced behavior there is now a setting that lets you control the deletion of automatically inserted text. So it is safe to reintroduce the deletion of closing quotes on backspace. This reverts commit 4a0b2039c0ed5c1f34efaf8f53dcf04ad9f384df. Change-Id: I92500ac218dc4c2e07a3b0ad01b06e6baa2e2c6c Reviewed-by: Eike Ziller --- src/plugins/texteditor/autocompleter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp index 1cc4a9ee561..4a5d502801c 100644 --- a/src/plugins/texteditor/autocompleter.cpp +++ b/src/plugins/texteditor/autocompleter.cpp @@ -212,6 +212,7 @@ bool AutoCompleter::autoBackspace(QTextCursor &cursor) QTextDocument *doc = cursor.document(); const QChar lookAhead = doc->characterAt(pos); const QChar lookBehind = doc->characterAt(pos - 1); + const QChar lookFurtherBehind = doc->characterAt(pos - 2); const QChar character = lookBehind; if (character == QLatin1Char('(') || character == QLatin1Char('[')) { @@ -240,7 +241,11 @@ bool AutoCompleter::autoBackspace(QTextCursor &cursor) // ### this code needs to be generalized if ((lookBehind == QLatin1Char('(') && lookAhead == QLatin1Char(')')) - || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']'))) { + || (lookBehind == QLatin1Char('[') && lookAhead == QLatin1Char(']')) + || (lookBehind == QLatin1Char('"') && lookAhead == QLatin1Char('"') + && lookFurtherBehind != QLatin1Char('\\')) + || (lookBehind == QLatin1Char('\'') && lookAhead == QLatin1Char('\'') + && lookFurtherBehind != QLatin1Char('\\'))) { if (! isInComment(c)) { cursor.beginEditBlock(); cursor.deleteChar(); From c0f3094866923f27692e654f94cd55546f5c87d5 Mon Sep 17 00:00:00 2001 From: Philip Lorenz Date: Tue, 22 Sep 2015 23:21:08 +0200 Subject: [PATCH 07/20] C++: Fix lexing of >> / >>= The current code always ends up setting the token to T_GREATER_GREATER. Change-Id: If75ff1f5bccffd5918ec2bf491724cd0981220ae Reviewed-by: Nikolai Kosjar Reviewed-by: Orgad Shaneh --- src/libs/3rdparty/cplusplus/Lexer.cpp | 6 +- tests/auto/cplusplus/lexer/tst_lexer.cpp | 79 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/libs/3rdparty/cplusplus/Lexer.cpp b/src/libs/3rdparty/cplusplus/Lexer.cpp index feddf3a5d07..efaaaf91659 100644 --- a/src/libs/3rdparty/cplusplus/Lexer.cpp +++ b/src/libs/3rdparty/cplusplus/Lexer.cpp @@ -630,9 +630,9 @@ void Lexer::scan_helper(Token *tok) if (_yychar == '=') { yyinp(); tok->f.kind = T_GREATER_GREATER_EQUAL; - } else - tok->f.kind = T_LESS_LESS; - tok->f.kind = T_GREATER_GREATER; + } else { + tok->f.kind = T_GREATER_GREATER; + } } else if (_yychar == '=') { yyinp(); tok->f.kind = T_GREATER_EQUAL; diff --git a/tests/auto/cplusplus/lexer/tst_lexer.cpp b/tests/auto/cplusplus/lexer/tst_lexer.cpp index 92115bc05c6..ecbd0f4ace9 100644 --- a/tests/auto/cplusplus/lexer/tst_lexer.cpp +++ b/tests/auto/cplusplus/lexer/tst_lexer.cpp @@ -38,6 +38,7 @@ typedef QByteArray _; Q_DECLARE_METATYPE(TokenKindList) Q_DECLARE_METATYPE(CPlusPlus::Tokens) +Q_DECLARE_METATYPE(CPlusPlus::Kind) //TESTED_COMPONENT=src/libs/cplusplus using namespace CPlusPlus; @@ -70,6 +71,8 @@ private slots: void literals_data(); void preprocessor(); void preprocessor_data(); + void ppOpOrPunc(); + void ppOpOrPunc_data(); void digraph(); void digraph_data(); void trigraph(); @@ -395,6 +398,82 @@ void tst_SimpleLexer::preprocessor_data() QTest::newRow("pp-number") << source << expectedTokenKindList; } +void tst_SimpleLexer::ppOpOrPunc() +{ + QFETCH(Kind, expectedTokenKind); + + const QByteArray source = QTest::currentDataTag(); + run(source, toTokens({expectedTokenKind}), false, CompareKind, true); +} + +void tst_SimpleLexer::ppOpOrPunc_data() +{ + QTest::addColumn("expectedTokenKind"); + + // N4296 - [2.12] + QTest::newRow("{") << T_LBRACE; + QTest::newRow("}") << T_RBRACE; + QTest::newRow("[") << T_LBRACKET; + QTest::newRow("]") << T_RBRACKET; + QTest::newRow("#") << T_POUND; + QTest::newRow("##") << T_POUND_POUND; + QTest::newRow("(") << T_LPAREN; + QTest::newRow(")") << T_RPAREN; + QTest::newRow("<:") << T_LBRACKET; + QTest::newRow(":>") << T_RBRACKET; + QTest::newRow("<%") << T_LBRACE; + QTest::newRow("%>") << T_RBRACE; + QTest::newRow("%:") << T_POUND; + QTest::newRow("%:%:") << T_POUND_POUND; + QTest::newRow(";") << T_SEMICOLON; + QTest::newRow(":") << T_COLON; + QTest::newRow("...") << T_DOT_DOT_DOT; + QTest::newRow("new") << T_NEW; + QTest::newRow("delete") << T_DELETE; + QTest::newRow("?") << T_QUESTION; + QTest::newRow("::") << T_COLON_COLON; + QTest::newRow(".") << T_DOT; + QTest::newRow(".*") << T_DOT_STAR; + QTest::newRow("+") << T_PLUS; + QTest::newRow("-") << T_MINUS; + QTest::newRow("*") << T_STAR; + QTest::newRow("/") << T_SLASH; + QTest::newRow("%") << T_PERCENT; + QTest::newRow("^") << T_CARET; + QTest::newRow("&") << T_AMPER; + QTest::newRow("|") << T_PIPE; + QTest::newRow("~") << T_TILDE; + QTest::newRow("^=") << T_CARET_EQUAL; + QTest::newRow("&=") << T_AMPER_EQUAL; + QTest::newRow("|=") << T_PIPE_EQUAL; + QTest::newRow("<<") << T_LESS_LESS; + QTest::newRow(">>") << T_GREATER_GREATER; + QTest::newRow(">>=") << T_GREATER_GREATER_EQUAL; + QTest::newRow("<<=") << T_LESS_LESS_EQUAL; + QTest::newRow("==") << T_EQUAL_EQUAL; + QTest::newRow("!=") << T_EXCLAIM_EQUAL; + QTest::newRow("<=") << T_LESS_EQUAL; + QTest::newRow(">=") << T_GREATER_EQUAL; + QTest::newRow("&&") << T_AMPER_AMPER; + QTest::newRow("||") << T_PIPE_PIPE; + QTest::newRow("++") << T_PLUS_PLUS; + QTest::newRow("--") << T_MINUS_MINUS; + QTest::newRow(",") << T_COMMA; + QTest::newRow("->*") << T_ARROW_STAR; + QTest::newRow("->") << T_ARROW; + QTest::newRow("and") << T_AND; + QTest::newRow("and_eq") << T_AND_EQ; + QTest::newRow("bitand") << T_BITAND; + QTest::newRow("bitor") << T_BITOR; + QTest::newRow("compl") << T_COMPL; + QTest::newRow("not") << T_NOT; + QTest::newRow("not_eq") << T_NOT_EQ; + QTest::newRow("or") << T_OR; + QTest::newRow("or_eq") << T_OR_EQ; + QTest::newRow("xor") << T_XOR; + QTest::newRow("xor_eq") << T_XOR_EQ; +} + void tst_SimpleLexer::bytes_and_utf16chars() { QFETCH(QByteArray, source); From 43075f5fb165e764f11abd35c4cc06cbda969a20 Mon Sep 17 00:00:00 2001 From: Dmitry Ashkadov Date: Thu, 13 Nov 2014 22:18:53 +0300 Subject: [PATCH 08/20] C++: Add support of ref-qualifier for functions. Now the ref-qualifier (& or &&) of the function declaration is propagated to GUI. For example, 'Refactor' -> 'Add Definition' preserves the ref-qualifier. Change-Id: I8ac4e1cad4e44985e94230aabbd9858a7e929fee Reviewed-by: Nikolai Kosjar Reviewed-by: Orgad Shaneh --- src/libs/3rdparty/cplusplus/Bind.cpp | 8 ++ src/libs/3rdparty/cplusplus/Symbols.cpp | 6 + src/libs/3rdparty/cplusplus/Symbols.h | 10 ++ src/libs/cplusplus/CppRewriter.cpp | 1 + src/libs/cplusplus/TypePrettyPrinter.cpp | 11 ++ .../auto/cplusplus/semantic/tst_semantic.cpp | 105 ++++++++++++++++++ .../tst_typeprettyprinter.cpp | 35 ++++++ 7 files changed, 176 insertions(+) diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index d8f9861e7d2..a97c71ec5c6 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -3255,6 +3255,14 @@ bool Bind::visit(FunctionDeclaratorAST *ast) fun->setOverride(type.isOverride()); fun->setFinal(type.isFinal()); + // propagate ref-qualifier + if (ast->ref_qualifier_token) { + const Kind kind = tokenAt(ast->ref_qualifier_token).kind(); + CPP_CHECK(kind == T_AMPER || kind == T_AMPER_AMPER); // & or && are only allowed + fun->setRefQualifier(kind == T_AMPER ? Function::LvalueRefQualifier : + Function::RvalueRefQualifier); + } + this->exceptionSpecification(ast->exception_specification, type); if (ast->as_cpp_initializer != 0) { fun->setAmbiguous(true); diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp index f8a8440c097..6a69ca2dc4e 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.cpp +++ b/src/libs/3rdparty/cplusplus/Symbols.cpp @@ -367,6 +367,12 @@ bool Function::isPureVirtual() const void Function::setPureVirtual(bool isPureVirtual) { f._isPureVirtual = isPureVirtual; } +Function::RefQualifier Function::refQualifier() const +{ return static_cast(f._refQualifier); } + +void Function::setRefQualifier(Function::RefQualifier refQualifier) +{ f._refQualifier = refQualifier; } + bool Function::isAmbiguous() const { return f._isAmbiguous; } diff --git a/src/libs/3rdparty/cplusplus/Symbols.h b/src/libs/3rdparty/cplusplus/Symbols.h index 826c816b690..a545644cfa7 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.h +++ b/src/libs/3rdparty/cplusplus/Symbols.h @@ -298,6 +298,12 @@ public: InvokableMethod }; + enum RefQualifier { + NoRefQualifier, // a function declared w/o & and && => *this may be lvalue or rvalue + LvalueRefQualifier, // a function declared with & => *this is lvalue + RvalueRefQualifier // a function declared with && => *this is rvalue + }; + public: Function(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name); Function(Clone *clone, Subst *subst, Function *original); @@ -344,6 +350,9 @@ public: bool isPureVirtual() const; void setPureVirtual(bool isPureVirtual); + RefQualifier refQualifier() const; + void setRefQualifier(RefQualifier refQualifier); + bool isSignatureEqualTo(const Function *other, Matcher *matcher = 0) const; bool isAmbiguous() const; // internal @@ -384,6 +393,7 @@ private: unsigned _isVolatile: 1; unsigned _isAmbiguous: 1; unsigned _methodKey: 3; + unsigned _refQualifier: 2; }; union { unsigned _flags; diff --git a/src/libs/cplusplus/CppRewriter.cpp b/src/libs/cplusplus/CppRewriter.cpp index 4a7325a6c48..1ce9cc2dfa7 100644 --- a/src/libs/cplusplus/CppRewriter.cpp +++ b/src/libs/cplusplus/CppRewriter.cpp @@ -135,6 +135,7 @@ public: funTy->copy(type); funTy->setConst(type->isConst()); funTy->setVolatile(type->isVolatile()); + funTy->setRefQualifier(type->refQualifier()); funTy->setName(rewrite->rewriteName(type->name())); diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp index 282deb830e2..e3693f17a05 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.cpp +++ b/src/libs/cplusplus/TypePrettyPrinter.cpp @@ -454,6 +454,17 @@ void TypePrettyPrinter::visit(Function *type) appendSpace(); _text += QLatin1String("volatile"); } + + // add ref-qualifier + if (type->refQualifier() != Function::NoRefQualifier) { + if (!_overview->starBindFlags.testFlag(Overview::BindToLeftSpecifier) + || (!type->isConst() && !type->isVolatile())) { + appendSpace(); + } + _text += type->refQualifier() == Function::LvalueRefQualifier + ? QLatin1String("&") + : QLatin1String("&&"); + } } } diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index ff0f6bc58c2..b7a4c161cf2 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -50,6 +50,9 @@ using namespace CPlusPlus; +// to use in tests directly w/o convertion to int +Q_DECLARE_METATYPE(Function::RefQualifier) + class tst_Semantic: public QObject { Q_OBJECT @@ -150,6 +153,8 @@ public: private slots: void function_declaration_1(); void function_declaration_2(); + void function_declaration_ref_qualifier_data(); + void function_declaration_ref_qualifier(); void function_definition_1(); void nested_class_1(); void alias_declaration_1(); @@ -202,6 +207,7 @@ void tst_Semantic::function_declaration_1() QVERIFY(funTy); QVERIFY(funTy->returnType()->isVoidType()); QCOMPARE(funTy->argumentCount(), 0U); + QCOMPARE(funTy->refQualifier(), Function::NoRefQualifier); QVERIFY(decl->name()->isNameId()); const Identifier *funId = decl->name()->asNameId()->identifier(); @@ -225,6 +231,7 @@ void tst_Semantic::function_declaration_2() QVERIFY(funTy); QVERIFY(funTy->returnType()->isVoidType()); QCOMPARE(funTy->argumentCount(), 1U); + QCOMPARE(funTy->refQualifier(), Function::NoRefQualifier); // check the formal argument. Argument *arg = funTy->argumentAt(0)->asArgument(); @@ -261,6 +268,103 @@ void tst_Semantic::function_declaration_2() QCOMPARE(foo, QByteArray("foo")); } +void tst_Semantic::function_declaration_ref_qualifier_data() +{ + QTest::addColumn("code"); + QTest::addColumn("success"); + QTest::addColumn("refQualifier"); + + QTest::newRow("no") + << "void f();" << true << Function::NoRefQualifier; + + QTest::newRow("no_const") + << "void f() const;" << true << Function::NoRefQualifier; + + QTest::newRow("no_const_noexcept") + << "void f() const noexcept;" << true << Function::NoRefQualifier; + + QTest::newRow("lvalue") + << "void f() &;" << true << Function::LvalueRefQualifier; + + QTest::newRow("lvalue_const") + << "void f() const &;" << true << Function::LvalueRefQualifier; + + QTest::newRow("lvalue_const_noexcept") + << "void f() const & noexcept;" << true << Function::LvalueRefQualifier; + + QTest::newRow("rvalue") + << "void f() &&;" << true << Function::RvalueRefQualifier; + + QTest::newRow("rvalue_const") + << "void f() const &&;" << true << Function::RvalueRefQualifier; + + QTest::newRow("rvalue_const_noexcept") + << "void f() const && noexcept;" << true << Function::RvalueRefQualifier; + + QTest::newRow("lvalue_more_spaces") + << "void f() const &;" << true << Function::LvalueRefQualifier; + + QTest::newRow("rvalue_more_spaces") + << "void f() && noexcept;" << true << Function::RvalueRefQualifier; + + QTest::newRow("lvalue_more_newline") + << "void f() const\n&;" << true << Function::LvalueRefQualifier; + + QTest::newRow("rvalue_more_newline") + << "void f() const\n&&;" << true << Function::RvalueRefQualifier; + + QTest::newRow("lvalue_no_space") + << "void f() const& noexcept;" << true << Function::LvalueRefQualifier; + + QTest::newRow("rvalue_no_space") + << "void f() const&& noexcept;" << true << Function::RvalueRefQualifier; + + QTest::newRow("lvalue_before_const") + << "void f() & const;" << false << Function::NoRefQualifier; + + QTest::newRow("rvalue_before_const") + << "void f() && const;" << false << Function::NoRefQualifier; + + QTest::newRow("lvalue_after_noexcept") + << "void f() const noexcept &;" << false << Function::NoRefQualifier; + + QTest::newRow("rvalue_after_noexcept") + << "void f() const noexcept &&;" << false << Function::NoRefQualifier; + + QTest::newRow("lvalue_double") + << "void f() const & & noexcept;" << false << Function::NoRefQualifier; + + QTest::newRow("rvalue_double") + << "void f() const && && noexcept;" << false << Function::NoRefQualifier; +} + +void tst_Semantic::function_declaration_ref_qualifier() +{ + QFETCH(QString, code); + QFETCH(bool, success); + QFETCH(Function::RefQualifier, refQualifier); + + QSharedPointer doc = document(code.toUtf8(), false, false, true); + if (!success) { + QVERIFY(doc->errorCount > 0); + return; + } + QCOMPARE(doc->errorCount, 0U); + QCOMPARE(doc->globals->memberCount(), 1U); + + Declaration *decl = doc->globals->memberAt(0)->asDeclaration(); + QVERIFY(decl); + + FullySpecifiedType declTy = decl->type(); + Function *funTy = declTy->asFunctionType(); + QVERIFY(funTy); + QVERIFY(funTy->returnType()->isVoidType()); + QCOMPARE(funTy->argumentCount(), 0U); + + // check the ref-qualifier + QCOMPARE(funTy->refQualifier(), refQualifier); +} + void tst_Semantic::function_definition_1() { QSharedPointer doc = document("void foo() {}"); @@ -271,6 +375,7 @@ void tst_Semantic::function_definition_1() QVERIFY(funTy); QVERIFY(funTy->returnType()->isVoidType()); QCOMPARE(funTy->argumentCount(), 0U); + QCOMPARE(funTy->refQualifier(), Function::NoRefQualifier); QVERIFY(funTy->name()->isNameId()); const Identifier *funId = funTy->name()->asNameId()->identifier(); diff --git a/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp b/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp index 11b08e30dc8..a028f9afece 100644 --- a/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp +++ b/tests/auto/cplusplus/typeprettyprinter/tst_typeprettyprinter.cpp @@ -93,6 +93,33 @@ static FullySpecifiedType fnTy(const QString &name, const FullySpecifiedType &re return FullySpecifiedType(fn); } +static FullySpecifiedType refThis(const FullySpecifiedType &type) +{ + FullySpecifiedType result(type); + Function *f = dynamic_cast(result.type()); + Q_ASSERT(f); + f->setRefQualifier(Function::LvalueRefQualifier); + return result; +} + +static FullySpecifiedType rrefThis(const FullySpecifiedType &type) +{ + FullySpecifiedType result(type); + Function *function = dynamic_cast(result.type()); + Q_ASSERT(function); + function->setRefQualifier(Function::RvalueRefQualifier); + return result; +} + +static FullySpecifiedType cnstThis(const FullySpecifiedType &type) +{ + FullySpecifiedType result(type); + Function *function = dynamic_cast(result.type()); + Q_ASSERT(function); + function->setConst(true); + return result; +} + static FullySpecifiedType ptr(const FullySpecifiedType &el) { return FullySpecifiedType(new PointerType(el)); } @@ -166,6 +193,14 @@ void tst_TypePrettyPrinter::basic_data() addRow(fnTy("foo", voidTy(), intTy()), bindToNothing, "void foo(int)", "foo"); addRow(fnTy("foo", voidTy(), intTy()), bindToAll, "void foo(int)", "foo"); + addRow(refThis(fnTy("foo", voidTy())), bindToNothing, "void foo() &", "foo"); + addRow(rrefThis(fnTy("foo", voidTy())), bindToNothing, "void foo() &&", "foo"); + addRow(refThis(fnTy("foo", voidTy())), bindToAll, "void foo() &", "foo"); + addRow(rrefThis(fnTy("foo", voidTy())), bindToAll, "void foo() &&", "foo"); + addRow(cnstThis(refThis(fnTy("foo", voidTy()))), bindToNothing, "void foo() const &", "foo"); + addRow(cnstThis(rrefThis(fnTy("foo", voidTy()))), bindToNothing, "void foo() const &&", "foo"); + addRow(cnstThis(refThis(fnTy("foo", voidTy()))), bindToAll, "void foo() const&", "foo"); + addRow(cnstThis(rrefThis(fnTy("foo", voidTy()))), bindToAll, "void foo() const&&", "foo"); // Pointers to functions and arrays are also excluded. It seems to be quite unusal to have // a space there. From 74fed1d5b779a0bd21c9d94ddcebc8f70fb48d93 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Jun 2016 15:14:04 -0700 Subject: [PATCH 09/20] Fix build on PPC: PPC is defined to 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit $ powerpc-poky-linux-gcc -dM -E -xc /dev/null | grep -i PPC #define _ARCH_PPC 1 #define __PPC__ 1 #define __PPC 1 #define PPC 1 Not on PPC64, though (only __PPC__ and __PPC64__ are defined). Change-Id: Ib57b52598e2f452985e9fffd145812f5098e441d Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Orgad Shaneh Reviewed-by: Tobias Hunger --- src/plugins/qmakeprojectmanager/makefileparse.cpp | 4 ++-- src/plugins/qmakeprojectmanager/qmakestep.cpp | 8 ++++---- src/plugins/qmakeprojectmanager/qmakestep.h | 2 +- tests/manual/shootout/tst_codesize.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/makefileparse.cpp b/src/plugins/qmakeprojectmanager/makefileparse.cpp index a52f22c3d4c..8b63e87f47c 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.cpp +++ b/src/plugins/qmakeprojectmanager/makefileparse.cpp @@ -167,12 +167,12 @@ void MakeFileParse::parseAssignments(QList *assignments) m_config.archConfig = QMakeStepConfig::NoArch; } else if (value == QLatin1String("ppc")) { if (qa.op == QLatin1String("+=")) - m_config.archConfig = QMakeStepConfig::PPC; + m_config.archConfig = QMakeStepConfig::PowerPC; else m_config.archConfig = QMakeStepConfig::NoArch; } else if (value == QLatin1String("ppc64")) { if (qa.op == QLatin1String("+=")) - m_config.archConfig = QMakeStepConfig::PPC64; + m_config.archConfig = QMakeStepConfig::PowerPC64; else m_config.archConfig = QMakeStepConfig::NoArch; } else if (value == QLatin1String("iphonesimulator")) { diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 681b54f44a4..f067018960a 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -888,9 +888,9 @@ QMakeStepConfig::TargetArchConfig QMakeStepConfig::targetArchFor(const Abi &targ arch = QMakeStepConfig::X86_64; } else if (targetAbi.architecture() == ProjectExplorer::Abi::PowerPCArchitecture) { if (targetAbi.wordWidth() == 32) - arch = QMakeStepConfig::PPC; + arch = QMakeStepConfig::PowerPC; else if (targetAbi.wordWidth() == 64) - arch = QMakeStepConfig::PPC64; + arch = QMakeStepConfig::PowerPC64; } } return arch; @@ -920,9 +920,9 @@ QStringList QMakeStepConfig::toArguments() const arguments << QLatin1String("CONFIG+=x86"); else if (archConfig == X86_64) arguments << QLatin1String("CONFIG+=x86_64"); - else if (archConfig == PPC) + else if (archConfig == PowerPC) arguments << QLatin1String("CONFIG+=ppc"); - else if (archConfig == PPC64) + else if (archConfig == PowerPC64) arguments << QLatin1String("CONFIG+=ppc64"); // TODO: make that depend on the actual Qt version that is used diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index 08e20e24ce1..bc1d969ca68 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -71,7 +71,7 @@ class QMAKEPROJECTMANAGER_EXPORT QMakeStepConfig { public: enum TargetArchConfig { - NoArch, X86, X86_64, PPC, PPC64 + NoArch, X86, X86_64, PowerPC, PowerPC64 }; enum OsType { diff --git a/tests/manual/shootout/tst_codesize.cpp b/tests/manual/shootout/tst_codesize.cpp index 02762d879de..630053987f1 100644 --- a/tests/manual/shootout/tst_codesize.cpp +++ b/tests/manual/shootout/tst_codesize.cpp @@ -360,7 +360,7 @@ void tst_CodeSize::codesize_data() QByteArray std_tie_code = "struct QMakeStepConfig\n" "{\n" - " enum TargetArchConfig { NoArch, X86, X86_64, PPC, PPC64 };\n" + " enum TargetArchConfig { NoArch, X86, X86_64, PowerPC, PowerPC64 };\n" " enum OsType { NoOsType, IphoneSimulator, IphoneOS };\n" "\n" " QMakeStepConfig()\n" From 88819d0490c93ddc4628878a1d66cd3f6a6ed26c Mon Sep 17 00:00:00 2001 From: Takumi ASAKI Date: Wed, 1 Jun 2016 16:42:05 +0900 Subject: [PATCH 10/20] Beautifier: Fix untranslated DISPLAY_NAME Change-Id: Ifad91eaada5f7614767b6332a643723de79fc6b2 Reviewed-by: Lorenz Haas Reviewed-by: David Schulz --- src/plugins/beautifier/artisticstyle/artisticstyle.cpp | 4 ++-- .../beautifier/artisticstyle/artisticstyleconstants.h | 4 +++- .../beautifier/artisticstyle/artisticstyleoptionspage.cpp | 3 ++- src/plugins/beautifier/beautifierplugin.cpp | 2 +- src/plugins/beautifier/clangformat/clangformat.cpp | 2 +- src/plugins/beautifier/clangformat/clangformatconstants.h | 4 +++- src/plugins/beautifier/uncrustify/uncrustify.cpp | 6 +++--- src/plugins/beautifier/uncrustify/uncrustifyconstants.h | 4 +++- src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp | 3 ++- 9 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp index 90d22d33b3b..7cac510c11e 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp @@ -69,7 +69,7 @@ ArtisticStyle::~ArtisticStyle() bool ArtisticStyle::initialize() { Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::ArtisticStyle::MENU_ID); - menu->menu()->setTitle(Constants::ArtisticStyle::DISPLAY_NAME); + menu->menu()->setTitle(tr(Constants::ArtisticStyle::DISPLAY_NAME)); m_formatFile = new QAction(BeautifierPlugin::msgFormatCurrentFile(), this); menu->addAction(Core::ActionManager::registerAction(m_formatFile, @@ -104,7 +104,7 @@ void ArtisticStyle::formatFile() const QString cfgFileName = configurationFile(); if (cfgFileName.isEmpty()) { BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile( - Constants::ArtisticStyle::DISPLAY_NAME)); + tr(Constants::ArtisticStyle::DISPLAY_NAME))); } else { m_beautifierPlugin->formatCurrentFile(command(cfgFileName)); } diff --git a/src/plugins/beautifier/artisticstyle/artisticstyleconstants.h b/src/plugins/beautifier/artisticstyle/artisticstyleconstants.h index fc2948c8ae4..3916cfa4366 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyleconstants.h +++ b/src/plugins/beautifier/artisticstyle/artisticstyleconstants.h @@ -25,11 +25,13 @@ #pragma once +#include + namespace Beautifier { namespace Constants { namespace ArtisticStyle { -const char DISPLAY_NAME[] = "Artistic Style"; +const char DISPLAY_NAME[] = QT_TRANSLATE_NOOP("Beautifier::Internal::ArtisticStyle::ArtisticStyle", "Artistic Style"); const char ACTION_FORMATFILE[] = "ArtisticStyle.FormatFile"; const char MENU_ID[] = "ArtisticStyle.Menu"; const char OPTION_ID[] = "ArtisticStyle"; diff --git a/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp b/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp index c578c62db2e..dffc7cc5e36 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstyleoptionspage.cpp @@ -28,6 +28,7 @@ #include "artisticstyleconstants.h" #include "artisticstylesettings.h" +#include "artisticstyle.h" #include "../beautifierconstants.h" #include "../beautifierplugin.h" @@ -49,7 +50,7 @@ ArtisticStyleOptionsPageWidget::ArtisticStyleOptionsPageWidget(ArtisticStyleSett "HOME", QDir::toNativeSeparators(QDir::home().absolutePath()))); ui->command->setExpectedKind(Utils::PathChooser::ExistingCommand); ui->command->setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle( - Constants::ArtisticStyle::DISPLAY_NAME)); + ArtisticStyle::tr(Constants::ArtisticStyle::DISPLAY_NAME))); connect(ui->command, &Utils::PathChooser::validChanged, ui->options, &QWidget::setEnabled); ui->configurations->setSettings(m_settings); } diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index d16af095d02..ee9bbf650f3 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -101,7 +101,7 @@ FormatTask format(FormatTask task) process.setTimeoutS(5); Utils::SynchronousProcessResponse response = process.runBlocking(executable, options); if (response.result != Utils::SynchronousProcessResponse::Finished) { - task.error = QObject::tr("Failed to format: %1.").arg(response.exitMessage(executable, 5)); + task.error = BeautifierPlugin::tr("Failed to format: %1.").arg(response.exitMessage(executable, 5)); return task; } const QString output = response.stdErr; diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index dd01cbadff6..efc7c73399d 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -73,7 +73,7 @@ QString ClangFormat::id() const bool ClangFormat::initialize() { Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::ClangFormat::MENU_ID); - menu->menu()->setTitle(Constants::ClangFormat::DISPLAY_NAME); + menu->menu()->setTitle(tr(Constants::ClangFormat::DISPLAY_NAME)); m_formatFile = new QAction(BeautifierPlugin::msgFormatCurrentFile(), this); Core::Command *cmd diff --git a/src/plugins/beautifier/clangformat/clangformatconstants.h b/src/plugins/beautifier/clangformat/clangformatconstants.h index 51f6fa1bf86..837d3323069 100644 --- a/src/plugins/beautifier/clangformat/clangformatconstants.h +++ b/src/plugins/beautifier/clangformat/clangformatconstants.h @@ -25,11 +25,13 @@ #pragma once +#include + namespace Beautifier { namespace Constants { namespace ClangFormat { -const char DISPLAY_NAME[] = "ClangFormat"; +const char DISPLAY_NAME[] = QT_TRANSLATE_NOOP("Beautifier::Internal::ClangFormat::ClangFormat", "ClangFormat"); const char ACTION_FORMATFILE[] = "ClangFormat.FormatFile"; const char ACTION_FORMATSELECTED[] = "ClangFormat.FormatSelectedText"; const char MENU_ID[] = "ClangFormat.Menu"; diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index 32b13a99a3e..3b61d3a9dc5 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -69,7 +69,7 @@ Uncrustify::~Uncrustify() bool Uncrustify::initialize() { Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::Uncrustify::MENU_ID); - menu->menu()->setTitle(Constants::Uncrustify::DISPLAY_NAME); + menu->menu()->setTitle(tr(Constants::Uncrustify::DISPLAY_NAME)); m_formatFile = new QAction(BeautifierPlugin::msgFormatCurrentFile(), this); Core::Command *cmd @@ -114,7 +114,7 @@ void Uncrustify::formatFile() const QString cfgFileName = configurationFile(); if (cfgFileName.isEmpty()) { BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile( - Constants::Uncrustify::DISPLAY_NAME)); + tr(Constants::Uncrustify::DISPLAY_NAME))); } else { m_beautifierPlugin->formatCurrentFile(command(cfgFileName)); } @@ -125,7 +125,7 @@ void Uncrustify::formatSelectedText() const QString cfgFileName = configurationFile(); if (cfgFileName.isEmpty()) { BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile( - Constants::Uncrustify::DISPLAY_NAME)); + tr(Constants::Uncrustify::DISPLAY_NAME))); return; } diff --git a/src/plugins/beautifier/uncrustify/uncrustifyconstants.h b/src/plugins/beautifier/uncrustify/uncrustifyconstants.h index 9936689c3f1..7fa9537c578 100644 --- a/src/plugins/beautifier/uncrustify/uncrustifyconstants.h +++ b/src/plugins/beautifier/uncrustify/uncrustifyconstants.h @@ -25,11 +25,13 @@ #pragma once +#include + namespace Beautifier { namespace Constants { namespace Uncrustify { -const char DISPLAY_NAME[] = "Uncrustify"; +const char DISPLAY_NAME[] = QT_TRANSLATE_NOOP("Beautifier::Internal::Uncrustify::Uncrustify", "Uncrustify"); const char ACTION_FORMATFILE[] = "Uncrustify.FormatFile"; const char ACTION_FORMATSELECTED[] = "Uncrustify.FormatSelectedText"; const char MENU_ID[] = "Uncrustify.Menu"; diff --git a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp index 959022c0170..ab2e79162b8 100644 --- a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp @@ -28,6 +28,7 @@ #include "uncrustifyconstants.h" #include "uncrustifysettings.h" +#include "uncrustify.h" #include "../beautifierconstants.h" #include "../beautifierplugin.h" @@ -51,7 +52,7 @@ UncrustifyOptionsPageWidget::UncrustifyOptionsPageWidget(UncrustifySettings *set "HOME", QDir::toNativeSeparators(QDir::home().absolutePath()))); ui->command->setExpectedKind(Utils::PathChooser::ExistingCommand); ui->command->setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle( - Constants::Uncrustify::DISPLAY_NAME)); + Uncrustify::tr(Constants::Uncrustify::DISPLAY_NAME))); connect(ui->command, &Utils::PathChooser::validChanged, ui->options, &QWidget::setEnabled); ui->configurations->setSettings(m_settings); } From d9d2d638f707ea70f881871699406b398a95047b Mon Sep 17 00:00:00 2001 From: Jean Gressmann Date: Tue, 31 May 2016 06:33:17 +0200 Subject: [PATCH 11/20] Fixes parsing of MSVC file locations for parallel builds Change-Id: I2a8456d2f1bb14dc8fff1df02b7580fa708d0249 Reviewed-by: Tobias Hunger --- src/plugins/projectexplorer/msvcparser.cpp | 39 +++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/msvcparser.cpp b/src/plugins/projectexplorer/msvcparser.cpp index 710a7e89326..25e0f3131df 100644 --- a/src/plugins/projectexplorer/msvcparser.cpp +++ b/src/plugins/projectexplorer/msvcparser.cpp @@ -31,7 +31,7 @@ #include // As of MSVC 2015: "foo.cpp(42) :" -> "foo.cpp(42):" -static const char FILE_POS_PATTERN[] = "(cl|LINK|.+[^ ]) ?: "; +static const char FILE_POS_PATTERN[] = "(?:\\d+>)?(cl|LINK|.+[^ ]) ?: "; static const char ERROR_PATTERN[] = "[A-Z]+\\d\\d\\d\\d ?:"; static QPair parseFileName(const QString &input) @@ -343,6 +343,16 @@ void ProjectExplorerPlugin::testMsvcOutputParsers_data() Constants::TASK_CATEGORY_COMPILE)) << QString(); + QTest::newRow("labeled error with number prefix") + << QString::fromLatin1("1>qmlstandalone\\main.cpp(54) : error C4716: 'findUnresolvedModule' : must return a value") << OutputParserTester::STDOUT + << QString() << QString() + << (QList() + << Task(Task::Error, + QLatin1String("C4716: 'findUnresolvedModule' : must return a value"), + Utils::FileName::fromUserInput(QLatin1String("qmlstandalone\\main.cpp")), 54, + Constants::TASK_CATEGORY_COMPILE)) + << QString(); + QTest::newRow("labeled warning") << QString::fromLatin1("x:\\src\\plugins\\projectexplorer\\msvcparser.cpp(69) : warning C4100: 'something' : unreferenced formal parameter") << OutputParserTester::STDOUT << QString() << QString() @@ -353,6 +363,17 @@ void ProjectExplorerPlugin::testMsvcOutputParsers_data() Constants::TASK_CATEGORY_COMPILE)) << QString(); + + QTest::newRow("labeled warning with number prefix") + << QString::fromLatin1("1>x:\\src\\plugins\\projectexplorer\\msvcparser.cpp(69) : warning C4100: 'something' : unreferenced formal parameter") << OutputParserTester::STDOUT + << QString() << QString() + << (QList() + << Task(Task::Warning, + QLatin1String("C4100: 'something' : unreferenced formal parameter"), + Utils::FileName::fromUserInput(QLatin1String("x:\\src\\plugins\\projectexplorer\\msvcparser.cpp")), 69, + Constants::TASK_CATEGORY_COMPILE)) + << QString(); + QTest::newRow("additional information") << QString::fromLatin1("x:\\src\\plugins\\texteditor\\icompletioncollector.h(50) : warning C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class'\n" " x:\\src\\plugins\\texteditor\\completionsupport.h(39) : see declaration of 'TextEditor::CompletionItem'") @@ -369,6 +390,22 @@ void ProjectExplorerPlugin::testMsvcOutputParsers_data() Constants::TASK_CATEGORY_COMPILE)) << QString(); + QTest::newRow("additional information with prefix") + << QString::fromLatin1("2>x:\\src\\plugins\\texteditor\\icompletioncollector.h(50) : warning C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class'\n" + " x:\\src\\plugins\\texteditor\\completionsupport.h(39) : see declaration of 'TextEditor::CompletionItem'") + << OutputParserTester::STDOUT + << QString() << QString() + << (QList() + << Task(Task::Warning, + QLatin1String("C4099: 'TextEditor::CompletionItem' : type name first seen using 'struct' now seen using 'class'"), + Utils::FileName::fromUserInput(QLatin1String("x:\\src\\plugins\\texteditor\\icompletioncollector.h")), 50, + Constants::TASK_CATEGORY_COMPILE) + << Task(Task::Unknown, + QLatin1String("see declaration of 'TextEditor::CompletionItem'"), + Utils::FileName::fromUserInput(QLatin1String("x:\\src\\plugins\\texteditor\\completionsupport.h")), 39, + Constants::TASK_CATEGORY_COMPILE)) + << QString(); + QTest::newRow("fatal linker error") << QString::fromLatin1("LINK : fatal error LNK1146: no argument specified with option '/LIBPATH:'") << OutputParserTester::STDOUT From 0ad2ae3e578d81b65c3554196c48fab9e5f88fc8 Mon Sep 17 00:00:00 2001 From: Nikita Baryshnikov Date: Tue, 21 Jun 2016 01:56:28 +0300 Subject: [PATCH 12/20] VcsBaseOptionsPage: deinline dtor Change-Id: I314ce3b6b95d0e04ca548b3ae6e6975b670e8336 Reviewed-by: Orgad Shaneh --- src/plugins/vcsbase/vcsbaseoptionspage.cpp | 2 ++ src/plugins/vcsbase/vcsbaseoptionspage.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/plugins/vcsbase/vcsbaseoptionspage.cpp b/src/plugins/vcsbase/vcsbaseoptionspage.cpp index a433fe998a1..a4bba72571c 100644 --- a/src/plugins/vcsbase/vcsbaseoptionspage.cpp +++ b/src/plugins/vcsbase/vcsbaseoptionspage.cpp @@ -51,6 +51,8 @@ VcsBaseOptionsPage::VcsBaseOptionsPage(QObject *parent) : Core::IOptionsPage(par setCategoryIcon(QLatin1String(Constants::SETTINGS_CATEGORY_VCS_ICON)); } +VcsBaseOptionsPage::~VcsBaseOptionsPage() = default; + VcsClientOptionsPageWidget::VcsClientOptionsPageWidget(QWidget *parent) : QWidget(parent) { } diff --git a/src/plugins/vcsbase/vcsbaseoptionspage.h b/src/plugins/vcsbase/vcsbaseoptionspage.h index ce2ab137da3..a2d29cd5cf2 100644 --- a/src/plugins/vcsbase/vcsbaseoptionspage.h +++ b/src/plugins/vcsbase/vcsbaseoptionspage.h @@ -43,6 +43,7 @@ class VCSBASE_EXPORT VcsBaseOptionsPage : public Core::IOptionsPage { public: explicit VcsBaseOptionsPage(QObject *parent = 0); + ~VcsBaseOptionsPage() override; }; class VcsBaseClientImpl; From 90bd65479b1f8e3b75e12797b5f6ee3f95e591b2 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Wed, 22 Jun 2016 14:45:42 +0200 Subject: [PATCH 13/20] Clang: Fix warning readmessageblock.cpp:95:36: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] Change-Id: I24c5125f2116e5538b7d0e2389e66bf5d318640a Reviewed-by: David Schulz --- src/libs/clangbackendipc/readmessageblock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/clangbackendipc/readmessageblock.cpp b/src/libs/clangbackendipc/readmessageblock.cpp index f7e0c537955..61637b31f80 100644 --- a/src/libs/clangbackendipc/readmessageblock.cpp +++ b/src/libs/clangbackendipc/readmessageblock.cpp @@ -92,7 +92,7 @@ void ReadMessageBlock::resetCounter() bool ReadMessageBlock::isTheWholeMessageReadable(QDataStream &in) { - if (ioDevice->bytesAvailable() < sizeof(blockSize)) + if (ioDevice->bytesAvailable() < qint64(sizeof(blockSize))) return false; if (blockSize == 0) From 8562abbb567c21e34d222c6dc024b4a3f046521f Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 23 Jun 2016 07:34:53 +0200 Subject: [PATCH 14/20] AutoTest: Avoid crash when accessing uninitialized runnable Change-Id: I87bbf5b824a693a2c8d653bf5093e088f01b84b5 Reviewed-by: David Schulz --- src/plugins/autotest/testconfiguration.cpp | 2 +- src/plugins/autotest/testrunconfiguration.h | 27 ++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index f5c24c49bb4..db39b91bbaf 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -187,7 +187,7 @@ void TestConfiguration::completeTestInformation(int runMode) setProject(project); setGuessedConfiguration(guessedRunConfiguration); if (!guessedRunConfiguration && runMode == TestRunner::Debug) - m_runConfig = new TestRunConfiguration(runConfigTarget); + m_runConfig = new TestRunConfiguration(runConfigTarget, this); } } diff --git a/src/plugins/autotest/testrunconfiguration.h b/src/plugins/autotest/testrunconfiguration.h index ef471fc2369..1ed3d2b0eea 100644 --- a/src/plugins/autotest/testrunconfiguration.h +++ b/src/plugins/autotest/testrunconfiguration.h @@ -25,7 +25,15 @@ #pragma once +#include "autotestplugin.h" +#include "testconfiguration.h" + +#include +#include +#include #include +#include +#include namespace Autotest { namespace Internal { @@ -33,15 +41,32 @@ namespace Internal { class TestRunConfiguration : public ProjectExplorer::RunConfiguration { public: - TestRunConfiguration(ProjectExplorer::Target *parent) + TestRunConfiguration(ProjectExplorer::Target *parent, TestConfiguration *config) : ProjectExplorer::RunConfiguration(parent, "AutoTest.TestRunConfig") { setDefaultDisplayName(tr("AutoTest Debug")); addExtraAspects(); + m_testConfig = config; + } + + ProjectExplorer::Runnable runnable() const override + { + ProjectExplorer::StandardRunnable r; + QTC_ASSERT(m_testConfig, return r); + r.executable = m_testConfig->targetFile(); + r.commandLineArguments = m_testConfig->argumentsForTestRunner( + *AutotestPlugin::instance()->settings()).join(' '); + r.workingDirectory = m_testConfig->workingDirectory(); + r.environment = m_testConfig->environment(); + r.runMode = ProjectExplorer::ApplicationLauncher::Gui; + r.device = ProjectExplorer::DeviceManager::instance()->defaultDevice( + ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); + return r; } private: QWidget *createConfigurationWidget() { return 0; } + TestConfiguration *m_testConfig = 0; }; } // namespace Internal From 8f474cbfbee1d805b7363849c37467d4e30ceb6c Mon Sep 17 00:00:00 2001 From: Marco Benelli Date: Thu, 23 Jun 2016 10:48:54 +0200 Subject: [PATCH 15/20] QmlJs: fixes bug in module import search. Task-number: QTCREATORBUG-16425 Change-Id: I5fdd1a5882730c0f52dba5edb8cf8ca7092a4409 Reviewed-by: Erik Verbruggen --- src/libs/qmljs/qmljsutils.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/libs/qmljs/qmljsutils.cpp b/src/libs/qmljs/qmljsutils.cpp index 8f87b2c98fa..e91db31b360 100644 --- a/src/libs/qmljs/qmljsutils.cpp +++ b/src/libs/qmljs/qmljsutils.cpp @@ -250,24 +250,28 @@ QString QmlJS::modulePath(const QString &name, const QString &version, QString candidate; - for (QString ver = sanitizedVersion; ; ver.remove(re)) { + for (QString ver = sanitizedVersion; !ver.isEmpty(); ver.remove(re)) { for (const QString &path: importPaths) { - if (ver.isEmpty()) { - candidate = QDir::cleanPath(QString::fromLatin1("%1/%2").arg(path, mkpath(parts))); - return QDir(candidate).exists() ? candidate : QString(); - } else { - for (int i = parts.count() - 1; i >= 0; --i) { - candidate = QDir::cleanPath( - QString::fromLatin1("%1/%2.%3/%4").arg(path, - mkpath(parts.mid(0, i + 1)), - ver, - mkpath(parts.mid(i + 1)))); - if (QDir(candidate).exists()) - return candidate; - } + for (int i = parts.count() - 1; i >= 0; --i) { + candidate = QDir::cleanPath( + QString::fromLatin1("%1/%2.%3/%4").arg(path, + mkpath(parts.mid(0, i + 1)), + ver, + mkpath(parts.mid(i + 1)))); + if (QDir(candidate).exists()) + return candidate; } } } + + // Version is empty + for (const QString &path: importPaths) { + candidate = QDir::cleanPath(QString::fromLatin1("%1/%2").arg(path, mkpath(parts))); + if (QDir(candidate).exists()) + return candidate; + } + + return QString(); } bool QmlJS::isValidBuiltinPropertyType(const QString &name) From 8219188738ebdfaffc75b3d7363e8f423e1f4def Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 23 Jun 2016 09:32:32 +0200 Subject: [PATCH 16/20] AutoTest: Disable QmlDebugger for debugging tests Currently debugging tests is enabled only for C++ based projects and starting QmlDebugger although not needed feels wrong and results additionally in a fail message which might be confusing for users. Change-Id: I1f62b67ea6d3d8bb56d9723ea1132257d0b96b9b Reviewed-by: David Schulz --- src/plugins/autotest/testrunconfiguration.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/autotest/testrunconfiguration.h b/src/plugins/autotest/testrunconfiguration.h index 1ed3d2b0eea..57876c66caa 100644 --- a/src/plugins/autotest/testrunconfiguration.h +++ b/src/plugins/autotest/testrunconfiguration.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace Autotest { namespace Internal { @@ -46,6 +47,11 @@ public: { setDefaultDisplayName(tr("AutoTest Debug")); addExtraAspects(); + + // disable QmlDebugger that is enabled by default + // might change if debugging QuickTest gets enabled + if (auto debugAspect = extraAspect()) + debugAspect->setUseQmlDebugger(false); m_testConfig = config; } From 7d342471a4a03b99c2545ce0f0a10561b19a041e Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 23 Jun 2016 15:57:26 +0200 Subject: [PATCH 17/20] SmallString: Fix ambiguity of iterators std::size_t is a undefined unsigned integer type and std::ptrdiff_t is a undefined signed integer type. So sometimes the compiler doesn't know which to choose because both could represent a integer. Change-Id: I669cd44c6f16854dfe3f3cc44edbfc422e1cbd6a Reviewed-by: Tim Jenssen --- src/libs/utils/smallstring.h | 4 ++-- src/libs/utils/smallstringliteral.h | 4 ++-- src/libs/utils/smallstringview.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index 6c815c7ebfb..1c6516a3c3a 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -267,12 +267,12 @@ public: reverse_iterator rbegin() noexcept { - return reverse_iterator(end() - 1l); + return reverse_iterator(end() - static_cast(1)); } reverse_iterator rend() noexcept { - return reverse_iterator(begin() - 1l); + return reverse_iterator(begin() - static_cast(1)); } const_iterator begin() const noexcept diff --git a/src/libs/utils/smallstringliteral.h b/src/libs/utils/smallstringliteral.h index 0f631d03e63..47c7dab33b4 100644 --- a/src/libs/utils/smallstringliteral.h +++ b/src/libs/utils/smallstringliteral.h @@ -90,12 +90,12 @@ public: const_reverse_iterator rbegin() const noexcept { - return const_reverse_iterator(end() - 1l); + return const_reverse_iterator(end() - static_cast(1)); } const_reverse_iterator rend() const noexcept { - return const_reverse_iterator(begin() - 1l); + return const_reverse_iterator(begin() - static_cast(1)); } constexpr static diff --git a/src/libs/utils/smallstringview.h b/src/libs/utils/smallstringview.h index 204a93ebfc9..c0cb4aedbb3 100644 --- a/src/libs/utils/smallstringview.h +++ b/src/libs/utils/smallstringview.h @@ -106,12 +106,12 @@ public: const_reverse_iterator rbegin() const noexcept { - return const_reverse_iterator(end() - 1l); + return const_reverse_iterator(end() - static_cast(1)); } const_reverse_iterator rend() const noexcept { - return const_reverse_iterator(begin() - 1l); + return const_reverse_iterator(begin() - static_cast(1)); } private: From c3a5eecfc5e6acb4b3c15b687d02ec35022b6c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georger=20Ara=C3=BAjo?= Date: Mon, 20 Jun 2016 17:38:29 -0300 Subject: [PATCH 18/20] Modnokai Night Shift v2 color scheme for QtC Text Editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7919dab34402ce5da0b77fb8fe0630c7c318479f Reviewed-by: André Hartmann --- .../styles/modnokai_night_shift_v2.xml | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 share/qtcreator/styles/modnokai_night_shift_v2.xml diff --git a/share/qtcreator/styles/modnokai_night_shift_v2.xml b/share/qtcreator/styles/modnokai_night_shift_v2.xml new file mode 100644 index 00000000000..a5716f834d1 --- /dev/null +++ b/share/qtcreator/styles/modnokai_night_shift_v2.xml @@ -0,0 +1,64 @@ + + + +