std::string clazy::getMostNeededQualifiedName()

in src/ContextUtils.cpp [53:115]


std::string clazy::getMostNeededQualifiedName(const SourceManager &sourceManager,
                                              CXXMethodDecl *method,
                                              DeclContext *currentScope,
                                              SourceLocation usageLoc,
                                              bool honourUsingDirectives)
{
    if (!currentScope) {
        return method->getQualifiedNameAsString();
    }

    // All namespaces, classes, inner class qualifications
    auto methodContexts = clazy::contextsForDecl(method->getDeclContext());

    // Visible scopes in current scope
    auto visibleContexts = clazy::contextsForDecl(currentScope);

    // Collect using directives
    std::vector<UsingDirectiveDecl *> usings;
    if (honourUsingDirectives) {
        for (DeclContext *context : visibleContexts) {
            clazy::append(context->using_directives(), usings);
        }
    }

    for (UsingDirectiveDecl *u : usings) {
        NamespaceDecl *ns = u->getNominatedNamespace();
        if (ns) {
            if (sourceManager.isBeforeInSLocAddrSpace(usageLoc, u->getBeginLoc())) {
                continue;
            }
#if LLVM_VERSION_MAJOR >= 19
            visibleContexts.push_back(ns->getFirstDecl());
#else

            visibleContexts.push_back(ns->getOriginalNamespace());
#endif
        }
    }

    for (DeclContext *context : visibleContexts) {
        if (context != method->getParent()) { // Don't remove the most immediate
            auto it = clazy::find_if(methodContexts, [context](DeclContext *c) {
                if (c == context) {
                    return true;
                }
                auto *ns1 = dyn_cast<NamespaceDecl>(c);
                auto *ns2 = dyn_cast<NamespaceDecl>(context);
                return ns1 && ns2 && ns1->getQualifiedNameAsString() == ns2->getQualifiedNameAsString();
            });
            if (it != methodContexts.end()) {
                methodContexts.erase(it, it + 1);
            }
        }
    }

    std::string neededContexts;
    for (DeclContext *context : methodContexts) {
        neededContexts = nameForContext(context) + "::" + neededContexts;
    }

    const std::string result = neededContexts + method->getNameAsString();
    return result;
}