diff options
author | David Schulz <david.schulz@qt.io> | 2019-12-04 09:53:26 +0100 |
---|---|---|
committer | David Schulz <david.schulz@qt.io> | 2020-01-08 09:21:25 +0000 |
commit | 1ab9dc946410e96e0e211347e9d9127740ab18dd (patch) | |
tree | 779341b2d2817194c978ab78d544e2635e054494 | |
parent | 15734ac5eb5b7b55916aca7b83a85ed8b6c793c1 (diff) | |
download | qt-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.qdoc | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfix_test.cpp | 45 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfixes.cpp | 50 |
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. |