forked from qt-creator/qt-creator
CppEditor: Fix some "convert to camel case" edge cases
Fixes: QTCREATORBUG-16560 Change-Id: I8573ae6c5dce0956c868addc69a921c62f1d571a Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -2047,6 +2047,39 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
<< CppQuickFixFactoryPtr(new InsertQtPropertyMembers)
|
<< CppQuickFixFactoryPtr(new InsertQtPropertyMembers)
|
||||||
<< _("class C { @Q_PROPERTY(typeid foo READ foo) };\n")
|
<< _("class C { @Q_PROPERTY(typeid foo READ foo) };\n")
|
||||||
<< _();
|
<< _();
|
||||||
|
|
||||||
|
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 CppEditorPlugin::test_quickfix()
|
void CppEditorPlugin::test_quickfix()
|
||||||
|
@@ -2002,9 +2002,13 @@ namespace {
|
|||||||
class ConvertToCamelCaseOp: public CppQuickFixOperation
|
class ConvertToCamelCaseOp: public CppQuickFixOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConvertToCamelCaseOp(const CppQuickFixInterface &interface, const QString &newName)
|
ConvertToCamelCaseOp(const CppQuickFixInterface &interface, const QString &name,
|
||||||
|
const AST *nameAst, bool test)
|
||||||
: CppQuickFixOperation(interface, -1)
|
: CppQuickFixOperation(interface, -1)
|
||||||
, m_name(newName)
|
, m_name(name)
|
||||||
|
, m_nameAst(nameAst)
|
||||||
|
, m_isAllUpper(name.isUpper())
|
||||||
|
, m_test(test)
|
||||||
{
|
{
|
||||||
setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Camel Case"));
|
setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Camel Case"));
|
||||||
}
|
}
|
||||||
@@ -2014,17 +2018,24 @@ public:
|
|||||||
CppRefactoringChanges refactoring(snapshot());
|
CppRefactoringChanges refactoring(snapshot());
|
||||||
CppRefactoringFilePtr currentFile = refactoring.file(filePath().toString());
|
CppRefactoringFilePtr currentFile = refactoring.file(filePath().toString());
|
||||||
|
|
||||||
for (int i = 1; i < m_name.length(); ++i) {
|
QString newName = m_isAllUpper ? m_name.toLower() : m_name;
|
||||||
const QChar c = m_name.at(i);
|
for (int i = 1; i < newName.length(); ++i) {
|
||||||
if (c.isUpper()) {
|
const QChar c = newName.at(i);
|
||||||
m_name[i] = c.toLower();
|
if (c.isUpper() && m_isAllUpper) {
|
||||||
} else if (i < m_name.length() - 1
|
newName[i] = c.toLower();
|
||||||
&& isConvertibleUnderscore(m_name, i)) {
|
} else if (i < newName.length() - 1 && isConvertibleUnderscore(newName, i)) {
|
||||||
m_name.remove(i, 1);
|
newName.remove(i, 1);
|
||||||
m_name[i] = m_name.at(i).toUpper();
|
newName[i] = newName.at(i).toUpper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
editor()->renameUsages(m_name);
|
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)
|
static bool isConvertibleUnderscore(const QString &name, int pos)
|
||||||
@@ -2034,7 +2045,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_name;
|
const QString m_name;
|
||||||
|
const AST * const m_nameAst;
|
||||||
|
const bool m_isAllUpper;
|
||||||
|
const bool m_test;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
@@ -2048,22 +2062,26 @@ void ConvertToCamelCase::match(const CppQuickFixInterface &interface, QuickFixOp
|
|||||||
|
|
||||||
AST * const ast = path.last();
|
AST * const ast = path.last();
|
||||||
const Name *name = nullptr;
|
const Name *name = nullptr;
|
||||||
|
const AST *astForName = nullptr;
|
||||||
if (const NameAST * const nameAst = ast->asName()) {
|
if (const NameAST * const nameAst = ast->asName()) {
|
||||||
if (nameAst->name && nameAst->name->asNameId())
|
if (nameAst->name && nameAst->name->asNameId()) {
|
||||||
|
astForName = nameAst;
|
||||||
name = nameAst->name;
|
name = nameAst->name;
|
||||||
|
}
|
||||||
} else if (const NamespaceAST * const namespaceAst = ast->asNamespace()) {
|
} else if (const NamespaceAST * const namespaceAst = ast->asNamespace()) {
|
||||||
|
astForName = namespaceAst;
|
||||||
name = namespaceAst->symbol->name();
|
name = namespaceAst->symbol->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString newName = QString::fromUtf8(name->identifier()->chars());
|
QString nameString = QString::fromUtf8(name->identifier()->chars());
|
||||||
if (newName.length() < 3)
|
if (nameString.length() < 3)
|
||||||
return;
|
return;
|
||||||
for (int i = 1; i < newName.length() - 1; ++i) {
|
for (int i = 1; i < nameString.length() - 1; ++i) {
|
||||||
if (ConvertToCamelCaseOp::isConvertibleUnderscore(newName, i)) {
|
if (ConvertToCamelCaseOp::isConvertibleUnderscore(nameString, i)) {
|
||||||
result << new ConvertToCamelCaseOp(interface, newName);
|
result << new ConvertToCamelCaseOp(interface, nameString, astForName, m_test);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -221,7 +221,12 @@ public:
|
|||||||
class ConvertToCamelCase : public CppQuickFixFactory
|
class ConvertToCamelCase : public CppQuickFixFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
ConvertToCamelCase(bool test = false) : CppQuickFixFactory(), m_test(test) {}
|
||||||
|
|
||||||
void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override;
|
void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const bool m_test;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -213,7 +213,7 @@ Utils::ChangeSet::Range CppRefactoringFile::range(unsigned tokenIndex) const
|
|||||||
return {start, start + token.utf16chars()};
|
return {start, start + token.utf16chars()};
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::ChangeSet::Range CppRefactoringFile::range(AST *ast) const
|
Utils::ChangeSet::Range CppRefactoringFile::range(const AST *ast) const
|
||||||
{
|
{
|
||||||
return {startOf(ast), endOf(ast)};
|
return {startOf(ast), endOf(ast)};
|
||||||
}
|
}
|
||||||
|
@@ -52,7 +52,7 @@ public:
|
|||||||
|
|
||||||
Range range(int start, int end) const;
|
Range range(int start, int end) const;
|
||||||
Range range(unsigned tokenIndex) const;
|
Range range(unsigned tokenIndex) const;
|
||||||
Range range(CPlusPlus::AST *ast) const;
|
Range range(const CPlusPlus::AST *ast) const;
|
||||||
|
|
||||||
const CPlusPlus::Token &tokenAt(unsigned index) const;
|
const CPlusPlus::Token &tokenAt(unsigned index) const;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user