aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2017-06-19 18:51:26 +0200
committerPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2017-06-23 11:47:24 +0000
commitc6771c39c1b19d30a0e60b5ecc43e0abab44bfc9 (patch)
treecea1697c68b3bb95bc5f82b45d7d6d224039cfbe
parenta9eb1d39c8bfd4133da030bc9c0a4b9c9cbee476 (diff)
CppEditor: Fix quickfix for adding include for static functions
Task-number: QTCREATORBUG-14499 Change-Id: Id3e962ed310f43c33b91c7834a1f9ca074519a38 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
-rw-r--r--src/plugins/cppeditor/cppquickfix_test.cpp32
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp71
2 files changed, 75 insertions, 28 deletions
diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp
index c1b2896846..7882fef70e 100644
--- a/src/plugins/cppeditor/cppquickfix_test.cpp
+++ b/src/plugins/cppeditor/cppquickfix_test.cpp
@@ -236,7 +236,6 @@ QuickFixOperationTest::QuickFixOperationTest(const QList<QuickFixTestDocument::P
QuickFixOperations operations;
factory->match(quickFixInterface, operations);
if (operations.isEmpty()) {
- QEXPECT_FAIL("onBaseOfQualifiedClassName", "QTCREATORBUG-14499", Continue);
QVERIFY(testDocuments.first()->m_expectedSource.isEmpty());
return;
}
@@ -3032,6 +3031,37 @@ void CppEditorPlugin::test_quickfix_AddIncludeForUndefinedIdentifier_data()
// -------------------------------------------------------------------------------------------
// Header File
+ original = "template <typename T> class Foo { static void bar() {} };\n";
+ expected = original;
+ testDocuments << QuickFixTestDocument::create("afile.h", original, expected);
+
+ // Source File
+ original =
+ "#include \"header.h\"\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " @Foo<int>::bar();\n"
+ "}\n"
+ ;
+ expected =
+ "#include \"afile.h\"\n"
+ "#include \"header.h\"\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " Foo<int>::bar();\n"
+ "}\n"
+ ;
+ testDocuments << QuickFixTestDocument::create("afile.cpp", original, expected);
+ QTest::newRow("onBaseOfQualifiedTemplateClassName")
+ << TestIncludePaths::globalIncludePath()
+ << testDocuments << firstRefactoringOperation << "";
+ testDocuments.clear();
+
+ // -------------------------------------------------------------------------------------------
+
+ // Header File
original = "namespace N { template <typename T> class Foo {}; }\n";
expected = original;
testDocuments << QuickFixTestDocument::create("afile.h", original, expected);
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index f4e0b72691..67d360c3bb 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -1872,24 +1872,6 @@ QString templateNameAsString(const TemplateNameId *templateName)
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()) {
- 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);
- }
-}
-
Snapshot forwardingHeaders(const CppQuickFixInterface &interface)
{
Snapshot result;
@@ -1909,6 +1891,44 @@ bool looksLikeAQtClass(const QString &identifier)
&& identifier.at(1).isUpper();
}
+bool matchName(const Name *name, QList<Core::LocatorFilterEntry> *matches, QString *className) {
+ if (!name)
+ return false;
+
+ if (CppClassesFilter *classesFilter
+ = ExtensionSystem::PluginManager::getObject<CppClassesFilter>()) {
+ QFutureInterface<Core::LocatorFilterEntry> dummy;
+
+ const Overview oo;
+ if (const QualifiedNameId *qualifiedName = name->asQualifiedNameId()) {
+ const Name *name = qualifiedName->name();
+ if (const TemplateNameId *templateName = name->asTemplateNameId()) {
+ *className = templateNameAsString(templateName);
+ } else {
+ *className = oo.prettyName(name);
+ *matches = classesFilter->matchesFor(dummy, *className);
+ if (matches->empty()) {
+ if (const Name *name = qualifiedName->base()) {
+ if (const TemplateNameId *templateName = name->asTemplateNameId())
+ *className = templateNameAsString(templateName);
+ else
+ *className = oo.prettyName(name);
+ }
+ }
+ }
+ } else if (const TemplateNameId *templateName = name->asTemplateNameId()) {
+ *className = templateNameAsString(templateName);
+ } else {
+ *className = oo.prettyName(name);
+ }
+
+ if (matches->empty())
+ *matches = classesFilter->matchesFor(dummy, *className);
+ }
+
+ return !matches->empty();
+}
+
} // anonymous namespace
void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interface,
@@ -1921,20 +1941,14 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
if (canLookupDefinition(interface, nameAst))
return;
- const QString className = unqualifiedNameForLocator(nameAst->name);
- if (className.isEmpty())
- return;
-
+ QString className;
+ QList<Core::LocatorFilterEntry> matches;
const QString currentDocumentFilePath = interface.semanticInfo().doc->fileName();
const ProjectPartHeaderPaths headerPaths = relevantHeaderPaths(currentDocumentFilePath);
bool qtHeaderFileIncludeOffered = false;
// Find an include file through the locator
- if (CppClassesFilter *classesFilter
- = ExtensionSystem::PluginManager::getObject<CppClassesFilter>()) {
- QFutureInterface<Core::LocatorFilterEntry> dummy;
- const QList<Core::LocatorFilterEntry> matches = classesFilter->matchesFor(dummy, className);
-
+ if (matchName(nameAst->name, &matches, &className)) {
const Snapshot forwardHeaders = forwardingHeaders(interface);
foreach (const Core::LocatorFilterEntry &entry, matches) {
IndexItem::Ptr info = entry.internalData.value<IndexItem::Ptr>();
@@ -1971,6 +1985,9 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
}
}
+ if (className.isEmpty())
+ return;
+
// The header file we are looking for might not be (yet) included in any file we have parsed.
// As such, it will not be findable via locator. At least for Qt classes, check also for
// headers with the same name.