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"
|
||||
);
|
||||
|
||||
// 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.
|
||||
QTest::newRow("AssignToLocalVariable_staticMemberFunction")
|
||||
<< CppQuickFixFactoryPtr(new AssignToLocalVariable) << _(
|
||||
|
@@ -4852,7 +4852,6 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
||||
const QList<AST *> &path = interface.path();
|
||||
AST *outerAST = 0;
|
||||
SimpleNameAST *nameAST = 0;
|
||||
SimpleNameAST *visibleNameAST = 0;
|
||||
|
||||
for (int i = path.size() - 3; i >= 0; --i) {
|
||||
if (CallAST *callAST = path.at(i)->asCall()) {
|
||||
@@ -4866,6 +4865,10 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
||||
return;
|
||||
if (path.at(idx)->asMemInitializer())
|
||||
return;
|
||||
if (path.at(idx)->asCall()) { // Fallback if we have a->b()->c()...
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (int a = i - 1; a > 0; --a) {
|
||||
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 (member->base_expression) {
|
||||
if (IdExpressionAST *idex = member->base_expression->asIdExpression()) {
|
||||
nameAST = idex->name->asSimpleName();
|
||||
visibleNameAST = member->member_name->asSimpleName();
|
||||
}
|
||||
}
|
||||
if (NameAST *name = member->member_name)
|
||||
nameAST = name->asSimpleName();
|
||||
} else if (QualifiedNameAST *qname = path.at(i + 2)->asQualifiedName()) { // static or
|
||||
nameAST = qname->unqualified_name->asSimpleName(); // func in ns
|
||||
visibleNameAST = nameAST;
|
||||
} else { // normal
|
||||
nameAST = path.at(i + 2)->asSimpleName();
|
||||
visibleNameAST = nameAST;
|
||||
}
|
||||
|
||||
if (nameAST && visibleNameAST) {
|
||||
if (nameAST) {
|
||||
outerAST = callAST;
|
||||
break;
|
||||
}
|
||||
@@ -4916,14 +4913,13 @@ void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFi
|
||||
|
||||
if (NamedTypeSpecifierAST *ts = path.at(i + 2)->asNamedTypeSpecifier()) {
|
||||
nameAST = ts->name->asSimpleName();
|
||||
visibleNameAST = nameAST;
|
||||
outerAST = newexp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outerAST && nameAST && visibleNameAST) {
|
||||
if (outerAST && nameAST) {
|
||||
const CppRefactoringFilePtr file = interface.currentFile();
|
||||
QList<LookupItem> items;
|
||||
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);
|
||||
result.append(new AssignToLocalVariableOperation(interface, insertPos, outerAST, name));
|
||||
return;
|
||||
|
Reference in New Issue
Block a user