Ejemplo n.º 1
0
int ListSymbolsJob::execute()
{
    Set<String> out;
    std::shared_ptr<Project> proj = project();
    if (proj) {
        if (queryFlags() & QueryMessage::WildcardSymbolNames
                && (string.contains('*') || string.contains('?')) && !string.endsWith('*')) {
            string += '*';
        }
        List<QueryMessage::PathFilter> filters = pathFilters();
        List<Path> paths;
        for (const auto &filter : filters) {
            if (filter.mode == QueryMessage::PathFilter::Self) {
                paths.append(filter.pattern);
                if (!paths.last().isFile()) {
                    paths.clear();
                    break;
                }
            } else {
                paths.clear();
                break;
            }
        }
        if (!paths.isEmpty()) {
            out = listSymbolsWithPathFilter(proj, paths);
        } else {
            out = listSymbols(proj);
        }
    }

    if (queryFlags() & QueryMessage::Elisp) {
        write("(list", IgnoreMax | DontQuote);
        for (Set<String>::const_iterator it = out.begin(); it != out.end(); ++it) {
            write(*it);
        }
        write(")", IgnoreMax | DontQuote);
    } else {
        List<String> sorted = out.toList();
        if (queryFlags() & QueryMessage::ReverseSort) {
            std::sort(sorted.begin(), sorted.end(), std::greater<String>());
        } else {
            std::sort(sorted.begin(), sorted.end());
        }
        const int count = sorted.size();
        for (int i = 0; i < count; ++i) {
            write(sorted.at(i));
        }
    }
    return out.isEmpty() ? 1 : 0;
}
Ejemplo n.º 2
0
Set<String> ListSymbolsJob::imenu(const std::shared_ptr<Project> &project)
{
    Set<String> out;
    const List<String> paths = pathFilters();
    if (paths.isEmpty()) {
        error() << "--imenu must take path filters";
        return out;
    }

    for (int i=0; i<paths.size(); ++i) {
        const Path file = paths.at(i);
        if (!file.isFile()) {
            error() << "Invalid path filter for --imenu" << file;
            continue;
        }
        const uint32_t fileId = Location::fileId(file);
        if (!fileId)
            continue;
        auto symbols = project->openSymbols(fileId);
        if (!symbols)
            continue;
        const int count = symbols->count();
        for (int j=0; j<count; ++j) {
            const Symbol &symbol = symbols->valueAt(j);
            if (RTags::isReference(symbol.kind))
                continue;
            switch (symbol.kind) {
            case CXCursor_VarDecl:
            case CXCursor_ParmDecl:
            case CXCursor_InclusionDirective:
            case CXCursor_EnumConstantDecl:
                break;
            case CXCursor_ClassDecl:
            case CXCursor_StructDecl:
            case CXCursor_ClassTemplate:
                if (!symbol.isDefinition())
                    break;
                // fall through
            default: {
                const String &symbolName = symbol.symbolName;
                if (!string.isEmpty() && !symbolName.contains(string))
                    continue;
                out.insert(symbolName);
                break; }
            }
        }
    }
    return out;
}
Ejemplo n.º 3
0
Set<String> ListSymbolsJob::imenu(const shared_ptr<Project> &project)
{
    Set<String> out;

    Scope<const SymbolMap&> symbols = project->lockSymbolsForRead();
    const SymbolMap &map = symbols.data();
    const List<String> paths = pathFilters();
    if (paths.isEmpty()) {
        error() << "--imenu must take path filters";
        return out;
    }

    for (int i=0; i<paths.size(); ++i) {
        const Path file = paths.at(i);
        if (!file.isFile()) {
            error() << "Invalid path filter for --imenu" << file;
            continue;
        }
        const uint32_t fileId = Location::fileId(file);
        if (!fileId)
            continue;
        for (SymbolMap::const_iterator it = map.lower_bound(Location(fileId, 0));
             it != map.end() && it->first.fileId() == fileId; ++it) {
            const CursorInfo &cursorInfo = it->second;
            if (RTags::isReference(cursorInfo.kind))
                continue;
            switch (cursorInfo.kind) {
            case CXCursor_VarDecl:
            case CXCursor_ParmDecl:
            case CXCursor_InclusionDirective:
            case CXCursor_EnumConstantDecl:
                break;
            case CXCursor_ClassDecl:
            case CXCursor_StructDecl:
            case CXCursor_ClassTemplate:
                if (!cursorInfo.isDefinition())
                    break;
                // fall through
            default: {
                const String &symbolName = it->second.symbolName;
                if (!string.isEmpty() && !symbolName.contains(string))
                    continue;
                out.insert(symbolName);
                break; }
            }
        }
    }
    return out;
}