forked from qt-creator/qt-creator
CppEditor: Another name minimalization fix
... involving using declarations.
See also aae3ce15aa
.
Fixes: QTCREATORBUG-28386
Change-Id: I4171dce7b4e34b41c4a894e3bb34b3f62f82ac0f
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -229,11 +229,11 @@ static bool isInlineNamespace(ClassOrNamespace *con, const Name *name)
|
||||
const Name *LookupContext::minimalName(Symbol *symbol, ClassOrNamespace *target, Control *control)
|
||||
{
|
||||
const Name *n = nullptr;
|
||||
std::optional<QList<const Name *>> minimal;
|
||||
QList<const Name *> names = LookupContext::fullyQualifiedName(symbol);
|
||||
ClassOrNamespace *current = target;
|
||||
|
||||
const auto getNameFromItems = [symbol, target, control](const QList<LookupItem> &items,
|
||||
const QList<const Name *> &names) -> const Name * {
|
||||
const QList<const Name *> &names) -> std::optional<QList<const Name *>> {
|
||||
for (const LookupItem &item : items) {
|
||||
if (!symbol->asUsingDeclaration() && !symbolIdentical(item.declaration(), symbol))
|
||||
continue;
|
||||
@@ -246,41 +246,54 @@ const Name *LookupContext::minimalName(Symbol *symbol, ClassOrNamespace *target,
|
||||
minimal.removeAt(i);
|
||||
}
|
||||
|
||||
return control->toName(minimal);
|
||||
return minimal;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return {};
|
||||
};
|
||||
|
||||
for (int i = names.size() - 1; i >= 0; --i) {
|
||||
if (! n)
|
||||
n = names.at(i);
|
||||
else
|
||||
n = control->qualifiedNameId(names.at(i), n);
|
||||
do {
|
||||
ClassOrNamespace *current = target;
|
||||
n = nullptr;
|
||||
|
||||
// once we're qualified enough to get the same symbol, break
|
||||
if (target) {
|
||||
const Name * const minimal = getNameFromItems(target->lookup(n), names.mid(i));
|
||||
if (minimal)
|
||||
return minimal;
|
||||
}
|
||||
if (current) {
|
||||
const ClassOrNamespace * const nested = current->getNested(names.last());
|
||||
if (nested) {
|
||||
const QList<const Name *> nameList
|
||||
= names.mid(0, names.size() - i - 1) << names.last();
|
||||
const QList<ClassOrNamespace *> usings = nested->usings();
|
||||
for (ClassOrNamespace * const u : usings) {
|
||||
const Name * const minimal = getNameFromItems(u->lookup(symbol->name()),
|
||||
nameList);
|
||||
if (minimal)
|
||||
return minimal;
|
||||
for (int i = names.size() - 1; i >= 0; --i) {
|
||||
if (! n)
|
||||
n = names.at(i);
|
||||
else
|
||||
n = control->qualifiedNameId(names.at(i), n);
|
||||
|
||||
if (target) {
|
||||
const auto candidate = getNameFromItems(target->lookup(n), names.mid(i));
|
||||
if (candidate && (!minimal || minimal->size() > candidate->size())) {
|
||||
minimal = candidate;
|
||||
if (minimal && minimal->size() == 1)
|
||||
return control->toName(*minimal);
|
||||
}
|
||||
}
|
||||
current = current->getNested(names.at(names.size() - i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (current) {
|
||||
const ClassOrNamespace * const nested = current->getNested(names.last());
|
||||
if (nested) {
|
||||
const QList<const Name *> nameList
|
||||
= names.mid(0, names.size() - i - 1) << names.last();
|
||||
const QList<ClassOrNamespace *> usings = nested->usings();
|
||||
for (ClassOrNamespace * const u : usings) {
|
||||
const auto candidate = getNameFromItems(u->lookup(symbol->name()), nameList);
|
||||
if (candidate && (!minimal || minimal->size() > candidate->size())) {
|
||||
minimal = candidate;
|
||||
if (minimal && minimal->size() == 1)
|
||||
return control->toName(*minimal);
|
||||
}
|
||||
}
|
||||
}
|
||||
current = current->getNested(names.at(names.size() - i - 1));
|
||||
}
|
||||
}
|
||||
if (target)
|
||||
target = target->parent();
|
||||
} while (target);
|
||||
|
||||
if (minimal)
|
||||
return control->toName(*minimal);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@@ -4555,6 +4555,39 @@ D::D()
|
||||
)";
|
||||
testDocuments << CppTestDocument::create("file.cpp", original, expected);
|
||||
QuickFixOperationTest(testDocuments, &factory);
|
||||
|
||||
testDocuments.clear();
|
||||
original = R"(
|
||||
namespace ns1 { template<typename T> class span {}; }
|
||||
|
||||
namespace ns {
|
||||
using ns1::span;
|
||||
class foo
|
||||
{
|
||||
void @bar(ns::span<int>);
|
||||
};
|
||||
}
|
||||
)";
|
||||
expected = R"(
|
||||
namespace ns1 { template<typename T> class span {}; }
|
||||
|
||||
namespace ns {
|
||||
using ns1::span;
|
||||
class foo
|
||||
{
|
||||
void bar(ns::span<int>);
|
||||
};
|
||||
|
||||
void foo::bar(ns::span<int>)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
)";
|
||||
// TODO: Unneeded namespace gets inserted in RewriteName::visit(const QualifiedNameId *)
|
||||
testDocuments << CppTestDocument::create("file.cpp", original, expected);
|
||||
QuickFixOperationTest(testDocuments, &factory);
|
||||
}
|
||||
|
||||
/// Find right implementation file. (QTCREATORBUG-10728)
|
||||
|
Reference in New Issue
Block a user