forked from qt-creator/qt-creator
CppEditor: Make AddIncludeForUndefinedIdentifier work on template name ids
Task-number: QTCREATORBUG-9704 Change-Id: Ib08c331364fbfcb6e3fb9971d45e8b27311143ae Reviewed-by: Christian Stenger <christian.stenger@digia.com>
This commit is contained in:
@@ -151,6 +151,8 @@ private slots:
|
|||||||
void test_quickfix_AddIncludeForUndefinedIdentifier_onSimpleName();
|
void test_quickfix_AddIncludeForUndefinedIdentifier_onSimpleName();
|
||||||
void test_quickfix_AddIncludeForUndefinedIdentifier_onNameOfQualifiedName();
|
void test_quickfix_AddIncludeForUndefinedIdentifier_onNameOfQualifiedName();
|
||||||
void test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQualifiedName();
|
void test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQualifiedName();
|
||||||
|
void test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateName();
|
||||||
|
void test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateNameInsideArguments();
|
||||||
void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_ignoremoc();
|
void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_ignoremoc();
|
||||||
void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_sortingTop();
|
void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_sortingTop();
|
||||||
void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_sortingMiddle();
|
void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_sortingMiddle();
|
||||||
|
|||||||
@@ -2325,6 +2325,84 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQua
|
|||||||
QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath());
|
QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateName()
|
||||||
|
{
|
||||||
|
QList<QuickFixTestDocument::Ptr> testFiles;
|
||||||
|
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original = "namespace N { template <typename T> class Foo {}; }\n";
|
||||||
|
expected = original;
|
||||||
|
testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
|
||||||
|
+ "/afile.h", original, expected);
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
original =
|
||||||
|
"#include \"header.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" @N::Foo<Bar> foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
expected =
|
||||||
|
"#include \"afile.h\"\n"
|
||||||
|
"#include \"header.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" N::Foo<Bar> foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
|
||||||
|
+ "/afile.cpp", original, expected);
|
||||||
|
|
||||||
|
// Do not use the test factory, at least once we want to go through the "full stack".
|
||||||
|
AddIncludeForUndefinedIdentifier factory;
|
||||||
|
QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onTemplateNameInsideArguments()
|
||||||
|
{
|
||||||
|
QList<QuickFixTestDocument::Ptr> testFiles;
|
||||||
|
|
||||||
|
QByteArray original;
|
||||||
|
QByteArray expected;
|
||||||
|
|
||||||
|
// Header File
|
||||||
|
original = "namespace N { template <typename T> class Foo {}; }\n";
|
||||||
|
expected = original;
|
||||||
|
testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
|
||||||
|
+ "/afile.h", original, expected);
|
||||||
|
|
||||||
|
// Source File
|
||||||
|
original =
|
||||||
|
"#include \"header.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" N::Bar<@Foo> foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
expected =
|
||||||
|
"#include \"afile.h\"\n"
|
||||||
|
"#include \"header.h\"\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" N::Bar<Foo> foo;\n"
|
||||||
|
"}\n"
|
||||||
|
;
|
||||||
|
testFiles << QuickFixTestDocument::create(TestIncludePaths::directoryOfTestFile().toUtf8()
|
||||||
|
+ "/afile.cpp", original, expected);
|
||||||
|
|
||||||
|
// Do not use the test factory, at least once we want to go through the "full stack".
|
||||||
|
AddIncludeForUndefinedIdentifier factory;
|
||||||
|
QuickFixTestCase::run(testFiles, &factory, TestIncludePaths::globalIncludePath());
|
||||||
|
}
|
||||||
|
|
||||||
/// Check: Ignore *.moc includes
|
/// Check: Ignore *.moc includes
|
||||||
void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_ignoremoc()
|
void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_ignoremoc()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1910,6 +1910,10 @@ NameAST *nameUnderCursor(const QList<AST *> &path)
|
|||||||
AST * const ast = path.at(i);
|
AST * const ast = path.at(i);
|
||||||
if (SimpleNameAST *simpleName = ast->asSimpleName()) {
|
if (SimpleNameAST *simpleName = ast->asSimpleName()) {
|
||||||
nameAst = simpleName;
|
nameAst = simpleName;
|
||||||
|
} else if (TemplateIdAST *templateId = ast->asTemplateId()) {
|
||||||
|
nameAst = templateId;
|
||||||
|
} else if (nameAst && ast->asNamedTypeSpecifier()) {
|
||||||
|
break; // Stop at "Foo" for "N::Bar<@Foo>"
|
||||||
} else if (QualifiedNameAST *qualifiedName = ast->asQualifiedName()) {
|
} else if (QualifiedNameAST *qualifiedName = ast->asQualifiedName()) {
|
||||||
nameAst = qualifiedName;
|
nameAst = qualifiedName;
|
||||||
break;
|
break;
|
||||||
@@ -1937,15 +1941,28 @@ bool canLookup(const CppQuickFixInterface &interface, const NameAST *nameAst)
|
|||||||
return !existingResults.isEmpty();
|
return !existingResults.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString unqualifiedName(const Name *name)
|
QString templateNameAsString(const TemplateNameId *templateName)
|
||||||
|
{
|
||||||
|
const Identifier *id = templateName->identifier();
|
||||||
|
return QString::fromUtf8(id->chars(), id->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// For templates, simply the name is returned, without '<...>'.
|
||||||
|
QString unqualifiedNameForLocator(const Name *name)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(name, return QString());
|
QTC_ASSERT(name, return QString());
|
||||||
|
|
||||||
const Overview oo;
|
const Overview oo;
|
||||||
if (const QualifiedNameId *qualifiedName = name->asQualifiedNameId())
|
if (const QualifiedNameId *qualifiedName = name->asQualifiedNameId()) {
|
||||||
return oo.prettyName(qualifiedName->name());
|
const Name *name = qualifiedName->name();
|
||||||
else
|
if (const TemplateNameId *templateName = name->asTemplateNameId())
|
||||||
|
return templateNameAsString(templateName);
|
||||||
return oo.prettyName(name);
|
return oo.prettyName(name);
|
||||||
|
} else if (const TemplateNameId *templateName = name->asTemplateNameId()) {
|
||||||
|
return templateNameAsString(templateName);
|
||||||
|
} else {
|
||||||
|
return oo.prettyName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
@@ -1964,7 +1981,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
|
|||||||
if (canLookup(interface, nameAst))
|
if (canLookup(interface, nameAst))
|
||||||
return; // There are results, so include isn't needed
|
return; // There are results, so include isn't needed
|
||||||
|
|
||||||
const QString className = unqualifiedName(nameAst->name);
|
const QString className = unqualifiedNameForLocator(nameAst->name);
|
||||||
if (className.isEmpty())
|
if (className.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user