forked from qt-creator/qt-creator
CppEditor: Fix quickfix for adding include for static functions
Task-number: QTCREATORBUG-14499 Change-Id: Id3e962ed310f43c33b91c7834a1f9ca074519a38 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -3031,6 +3030,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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user