CppEditor: Merge two factories

They are closely related, and we might want to add more variants of this
functionality.

Change-Id: Ida83cce018fad5a84d5f6d24a0fa4ff2bca5a67b
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2023-04-25 17:51:25 +02:00
parent 3821683647
commit 5e73bacb0e
3 changed files with 62 additions and 75 deletions

View File

@@ -1725,7 +1725,7 @@ void QuickfixTest::testGeneric_data()
<< _(R"(const char *str = @"\xc3\xa0""f23\xd0\xb1g\xd0\xb1""1";)") << _(R"(const char *str = @"\xc3\xa0""f23\xd0\xb1g\xd0\xb1""1";)")
<< _(R"(const char *str = "àf23бgб1";)"); << _(R"(const char *str = "àf23бgб1";)");
QTest::newRow("AddLocalDeclaration_QTCREATORBUG-26004") QTest::newRow("AddLocalDeclaration_QTCREATORBUG-26004")
<< CppQuickFixFactoryPtr(new AddLocalDeclaration) << CppQuickFixFactoryPtr(new AddDeclarationForUndeclaredIdentifier)
<< _("void func() {\n" << _("void func() {\n"
" QStringList list;\n" " QStringList list;\n"
" @it = list.cbegin();\n" " @it = list.cbegin();\n"
@@ -3863,7 +3863,7 @@ void QuickfixTest::testInsertMemberFromInitialization()
CppTestDocument::create("file.h", original, expected) CppTestDocument::create("file.h", original, expected)
}); });
InsertMemberFromInitialization factory; AddDeclarationForUndeclaredIdentifier factory;
QuickFixOperationTest(testDocuments, &factory); QuickFixOperationTest(testDocuments, &factory);
} }

View File

