CppEditor: Fix "decl from def" quickfix with templated return type

We must treat return and parameters types of the function differently
from the function itself with regards to template parameters. This was
already done for parameters, but not for the return type.

Fixes: QTCREATORBUG-26248
Change-Id: I44cf6f0bda7b5e3c38f9f73e13f51f2c12ab7dc4
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Christian Kandeler
2021-09-10 16:37:50 +02:00
parent 1faff324cd
commit 50046dbc54
4 changed files with 39 additions and 11 deletions

View File

@@ -427,8 +427,15 @@ void TypePrettyPrinter::visit(Function *type)
_name.clear();
}
Overview retAndArgOverview;
retAndArgOverview.starBindFlags = _overview->starBindFlags;
retAndArgOverview.showReturnTypes = true;
retAndArgOverview.showArgumentNames = false;
retAndArgOverview.showFunctionSignatures = true;
retAndArgOverview.showTemplateParameters = true;
if (_overview->showReturnTypes) {
const QString returnType = _overview->prettyType(type->returnType());
const QString returnType = retAndArgOverview.prettyType(type->returnType());
if (!returnType.isEmpty()) {
if (!endsWithPtrOrRef(returnType) || !(_overview->starBindFlags & Overview::BindToIdentifier))
_text.prepend(QLatin1Char(' '));
@@ -463,13 +470,6 @@ void TypePrettyPrinter::visit(Function *type)
}
if (_overview->showFunctionSignatures) {
Overview argumentText;
argumentText.starBindFlags = _overview->starBindFlags;
argumentText.showReturnTypes = true;
argumentText.showArgumentNames = false;
argumentText.showFunctionSignatures = true;
argumentText.showTemplateParameters = _overview->showTemplateParameters;
_text += QLatin1Char('(');
for (int index = 0, argc = type->argumentCount(); index < argc; ++index) {
@@ -485,7 +485,7 @@ void TypePrettyPrinter::visit(Function *type)
if (_overview->showArgumentNames)
name = arg->name();
_text += argumentText.prettyType(arg->type(), name);
_text += retAndArgOverview.prettyType(arg->type(), name);
if (_overview->showDefaultArguments) {
if (const StringLiteral *initializer = arg->initializer()) {

View File

@@ -4614,7 +4614,7 @@ void QuickfixTest::testInsertDefFromDeclTemplateFunction()
"};\n"
"\n"
"template<class T>\n"
"void Foo::func<T>()\n"
"void Foo::func()\n"
"{\n"
"\n"
"}\n";
@@ -4939,6 +4939,28 @@ void QuickfixTest::testInsertDeclFromDefTemplateFuncInt()
QuickFixOperationTest(singleDocument(original, expected), &factory, {}, 0);
}
void QuickfixTest::testInsertDeclFromDefTemplateReturnType()
{
QByteArray original =
"class Foo\n"
"{\n"
"};\n"
"\n"
"std::vector<int> Foo::fu@nc() const {}\n";
QByteArray expected =
"class Foo\n"
"{\n"
"public:\n"
" std::vector<int> func() const;\n"
"};\n"
"\n"
"std::vector<int> Foo::func() const {}\n";
InsertDeclFromDef factory;
QuickFixOperationTest(singleDocument(original, expected), &factory, {}, 0);
}
void QuickfixTest::testInsertDeclFromDefNotTriggeredForTemplateFunc()
{
QByteArray contents =

View File

@@ -161,6 +161,7 @@ private slots:
void testInsertDeclFromDef();
void testInsertDeclFromDefTemplateFuncTypename();
void testInsertDeclFromDefTemplateFuncInt();
void testInsertDeclFromDefTemplateReturnType();
void testInsertDeclFromDefNotTriggeredForTemplateFunc();
void testAddIncludeForUndefinedIdentifier_data();

View File

@@ -2734,7 +2734,12 @@ public:
oo.showReturnTypes = true;
oo.showArgumentNames = true;
oo.showEnclosingTemplate = true;
oo.showTemplateParameters = true;
// What we really want is to show template parameters for the class, but not for the
// function, but we cannot express that. This is an approximation that will work
// as long as either the surrounding class or the function is not a template.
oo.showTemplateParameters = decl->enclosingClass()
&& decl->enclosingClass()->enclosingTemplate();
if (defPos == DefPosInsideClass) {
const int targetPos = targetFile->position(loc.line(), loc.column());