summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2019-12-04 09:53:26 +0100
committerDavid Schulz <david.schulz@qt.io>2020-01-08 09:21:25 +0000
commit1ab9dc946410e96e0e211347e9d9127740ab18dd (patch)
tree779341b2d2817194c978ab78d544e2635e054494
parent15734ac5eb5b7b55916aca7b83a85ed8b6c793c1 (diff)
downloadqt-creator-1ab9dc946410e96e0e211347e9d9127740ab18dd.tar.gz
CppEditor: generate valid code via "Convert to Pointer/Stack Variable"
Adding a "= new <TypeName>" after converting a stack variable without assignment or initializer to pointer. Also remove the assignment when converting from pointer to stack variable as this works better with explicit constructors. Fixes: QTCREATORBUG-23181 Change-Id: I377ec32a1b66cf4b96db14cfcb4b71fb96c80c98 Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r--doc/src/editors/creator-code-refactoring.qdoc2
-rw-r--r--src/plugins/cppeditor/cppquickfix_test.cpp45
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp50
3 files changed, 74 insertions, 23 deletions
diff --git a/doc/src/editors/creator-code-refactoring.qdoc b/doc/src/editors/creator-code-refactoring.qdoc
index 8120a0543c..f333c92bc4 100644
--- a/doc/src/editors/creator-code-refactoring.qdoc
+++ b/doc/src/editors/creator-code-refactoring.qdoc
@@ -755,7 +755,7 @@
as
\code
- QByteArray foo = "foo";
+ QByteArray foo("foo");
foo.append("bar");
\endcode
diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp
index 63f1290b6a..e75464d2b5 100644
--- a/src/plugins/cppeditor/cppquickfix_test.cpp
+++ b/src/plugins/cppeditor/cppquickfix_test.cpp
@@ -1578,7 +1578,7 @@ void CppEditorPlugin::test_quickfix_data()
" f2(&str);\n"
"}\n")
<< _("void foo() {\n"
- " QString *str;\n"
+ " QString *str = new QString;\n"
" if (!str->isEmpty())\n"
" str->clear();\n"
" f1(*str);\n"
@@ -1612,7 +1612,7 @@ void CppEditorPlugin::test_quickfix_data()
" str->clear();\n"
"}\n")
<< _("void foo() {\n"
- " QString str = QLatin1String(\"schnurz\");\n"
+ " QString str(QLatin1String(\"schnurz\"));\n"
" if (!str.isEmpty())\n"
" str.clear();\n"
"}\n");
@@ -1731,7 +1731,7 @@ void CppEditorPlugin::test_quickfix_data()
" f1(str);\n"
"}\n")
<< _("void foo() {\n"
- " QString *str;\n"
+ " QString *str = new QString;\n"
" str->clear();\n"
" {\n"
" QString str;\n"
@@ -1808,6 +1808,45 @@ void CppEditorPlugin::test_quickfix_data()
" BAR = *foo;\n"
"}\n");
+ QString testObjAndFunc = "struct Object\n"
+ "{\n"
+ " Object(%1){}\n"
+ "};\n"
+ "void func()\n"
+ "{\n"
+ " %2\n"
+ "}\n";
+
+ QTest::newRow("ConvertToStack1_QTCREATORBUG23181")
+ << CppQuickFixFactoryPtr(new ConvertFromAndToPointer)
+ << _(testObjAndFunc.arg("int").arg("Object *@obj = new Object(0);").toUtf8())
+ << _(testObjAndFunc.arg("int").arg("Object obj(0);").toUtf8());
+
+ QTest::newRow("ConvertToStack2_QTCREATORBUG23181")
+ << CppQuickFixFactoryPtr(new ConvertFromAndToPointer)
+ << _(testObjAndFunc.arg("int").arg("Object *@obj = new Object{0};").toUtf8())
+ << _(testObjAndFunc.arg("int").arg("Object obj{0};").toUtf8());
+
+ QTest::newRow("ConvertToPointer1_QTCREATORBUG23181")
+ << CppQuickFixFactoryPtr(new ConvertFromAndToPointer)
+ << _(testObjAndFunc.arg("").arg("Object @obj;").toUtf8())
+ << _(testObjAndFunc.arg("").arg("Object *obj = new Object;").toUtf8());
+
+ QTest::newRow("ConvertToPointer2_QTCREATORBUG23181")
+ << CppQuickFixFactoryPtr(new ConvertFromAndToPointer)
+ << _(testObjAndFunc.arg("").arg("Object @obj();").toUtf8())
+ << _(testObjAndFunc.arg("").arg("Object *obj = new Object();").toUtf8());
+
+ QTest::newRow("ConvertToPointer3_QTCREATORBUG23181")
+ << CppQuickFixFactoryPtr(new ConvertFromAndToPointer)
+ << _(testObjAndFunc.arg("").arg("Object @obj{};").toUtf8())
+ << _(testObjAndFunc.arg("").arg("Object *obj = new Object{};").toUtf8());
+
+ QTest::newRow("ConvertToPointer4_QTCREATORBUG23181")
+ << CppQuickFixFactoryPtr(new ConvertFromAndToPointer)
+ << _(testObjAndFunc.arg("int").arg("Object @obj(0);").toUtf8())
+ << _(testObjAndFunc.arg("int").arg("Object *obj = new Object(0);").toUtf8());
+
QTest::newRow("InsertQtPropertyMembers_noTriggerInvalidCode")
<< CppQuickFixFactoryPtr(new InsertQtPropertyMembers)
<< _("class C { @Q_PROPERTY(typeid foo READ foo) };\n")
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index d384322bdd..c3c93f7a5e 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -4153,20 +4153,21 @@ private:
void removeNewExpression(ChangeSet &changes, NewExpressionAST *newExprAST) const
{
- ExpressionListParenAST *exprlist = newExprAST->new_initializer
- ? newExprAST->new_initializer->asExpressionListParen()
- : nullptr;
+ ExpressionListAST *exprlist = nullptr;
+ if (newExprAST->new_initializer) {
+ if (ExpressionListParenAST *ast = newExprAST->new_initializer->asExpressionListParen())
+ exprlist = ast->expression_list;
+ else if (BracedInitializerAST *ast = newExprAST->new_initializer->asBracedInitializer())
+ exprlist = ast->expression_list;
+ }
- if (exprlist && exprlist->expression_list) {
+ if (exprlist) {
// remove 'new' keyword and type before initializer
changes.remove(m_file->startOf(newExprAST->new_token),
m_file->startOf(newExprAST->new_initializer));
- // remove parenthesis around initializer
- int pos = m_file->startOf(exprlist->lparen_token);
- changes.remove(pos, pos + 1);
- pos = m_file->startOf(exprlist->rparen_token);
- changes.remove(pos, pos + 1);
+ changes.remove(m_file->endOf(m_declaratorAST->equal_token - 1),
+ m_file->startOf(m_declaratorAST->equal_token + 1));
} else {
// remove the whole new expression
changes.remove(m_file->endOf(m_identifierAST->firstToken()),
@@ -4272,24 +4273,30 @@ private:
return overview.prettyName(namedType->name->name);
}
- void insertNewExpression(ChangeSet &changes, CallAST *callAST) const
+ void insertNewExpression(ChangeSet &changes, ExpressionAST *ast) const
{
const QString typeName = typeNameOfDeclaration();
- if (typeName.isEmpty()) {
- changes.insert(m_file->startOf(callAST), QLatin1String("new "));
+ if (CallAST *callAST = ast->asCall()) {
+ if (typeName.isEmpty()) {
+ changes.insert(m_file->startOf(callAST), QLatin1String("new "));
+ } else {
+ changes.insert(m_file->startOf(callAST),
+ QLatin1String("new ") + typeName + QLatin1Char('('));
+ changes.insert(m_file->startOf(callAST->lastToken()), QLatin1String(")"));
+ }
} else {
- changes.insert(m_file->startOf(callAST),
- QLatin1String("new ") + typeName + QLatin1Char('('));
- changes.insert(m_file->startOf(callAST->lastToken()), QLatin1String(")"));
+ if (typeName.isEmpty())
+ return;
+ changes.insert(m_file->startOf(ast), QLatin1String(" = new ") + typeName);
}
}
- void insertNewExpression(ChangeSet &changes, ExpressionListParenAST *exprListAST) const
+ void insertNewExpression(ChangeSet &changes) const
{
const QString typeName = typeNameOfDeclaration();
if (typeName.isEmpty())
return;
- changes.insert(m_file->startOf(exprListAST),
+ changes.insert(m_file->endOf(m_identifierAST->firstToken()),
QLatin1String(" = new ") + typeName);
}
@@ -4301,10 +4308,15 @@ private:
changes.insert(m_file->startOf(idExprAST), QLatin1String("&"));
} else if (CallAST *callAST = m_declaratorAST->initializer->asCall()) {
insertNewExpression(changes, callAST);
- } else if (ExpressionListParenAST *exprListAST
- = m_declaratorAST->initializer->asExpressionListParen()) {
+ } else if (ExpressionListParenAST *exprListAST = m_declaratorAST->initializer
+ ->asExpressionListParen()) {
insertNewExpression(changes, exprListAST);
+ } else if (BracedInitializerAST *bracedInitializerAST = m_declaratorAST->initializer
+ ->asBracedInitializer()) {
+ insertNewExpression(changes, bracedInitializerAST);
}
+ } else {
+ insertNewExpression(changes);
}
// Fix all occurrences of the identifier in this function.