forked from qt-creator/qt-creator
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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user