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;
|
QuickFixOperations operations;
|
||||||
factory->match(quickFixInterface, operations);
|
factory->match(quickFixInterface, operations);
|
||||||
if (operations.isEmpty()) {
|
if (operations.isEmpty()) {
|
||||||
QEXPECT_FAIL("onBaseOfQualifiedClassName", "QTCREATORBUG-14499", Continue);
|
|
||||||
QVERIFY(testDocuments.first()->m_expectedSource.isEmpty());
|
QVERIFY(testDocuments.first()->m_expectedSource.isEmpty());
|
||||||
return;
|
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
|
// Header File
|
||||||
original = "namespace N { template <typename T> class Foo {}; }\n";
|
original = "namespace N { template <typename T> class Foo {}; }\n";
|
||||||
expected = original;
|
expected = original;
|
||||||
|
|||||||
@@ -1872,24 +1872,6 @@ QString templateNameAsString(const TemplateNameId *templateName)
|
|||||||
return QString::fromUtf8(id->chars(), id->size());
|
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 forwardingHeaders(const CppQuickFixInterface &interface)
|
||||||
{
|
{
|
||||||
Snapshot result;
|
Snapshot result;
|
||||||
@@ -1909,6 +1891,44 @@ bool looksLikeAQtClass(const QString &identifier)
|
|||||||
&& identifier.at(1).isUpper();
|
&& 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
|
} // anonymous namespace
|
||||||
|
|
||||||
void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interface,
|
void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interface,
|
||||||
@@ -1921,20 +1941,14 @@ void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interfa
|
|||||||
if (canLookupDefinition(interface, nameAst))
|
if (canLookupDefinition(interface, nameAst))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QString className = unqualifiedNameForLocator(nameAst->name);
|
QString className;
|
||||||
if (className.isEmpty())
|
QList<Core::LocatorFilterEntry> matches;
|
||||||
return;
|
|
||||||
|
|
||||||
const QString currentDocumentFilePath = interface.semanticInfo().doc->fileName();
|
const QString currentDocumentFilePath = interface.semanticInfo().doc->fileName();
|
||||||
const ProjectPartHeaderPaths headerPaths = relevantHeaderPaths(currentDocumentFilePath);
|
const ProjectPartHeaderPaths headerPaths = relevantHeaderPaths(currentDocumentFilePath);
|
||||||
bool qtHeaderFileIncludeOffered = false;
|
bool qtHeaderFileIncludeOffered = false;
|
||||||
|
|
||||||
// Find an include file through the locator
|
// Find an include file through the locator
|
||||||
if (CppClassesFilter *classesFilter
|
if (matchName(nameAst->name, &matches, &className)) {
|
||||||
= ExtensionSystem::PluginManager::getObject<CppClassesFilter>()) {
|
|
||||||
QFutureInterface<Core::LocatorFilterEntry> dummy;
|
|
||||||
const QList<Core::LocatorFilterEntry> matches = classesFilter->matchesFor(dummy, className);
|
|
||||||
|
|
||||||
const Snapshot forwardHeaders = forwardingHeaders(interface);
|
const Snapshot forwardHeaders = forwardingHeaders(interface);
|
||||||
foreach (const Core::LocatorFilterEntry &entry, matches) {
|
foreach (const Core::LocatorFilterEntry &entry, matches) {
|
||||||
IndexItem::Ptr info = entry.internalData.value<IndexItem::Ptr>();
|
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.
|
// 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
|
// As such, it will not be findable via locator. At least for Qt classes, check also for
|
||||||
// headers with the same name.
|
// headers with the same name.
|
||||||
|
|||||||
Reference in New Issue
Block a user