diff options
author | Przemyslaw Gorszkowski <pgorszkowski@gmail.com> | 2017-06-19 18:51:26 +0200 |
---|---|---|
committer | Przemyslaw Gorszkowski <pgorszkowski@gmail.com> | 2017-06-23 11:47:24 +0000 |
commit | c6771c39c1b19d30a0e60b5ecc43e0abab44bfc9 (patch) | |
tree | cea1697c68b3bb95bc5f82b45d7d6d224039cfbe | |
parent | a9eb1d39c8bfd4133da030bc9c0a4b9c9cbee476 (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.cpp | 32 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfixes.cpp | 71 |
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. |