diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2024-05-17 10:44:27 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2024-05-17 14:10:44 +0000 |
commit | 3c18fe3cb15251244e52423b99162035cda0618e (patch) | |
tree | e9f52b67dd411231e966de8df6a695402c169b84 /src/plugins | |
parent | a6758ab76c4d37abdb0fd0b392f8c1f134b4b294 (diff) |
CppEditor: Move ConvertToCamelCase quickfix to its own files
Change-Id: Ic45ad1732fbf1253088db1b8adb93d752ed7cd1c
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/cppeditor/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditor.qbs | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/quickfixes/converttocamelcase.cpp | 191 | ||||
-rw-r--r-- | src/plugins/cppeditor/quickfixes/converttocamelcase.h | 8 | ||||
-rw-r--r-- | src/plugins/cppeditor/quickfixes/cppquickfix_test.cpp | 33 | ||||
-rw-r--r-- | src/plugins/cppeditor/quickfixes/cppquickfixes.cpp | 101 | ||||
-rw-r--r-- | src/plugins/cppeditor/quickfixes/cppquickfixes.h | 17 |
7 files changed, 206 insertions, 147 deletions
diff --git a/src/plugins/cppeditor/CMakeLists.txt b/src/plugins/cppeditor/CMakeLists.txt index bc7d6d150c..bdfe7b2283 100644 --- a/src/plugins/cppeditor/CMakeLists.txt +++ b/src/plugins/cppeditor/CMakeLists.txt @@ -101,6 +101,7 @@ add_qtc_plugin(CppEditor quickfixes/convertnumericliteral.cpp quickfixes/convertnumericliteral.h quickfixes/convertqt4connect.cpp quickfixes/convertqt4connect.h quickfixes/convertstringliteral.cpp quickfixes/convertstringliteral.h + quickfixes/converttocamelcase.cpp quickfixes/converttocamelcase.h quickfixes/converttometamethodcall.cpp quickfixes/converttometamethodcall.h quickfixes/cppcodegenerationquickfixes.cpp quickfixes/cppcodegenerationquickfixes.h quickfixes/cppinsertvirtualmethods.cpp quickfixes/cppinsertvirtualmethods.h diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 9c0cd9ff3d..c02ed9b8e6 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -233,6 +233,8 @@ QtcPlugin { "convertqt4connect.h", "convertstringliteral.cpp", "convertstringliteral.h", + "converttocamelcase.cpp", + "converttocamelcase.h", "converttometamethodcall.cpp", "converttometamethodcall.h", "cppcodegenerationquickfixes.cpp", diff --git a/src/plugins/cppeditor/quickfixes/converttocamelcase.cpp b/src/plugins/cppeditor/quickfixes/converttocamelcase.cpp new file mode 100644 index 0000000000..5d79997297 --- /dev/null +++ b/src/plugins/cppeditor/quickfixes/converttocamelcase.cpp @@ -0,0 +1,191 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "converttocamelcase.h" + +#include "../cppeditortr.h" +#include "../cppeditorwidget.h" +#include "../cpprefactoringchanges.h" +#include "cppquickfix.h" + +#ifdef WITH_TESTS +#include "cppquickfix_test.h" +#include <QtTest> +#endif + +using namespace CPlusPlus; +using namespace Utils; + +namespace CppEditor::Internal { +namespace { + +class ConvertToCamelCaseOp: public CppQuickFixOperation +{ +public: + ConvertToCamelCaseOp(const CppQuickFixInterface &interface, const QString &name, + const AST *nameAst, bool test) + : CppQuickFixOperation(interface, -1) + , m_name(name) + , m_nameAst(nameAst) + , m_isAllUpper(name.isUpper()) + , m_test(test) + { + setDescription(Tr::tr("Convert to Camel Case")); + } + + static bool isConvertibleUnderscore(const QString &name, int pos) + { + return name.at(pos) == QLatin1Char('_') && name.at(pos+1).isLetter() + && !(pos == 1 && name.at(0) == QLatin1Char('m')); + } + +private: + void perform() override + { + CppRefactoringChanges refactoring(snapshot()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); + + QString newName = m_isAllUpper ? m_name.toLower() : m_name; + for (int i = 1; i < newName.length(); ++i) { + const QChar c = newName.at(i); + if (c.isUpper() && m_isAllUpper) { + newName[i] = c.toLower(); + } else if (i < newName.length() - 1 && isConvertibleUnderscore(newName, i)) { + newName.remove(i, 1); + newName[i] = newName.at(i).toUpper(); + } + } + if (m_test) { + ChangeSet changeSet; + changeSet.replace(currentFile->range(m_nameAst), newName); + currentFile->setChangeSet(changeSet); + currentFile->apply(); + } else { + editor()->renameUsages(newName); + } + } + + const QString m_name; + const AST * const m_nameAst; + const bool m_isAllUpper; + const bool m_test; +}; + +/*! + Turns "an_example_symbol" into "anExampleSymbol" and + "AN_EXAMPLE_SYMBOL" into "AnExampleSymbol". + + Activates on: identifiers +*/ +class ConvertToCamelCase : public CppQuickFixFactory +{ +public: + ConvertToCamelCase(bool test = false) : m_test(test) {} + +#ifdef WITH_TESTS + static QObject *createTest(); +#endif + +private: + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override + { + const QList<AST *> &path = interface.path(); + + if (path.isEmpty()) + return; + + AST * const ast = path.last(); + const Name *name = nullptr; + const AST *astForName = nullptr; + if (const NameAST * const nameAst = ast->asName()) { + if (nameAst->name && nameAst->name->asNameId()) { + astForName = nameAst; + name = nameAst->name; + } + } else if (const NamespaceAST * const namespaceAst = ast->asNamespace()) { + astForName = namespaceAst; + name = namespaceAst->symbol->name(); + } + + if (!name) + return; + + QString nameString = QString::fromUtf8(name->identifier()->chars()); + if (nameString.length() < 3) + return; + for (int i = 1; i < nameString.length() - 1; ++i) { + if (ConvertToCamelCaseOp::isConvertibleUnderscore(nameString, i)) { + result << new ConvertToCamelCaseOp(interface, nameString, astForName, m_test); + return; + } + } + } + + const bool m_test; +}; + +#ifdef WITH_TESTS +using namespace Tests; + +class ConvertToCamelCaseTest : public QObject +{ + Q_OBJECT + +private slots: + void test_data() + { + QTest::addColumn<QByteArray>("original"); + QTest::addColumn<QByteArray>("expected"); + + using QByteArray = QByteArray; + + QTest::newRow("convert to camel case: normal") + << QByteArray("void @lower_case_function();\n") + << QByteArray("void lowerCaseFunction();\n"); + QTest::newRow("convert to camel case: already camel case") + << QByteArray("void @camelCaseFunction();\n") + << QByteArray(); + QTest::newRow("convert to camel case: no underscores (lower case)") + << QByteArray("void @lowercasefunction();\n") + << QByteArray(); + QTest::newRow("convert to camel case: no underscores (upper case)") + << QByteArray("void @UPPERCASEFUNCTION();\n") + << QByteArray(); + QTest::newRow("convert to camel case: non-applicable underscore") + << QByteArray("void @m_a_member;\n") + << QByteArray("void m_aMember;\n"); + QTest::newRow("convert to camel case: upper case") + << QByteArray("void @UPPER_CASE_FUNCTION();\n") + << QByteArray("void upperCaseFunction();\n"); + QTest::newRow("convert to camel case: partially camel case already") + << QByteArray("void mixed@_andCamelCase();\n") + << QByteArray("void mixedAndCamelCase();\n"); + QTest::newRow("convert to camel case: wild mix") + << QByteArray("void @WhAt_TODO_hErE();\n") + << QByteArray("void WhAtTODOHErE();\n"); + } + + void test() + { + QFETCH(QByteArray, original); + QFETCH(QByteArray, expected); + ConvertToCamelCase factory(true); + QuickFixOperationTest(singleDocument(original, expected), &factory); + } +}; + +QObject *ConvertToCamelCase::createTest() { return new ConvertToCamelCaseTest; } + +#endif // WITH_TESTS +} // namespace + +void registerConvertToCamelCaseQuickfix() +{ + CppQuickFixFactory::registerFactory<ConvertToCamelCase>(); +} + +} // namespace CppEditor::Internal + +#ifdef WITH_TESTS +#include <converttocamelcase.moc> +#endif diff --git a/src/plugins/cppeditor/quickfixes/converttocamelcase.h b/src/plugins/cppeditor/quickfixes/converttocamelcase.h new file mode 100644 index 0000000000..2d7acb08f7 --- /dev/null +++ b/src/plugins/cppeditor/quickfixes/converttocamelcase.h @@ -0,0 +1,8 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +namespace CppEditor::Internal { +void registerConvertToCamelCaseQuickfix(); +} // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/quickfixes/cppquickfix_test.cpp b/src/plugins/cppeditor/quickfixes/cppquickfix_test.cpp index 41df3b423a..efb2d7fa64 100644 --- a/src/plugins/cppeditor/quickfixes/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/quickfixes/cppquickfix_test.cpp @@ -269,39 +269,6 @@ void QuickfixTest::testGeneric_data() << CppQuickFixFactoryPtr(new ReformatPointerDeclaration) << _("char@*s;") << _("char *s;"); - - QTest::newRow("convert to camel case: normal") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void @lower_case_function();\n") - << _("void lowerCaseFunction();\n"); - QTest::newRow("convert to camel case: already camel case") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void @camelCaseFunction();\n") - << _(); - QTest::newRow("convert to camel case: no underscores (lower case)") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void @lowercasefunction();\n") - << _(); - QTest::newRow("convert to camel case: no underscores (upper case)") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void @UPPERCASEFUNCTION();\n") - << _(); - QTest::newRow("convert to camel case: non-applicable underscore") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void @m_a_member;\n") - << _("void m_aMember;\n"); - QTest::newRow("convert to camel case: upper case") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void @UPPER_CASE_FUNCTION();\n") - << _("void upperCaseFunction();\n"); - QTest::newRow("convert to camel case: partially camel case already") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void mixed@_andCamelCase();\n") - << _("void mixedAndCamelCase();\n"); - QTest::newRow("convert to camel case: wild mix") - << CppQuickFixFactoryPtr(new ConvertToCamelCase(true)) - << _("void @WhAt_TODO_hErE();\n") - << _("void WhAtTODOHErE();\n"); } void QuickfixTest::testGeneric() diff --git a/src/plugins/cppeditor/quickfixes/cppquickfixes.cpp b/src/plugins/cppeditor/quickfixes/cppquickfixes.cpp index 1432488ad9..46af51d38c 100644 --- a/src/plugins/cppeditor/quickfixes/cppquickfixes.cpp +++ b/src/plugins/cppeditor/quickfixes/cppquickfixes.cpp @@ -11,19 +11,19 @@ #include "../cpppointerdeclarationformatter.h" #include "../cpprefactoringchanges.h" #include "../cpptoolsreuse.h" -#include "../insertionpointlocator.h" #include "assigntolocalvariable.h" #include "bringidentifierintoscope.h" #include "completeswitchstatement.h" #include "convertfromandtopointer.h" #include "convertnumericliteral.h" +#include "convertqt4connect.h" +#include "convertstringliteral.h" +#include "converttocamelcase.h" #include "converttometamethodcall.h" #include "cppcodegenerationquickfixes.h" #include "cppinsertvirtualmethods.h" #include "cppquickfixassistant.h" #include "cppquickfixhelpers.h" -#include "convertqt4connect.h" -#include "convertstringliteral.h" #include "createdeclarationfromuse.h" #include "extractfunction.h" #include "extractliteralasparameter.h" @@ -91,9 +91,7 @@ #include <QTextCursor> #include <QVBoxLayout> -#include <bitset> #include <cctype> -#include <limits> using namespace CPlusPlus; using namespace ProjectExplorer; @@ -137,96 +135,6 @@ namespace Internal { namespace { -class ConvertToCamelCaseOp: public CppQuickFixOperation -{ -public: - ConvertToCamelCaseOp(const CppQuickFixInterface &interface, const QString &name, - const AST *nameAst, bool test) - : CppQuickFixOperation(interface, -1) - , m_name(name) - , m_nameAst(nameAst) - , m_isAllUpper(name.isUpper()) - , m_test(test) - { - setDescription(Tr::tr("Convert to Camel Case")); - } - - void perform() override - { - CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); - - QString newName = m_isAllUpper ? m_name.toLower() : m_name; - for (int i = 1; i < newName.length(); ++i) { - const QChar c = newName.at(i); - if (c.isUpper() && m_isAllUpper) { - newName[i] = c.toLower(); - } else if (i < newName.length() - 1 && isConvertibleUnderscore(newName, i)) { - newName.remove(i, 1); - newName[i] = newName.at(i).toUpper(); - } - } - if (m_test) { - ChangeSet changeSet; - changeSet.replace(currentFile->range(m_nameAst), newName); - currentFile->setChangeSet(changeSet); - currentFile->apply(); - } else { - editor()->renameUsages(newName); - } - } - - static bool isConvertibleUnderscore(const QString &name, int pos) - { - return name.at(pos) == QLatin1Char('_') && name.at(pos+1).isLetter() - && !(pos == 1 && name.at(0) == QLatin1Char('m')); - } - -private: - const QString m_name; - const AST * const m_nameAst; - const bool m_isAllUpper; - const bool m_test; -}; - -} // anonymous namespace - -void ConvertToCamelCase::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) -{ - const QList<AST *> &path = interface.path(); - - if (path.isEmpty()) - return; - - AST * const ast = path.last(); - const Name *name = nullptr; - const AST *astForName = nullptr; - if (const NameAST * const nameAst = ast->asName()) { - if (nameAst->name && nameAst->name->asNameId()) { - astForName = nameAst; - name = nameAst->name; - } - } else if (const NamespaceAST * const namespaceAst = ast->asNamespace()) { - astForName = namespaceAst; - name = namespaceAst->symbol->name(); - } - - if (!name) - return; - - QString nameString = QString::fromUtf8(name->identifier()->chars()); - if (nameString.length() < 3) - return; - for (int i = 1; i < nameString.length() - 1; ++i) { - if (ConvertToCamelCaseOp::isConvertibleUnderscore(nameString, i)) { - result << new ConvertToCamelCaseOp(interface, nameString, astForName, m_test); - return; - } - } -} - -namespace { - class RearrangeParamDeclarationListOp: public CppQuickFixOperation { public: @@ -476,8 +384,6 @@ void ExtraRefactoringOperations::doMatch(const CppQuickFixInterface &interface, void createCppQuickFixes() { - new ConvertToCamelCase; - new RearrangeParamDeclarationList; new ReformatPointerDeclaration; @@ -504,6 +410,7 @@ void createCppQuickFixes() registerConvertToMetaMethodCallQuickfix(); registerSplitSimpleDeclarationQuickfix(); registerConvertNumericLiteralQuickfix(); + registerConvertToCamelCaseQuickfix(); new ExtraRefactoringOperations; } diff --git a/src/plugins/cppeditor/quickfixes/cppquickfixes.h b/src/plugins/cppeditor/quickfixes/cppquickfixes.h index bb2312842e..c53c66bd84 100644 --- a/src/plugins/cppeditor/quickfixes/cppquickfixes.h +++ b/src/plugins/cppeditor/quickfixes/cppquickfixes.h @@ -29,23 +29,6 @@ public: }; /*! - Turns "an_example_symbol" into "anExampleSymbol" and - "AN_EXAMPLE_SYMBOL" into "AnExampleSymbol". - - Activates on: identifiers -*/ -class ConvertToCamelCase : public CppQuickFixFactory -{ -public: - ConvertToCamelCase(bool test = false) : CppQuickFixFactory(), m_test(test) {} - - void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; - -private: - const bool m_test; -}; - -/*! Switches places of the parameter declaration under cursor with the next or the previous one in the parameter declaration list |