summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@digia.com>2014-10-07 15:15:04 +0200
committerNikolai Kosjar <nikolai.kosjar@digia.com>2014-10-08 15:48:47 +0200
commit2db588f8c514ad33a7171c7ad3e736ac38eda9e7 (patch)
tree060410056e90635e99cefceed1e4f6520b9dc84c
parent57279c0d0fbcf4e75ec2ae6aba0a3c1983365898 (diff)
downloadqt-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.h2
-rw-r--r--src/plugins/cppeditor/cppquickfix_test.cpp78
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp27
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;