diff options
author | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2014-10-07 15:15:04 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@digia.com> | 2014-10-08 15:48:47 +0200 |
commit | 2db588f8c514ad33a7171c7ad3e736ac38eda9e7 (patch) | |
tree | 060410056e90635e99cefceed1e4f6520b9dc84c | |
parent | 57279c0d0fbcf4e75ec2ae6aba0a3c1983365898 (diff) | |
download | qt-creator-2db588f8c514ad33a7171c7ad3e736ac38eda9e7.tar.gz |
CppEditor: Make AddIncludeForUndefinedIdentifier work on template name ids
Task-number: QTCREATORBUG-9704
Change-Id: Ib08c331364fbfcb6e3fb9971d45e8b27311143ae
Reviewed-by: Christian Stenger <christian.stenger@digia.com>
-rw-r--r-- | src/plugins/cppeditor/cppeditorplugin.h | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfix_test.cpp | 78 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfixes.cpp | 27 |
3 files changed, 102 insertions, 5 deletions
diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index b203caa97a..bf76e9a22a 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -151,6 +151,8 @@ private slots: void test_quickfix_AddIncludeForUndefinedIdentifier_onSimpleName(); void test_quickfix_AddIncludeForUndefinedIdentifier_onNameOfQualifiedName(); 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_sortingTop(); void test_quickfix_AddIncludeForUndefinedIdentifier_inserting_sortingMiddle(); diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 2f0b55a467..7a5594344b 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -2325,6 +2325,84 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_onBaseOfQua 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 void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_inserting_ignoremoc() { diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 97bc4cb3ce..829045f83a 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -1910,6 +1910,10 @@ NameAST *nameUnderCursor(const QList<AST *> &path) AST * const ast = path.at(i); if (SimpleNameAST *simpleName = ast->asSimpleName()) { 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()) { nameAst = qualifiedName; break; @@ -1937,15 +1941,28 @@ bool canLookup(const CppQuickFixInterface &interface, const NameAST *nameAst) 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()); const Overview oo; - if (const QualifiedNameId *qualifiedName = name->asQualifiedNameId()) - return oo.prettyName(qualifiedName->name()); - else + if (const QualifiedNameId *qualifiedName = name->asQualifiedNameId()) { + const Name *name = qualifiedName->name(); + if (const TemplateNameId *templateName = name->asTemplateNameId()) + return templateNameAsString(templateName); return oo.prettyName(name); + } else if (const TemplateNameId *templateName = name->asTemplateNameId()) { + return templateNameAsString(templateName); + } else { + return oo.prettyName(name); + } } } // anonymous namespace @@ -1964,7 +1981,7 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa if (canLookup(interface, nameAst)) return; // There are results, so include isn't needed - const QString className = unqualifiedName(nameAst->name); + const QString className = unqualifiedNameForLocator(nameAst->name); if (className.isEmpty()) return; |