@@ -1646,42 +1646,6 @@ private:
} // anonymous namespace } // anonymous namespace
void AddLocalDeclaration::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
{
const QList<AST *> &path = interface.path();
CppRefactoringFilePtr file = interface.currentFile();
for (int index = path.size() - 1; index != -1; --index) {
if (BinaryExpressionAST *binary = path.at(index)->asBinaryExpression()) {
if (binary->left_expression && binary->right_expression
&& file->tokenAt(binary->binary_op_token).is(T_EQUAL)) {
IdExpressionAST *idExpr = binary->left_expression->asIdExpression();
if (interface.isCursorOn(binary->left_expression) && idExpr
&& idExpr->name->asSimpleName() != nullptr) {
SimpleNameAST *nameAST = idExpr->name->asSimpleName();
const QList<LookupItem> results = interface.context().lookup(nameAST->name, file->scopeAt(nameAST->firstToken()));
Declaration *decl = nullptr;
for (const LookupItem &r : results) {
if (!r.declaration())
continue;
if (Declaration *d = r.declaration()->asDeclaration()) {
if (!d->type()->asFunctionType()) {
decl = d;
break;
}
}
}
if (!decl) {
result << new AddLocalDeclarationOp(interface, index, binary, nameAST);
return;
}
}
}
}
}
}
namespace { namespace {
class ConvertToCamelCaseOp: public CppQuickFixOperation class ConvertToCamelCaseOp: public CppQuickFixOperation
@@ -2980,25 +2944,64 @@ private:
const QString m_type; const QString m_type;
}; };
void InsertMemberFromInitialization::match(const CppQuickFixInterface &interface, void AddDeclarationForUndeclaredIdentifier::match(const CppQuickFixInterface &interface,
QuickFixOperations &result) QuickFixOperations &result)
{ {
// First check whether we are on a member initialization. if (!checkForMemberInitializer(interface, result))
return;
const CppRefactoringFilePtr &file = interface.currentFile();
const QList<AST *> path = interface.path(); const QList<AST *> path = interface.path();
for (int index = path.size() - 1; index != -1; --index) {
if (BinaryExpressionAST *binary = path.at(index)->asBinaryExpression()) {
if (binary->left_expression && binary->right_expression
&& file->tokenAt(binary->binary_op_token).is(T_EQUAL)) {
IdExpressionAST *idExpr = binary->left_expression->asIdExpression();
if (interface.isCursorOn(binary->left_expression) && idExpr
&& idExpr->name->asSimpleName() != nullptr) {
SimpleNameAST *nameAST = idExpr->name->asSimpleName();
const QList<LookupItem> results = interface.context().lookup(
nameAST->name, file->scopeAt(nameAST->firstToken()));
Declaration *decl = nullptr;
for (const LookupItem &r : results) {
if (!r.declaration())
continue;
if (Declaration *d = r.declaration()->asDeclaration()) {
if (!d->type()->asFunctionType()) {
decl = d;
break;
}
}
}
if (!decl) {
result << new AddLocalDeclarationOp(interface, index, binary, nameAST);
return;
}
}
}
}
}
}
bool AddDeclarationForUndeclaredIdentifier::checkForMemberInitializer(
const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result)
{
const QList<AST *> &path = interface.path();
const int size = path.size(); const int size = path.size();
if (size < 4) if (size < 4)
return; return true;
const SimpleNameAST * const name = path.at(size - 1)->asSimpleName(); const SimpleNameAST * const name = path.at(size - 1)->asSimpleName();
if (!name) if (!name)
return; return true;
const MemInitializerAST * const memInitializer = path.at(size - 2)->asMemInitializer(); const MemInitializerAST * const memInitializer = path.at(size - 2)->asMemInitializer();
if (!memInitializer) if (!memInitializer)
return; return true;
if (!path.at(size - 3)->asCtorInitializer()) if (!path.at(size - 3)->asCtorInitializer())
return; return true;
const FunctionDefinitionAST * ctor = path.at(size - 4)->asFunctionDefinition(); const FunctionDefinitionAST * ctor = path.at(size - 4)->asFunctionDefinition();
if (!ctor) if (!ctor)
return; return false;
// Now find the class. // Now find the class.
const Class *theClass = nullptr; const Class *theClass = nullptr;
@@ -3018,12 +3021,12 @@ void InsertMemberFromInitialization::match(const CppQuickFixInterface &interface
} }
if (!theClass) if (!theClass)
return; return false;
// Check whether the member exists already. // Check whether the member exists already.
if (theClass->find(interface.currentFile()->cppDocument()->translationUnit()->identifier( if (theClass->find(interface.currentFile()->cppDocument()->translationUnit()->identifier(
name->identifier_token))) { name->identifier_token))) {
return; return false;
} }
const QString type = getType(interface, memInitializer, ctor); const QString type = getType(interface, memInitializer, ctor);
@@ -3032,9 +3035,10 @@ void InsertMemberFromInitialization::match(const CppQuickFixInterface &interface
const QString member = QString::fromUtf8(memberId->chars(), memberId->size()); const QString member = QString::fromUtf8(memberId->chars(), memberId->size());
result << new InsertMemberFromInitializationOp(interface, theClass, member, type); result << new InsertMemberFromInitializationOp(interface, theClass, member, type);
return false;
} }
QString InsertMemberFromInitialization::getType( QString AddDeclarationForUndeclaredIdentifier::getType(
const CppQuickFixInterface &interface, const CppQuickFixInterface &interface,
const MemInitializerAST *memInitializer, const MemInitializerAST *memInitializer,
const FunctionDefinitionAST *ctor) const const FunctionDefinitionAST *ctor) const
@@ -9072,7 +9076,6 @@ void createCppQuickFixes()
new SplitIfStatement; new SplitIfStatement;
new SplitSimpleDeclaration; new SplitSimpleDeclaration;
new AddLocalDeclaration;
new AddBracesToIf; new AddBracesToIf;
new RearrangeParamDeclarationList; new RearrangeParamDeclarationList;
new ReformatPointerDeclaration; new ReformatPointerDeclaration;
@@ -9089,7 +9092,7 @@ void createCppQuickFixes()
new GenerateGettersSettersForClass; new GenerateGettersSettersForClass;
new InsertDeclFromDef; new InsertDeclFromDef;
new InsertDefFromDecl; new InsertDefFromDecl;
new InsertMemberFromInitialization; new AddDeclarationForUndeclaredIdentifier;
new InsertDefsFromDecls; new InsertDefsFromDecls;
new MoveFuncDefOutside; new MoveFuncDefOutside;

View File

@@ -284,23 +284,6 @@ public:
void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override;
}; };
/*!
Rewrites
a = foo();
As
Type a = foo();
Where Type is the return type of foo()
Activates on: the assignee, if the type of the right-hand side of the assignment is known.
*/
class AddLocalDeclaration: public CppQuickFixFactory
{
public:
void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override;
};
/*! /*!
Add curly braces to a if statement that doesn't already contain a Add curly braces to a if statement that doesn't already contain a
compound statement. I.e. compound statement. I.e.
@@ -374,16 +357,17 @@ public:
void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override;
}; };
/*! class AddDeclarationForUndeclaredIdentifier : public CppQuickFixFactory
Adds a class member from an initialization in the constructor.
*/
class InsertMemberFromInitialization : public CppQuickFixFactory
{ {
public: public:
void match(const CppQuickFixInterface &interface, void match(const CppQuickFixInterface &interface,
TextEditor::QuickFixOperations &result) override; TextEditor::QuickFixOperations &result) override;
private: private:
// Returns whether to still do other checks.
bool checkForMemberInitializer(const CppQuickFixInterface &interface,
TextEditor::QuickFixOperations &result);
QString getType( QString getType(
const CppQuickFixInterface &interface, const CppQuickFixInterface &interface,
const CPlusPlus::MemInitializerAST *memInitializer, const CPlusPlus::MemInitializerAST *memInitializer,