forked from qt-creator/qt-creator
CppEditor: Fix AssignToLocalVariable
Make calls like a->b()->c() assignable to a local variable. Task-number: QTCREATORBUG-10355 Change-Id: If4a55b435c99150710d00567188f901acb2c1a89 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
@@ -1050,6 +1050,42 @@ void CppEditorPlugin::test_quickfix_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Check: Add local variable for a member function, cursor in the middle (QTCREATORBUG-10355)
|
||||||
|
QTest::newRow("AssignToLocalVariable_memberFunction2ndGrade1")
|
||||||
|
<< CppQuickFixFactoryPtr(new AssignToLocalVariable) << _(
|
||||||
|
"struct Foo {int* func();};\n"
|
||||||
|
"struct Baz {Foo* foo();};\n"
|
||||||
|
"void bar() {\n"
|
||||||
|
" Baz *b = new Baz;\n"
|
||||||
|
" b->foo@()->func();\n"
|
||||||
|
"}"
|
||||||
|
) << _(
|
||||||
|
"struct Foo {int* func();};\n"
|
||||||
|
"struct Baz {Foo* foo();};\n"
|
||||||
|
"void bar() {\n"
|
||||||
|
" Baz *b = new Baz;\n"
|
||||||
|
" int *localFunc = b->foo()->func();\n"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check: Add local variable for a member function, cursor on function call (QTCREATORBUG-10355)
|
||||||
|
QTest::newRow("AssignToLocalVariable_memberFunction2ndGrade2")
|
||||||
|
<< CppQuickFixFactoryPtr(new AssignToLocalVariable) << _(
|
||||||
|
"struct Foo {int* func();};\n"
|
||||||
|
"struct Baz {Foo* foo();};\n"
|
||||||
|
"void bar() {\n"
|
||||||
|
" Baz *b = new Baz;\n"
|
||||||
|
" b->foo()->f@unc();\n"
|
||||||
|
"}"
|
||||||
|
) << _(
|
||||||
|
"struct Foo {int* func();};\n"
|
||||||
|
"struct Baz {Foo* foo();};\n"
|
||||||
|
"void bar() {\n"
|
||||||
|
" Baz *b = new Baz;\n"
|
||||||
|
" int *localFunc = b->foo()->func();\n"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
|
||||||
// Check: Add local variable for a static member function.
|
// Check: Add local variable for a static member function.
|
||||||
QTest::newRow("AssignToLocalVariable_staticMemberFunction")
|
QTest::newRow("AssignToLocalVariable_staticMemberFunction")
|
||||||
<< CppQuickFixFactoryPtr(new AssignToLocalVariable) << _(
|
<< CppQuickFixFactoryPtr(new AssignToLocalVariable) << _(
|
||||||
|
@@ -4852,7 +4852,6 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
|||||||
const QList<AST *> &path = interface.path();
|
const QList<AST *> &path = interface.path();
|
||||||
AST *outerAST = 0;
|
AST *outerAST = 0;
|
||||||
SimpleNameAST *nameAST = 0;
|
SimpleNameAST *nameAST = 0;
|
||||||
SimpleNameAST *visibleNameAST = 0;
|
|
||||||
|
|
||||||
for (int i = path.size() - 3; i >= 0; --i) {
|
for (int i = path.size() - 3; i >= 0; --i) {
|
||||||
if (CallAST *callAST = path.at(i)->asCall()) {
|
if (CallAST *callAST = path.at(i)->asCall()) {
|
||||||
@@ -4866,6 +4865,10 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
|||||||
return;
|
return;
|
||||||
if (path.at(idx)->asMemInitializer())
|
if (path.at(idx)->asMemInitializer())
|
||||||
return;
|
return;
|
||||||
|
if (path.at(idx)->asCall()) { // Fallback if we have a->b()->c()...
|
||||||
|
--i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int a = i - 1; a > 0; --a) {
|
for (int a = i - 1; a > 0; --a) {
|
||||||
if (path.at(a)->asBinaryExpression())
|
if (path.at(a)->asBinaryExpression())
|
||||||
@@ -4877,21 +4880,15 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (MemberAccessAST *member = path.at(i + 1)->asMemberAccess()) { // member
|
if (MemberAccessAST *member = path.at(i + 1)->asMemberAccess()) { // member
|
||||||
if (member->base_expression) {
|
if (NameAST *name = member->member_name)
|
||||||
if (IdExpressionAST *idex = member->base_expression->asIdExpression()) {
|
nameAST = name->asSimpleName();
|
||||||
nameAST = idex->name->asSimpleName();
|
|
||||||
visibleNameAST = member->member_name->asSimpleName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (QualifiedNameAST *qname = path.at(i + 2)->asQualifiedName()) { // static or
|
} else if (QualifiedNameAST *qname = path.at(i + 2)->asQualifiedName()) { // static or
|
||||||
nameAST = qname->unqualified_name->asSimpleName(); // func in ns
|
nameAST = qname->unqualified_name->asSimpleName(); // func in ns
|
||||||
visibleNameAST = nameAST;
|
|
||||||
} else { // normal
|
} else { // normal
|
||||||
nameAST = path.at(i + 2)->asSimpleName();
|
nameAST = path.at(i + 2)->asSimpleName();
|
||||||
visibleNameAST = nameAST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nameAST && visibleNameAST) {
|
if (nameAST) {
|
||||||
outerAST = callAST;
|
outerAST = callAST;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -4916,14 +4913,13 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
|||||||
|
|
||||||
if (NamedTypeSpecifierAST *ts = path.at(i + 2)->asNamedTypeSpecifier()) {
|
if (NamedTypeSpecifierAST *ts = path.at(i + 2)->asNamedTypeSpecifier()) {
|
||||||
nameAST = ts->name->asSimpleName();
|
nameAST = ts->name->asSimpleName();
|
||||||
visibleNameAST = nameAST;
|
|
||||||
outerAST = newexp;
|
outerAST = newexp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outerAST && nameAST && visibleNameAST) {
|
if (outerAST && nameAST) {
|
||||||
const CppRefactoringFilePtr file = interface.currentFile();
|
const CppRefactoringFilePtr file = interface.currentFile();
|
||||||
QList<LookupItem> items;
|
QList<LookupItem> items;
|
||||||
TypeOfExpression typeOfExpression;
|
TypeOfExpression typeOfExpression;
|
||||||
@@ -4962,7 +4958,7 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Name *name = visibleNameAST->name;
|
const Name *name = nameAST->name;
|
||||||
const int insertPos = interface.currentFile()->startOf(outerAST);
|
const int insertPos = interface.currentFile()->startOf(outerAST);
|
||||||
result.append(new AssignToLocalVariableOperation(interface, insertPos, outerAST, name));
|
result.append(new AssignToLocalVariableOperation(interface, insertPos, outerAST, name));
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user