void ParserTreeItem::add(const ParserTreeItem::ConstPtr &target)
{
    if (target.isNull())
        return;

    // add locations
    d->symbolLocations = d->symbolLocations.unite(target->d->symbolLocations);

    // add children
    // every target child
    CitSymbolInformations cur = target->d->symbolInformations.constBegin();
    CitSymbolInformations end = target->d->symbolInformations.constEnd();
    while (cur != end) {
        const SymbolInformation &inf = cur.key();
        const ParserTreeItem::Ptr &targetChild = cur.value();

        ParserTreeItem::Ptr child = d->symbolInformations.value(inf);
        if (!child.isNull()) {
            child->add(targetChild);
        } else {
            ParserTreeItem::Ptr add(new ParserTreeItem());
            add->copyTree(targetChild);
            d->symbolInformations[inf] = add;
        }
        // next item
        ++cur;
    }
}
Example #2
0
void Parser::addProject(const ParserTreeItem::Ptr &item, const QStringList &fileList,
                                 const QString &projectId)
{
    // recalculate cache tree if needed
    ParserTreeItem::Ptr prj(getCachedOrParseProjectTree(fileList, projectId));
    if (item.isNull())
        return;

    // if there is an item - copy project tree to that item
    item->copy(prj);
}
void ParserTreeItem::appendChild(const ParserTreeItem::Ptr &item, const SymbolInformation &inf)
{
    // removeChild must be used to remove an item
    if (item.isNull())
        return;

    d->symbolInformations[inf] = item;
}
Example #4
0
ParserTreeItem::ConstPtr Parser::parse()
{
    QTime time;
    if (debug)
        time.start();

    ParserTreeItem::Ptr rootItem(new ParserTreeItem());

    // check all projects
    QList<ProjectExplorer::Project *> projects = getProjectList();
    foreach (const ProjectExplorer::Project *prj, projects) {
        if (!prj)
            continue;

        ParserTreeItem::Ptr item;
        if (!d->flatMode)
            item = ParserTreeItem::Ptr(new ParserTreeItem());

        QString prjName(prj->displayName());
        QString prjType(prjName);
        if (prj->document())
            prjType = prj->document()->filePath();
        SymbolInformation inf(prjName, prjType);

        QStringList projectList = addProjectNode(item, prj->rootProjectNode());

        if (d->flatMode) {
            // use prj path (prjType) as a project id
//            addProject(item, prj->files(ProjectExplorer::Project::ExcludeGeneratedFiles), prjType);
            //! \todo return back, works too long
            ParserTreeItem::Ptr flatItem = createFlatTree(projectList);
            item.swap(flatItem);
        }
        item->setIcon(prj->rootProjectNode()->icon());
        rootItem->appendChild(item, inf);
    }

    if (debug)
        qDebug() << "Class View:" << QDateTime::currentDateTime().toString()
            << "Parsed in " << time.elapsed() << "msecs.";

    return rootItem;
}
void ParserTreeItem::convertTo(QStandardItem *item) const
{
    if (!item)
        return;

    QMap<SymbolInformation, ParserTreeItem::Ptr> map;

    // convert to map - to sort it
    CitSymbolInformations curHash = d->symbolInformations.constBegin();
    CitSymbolInformations endHash = d->symbolInformations.constEnd();
    while (curHash != endHash) {
        map.insert(curHash.key(), curHash.value());
        ++curHash;
    }

    typedef QMap<SymbolInformation, ParserTreeItem::Ptr>::const_iterator MapCitSymbolInformations;
    // add to item
    MapCitSymbolInformations cur = map.constBegin();
    MapCitSymbolInformations end = map.constEnd();
    while (cur != end) {
        const SymbolInformation &inf = cur.key();
        ParserTreeItem::Ptr ptr = cur.value();

        QStandardItem *add = new QStandardItem();
        Utils::setSymbolInformationToItem(inf, add);
        if (!ptr.isNull()) {
            // icon
            add->setIcon(ptr->icon());

            // draggable
            if (!ptr->symbolLocations().isEmpty())
                add->setFlags(add->flags() | Qt::ItemIsDragEnabled);

            // locations
            add->setData(Utils::locationsToRole(ptr->symbolLocations()),
                         Constants::SymbolLocationsRole);
        }
        item->appendRow(add);
        ++cur;
    }
}
void ParserTreeItem::convertTo(QStandardItem *item, bool recursive) const
{
    if (!item)
        return;

    QMap<SymbolInformation, ParserTreeItem::Ptr> map;

    // convert to map - to sort it
    QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator curHash =
            d->symbolInformations.constBegin();
    QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator endHash =
            d->symbolInformations.constEnd();
    while(curHash != endHash) {
        map.insert(curHash.key(), curHash.value());
        ++curHash;
    }

    // add to item
    QMap<SymbolInformation, ParserTreeItem::Ptr>::const_iterator cur = map.constBegin();
    QMap<SymbolInformation, ParserTreeItem::Ptr>::const_iterator end = map.constEnd();
    while(cur != end) {
        const SymbolInformation &inf = cur.key();
        ParserTreeItem::Ptr ptr = cur.value();

        QStandardItem *add = new QStandardItem();
        Utils::setSymbolInformationToItem(inf, add);
        if (!ptr.isNull()) {
            // icon
            add->setIcon(ptr->icon());

            // locations
            add->setData(Utils::locationsToRole(ptr->symbolLocations()),
                         Constants::SymbolLocationsRole);

            if (recursive)
                cur.value()->convertTo(add, false);
        }
        item->appendRow(add);
        ++cur;
    }
}
ParserTreeItem::Ptr Parser::getCachedOrParseProjectTree(const QStringList &fileList,
                                                const QString &projectId)
{
    d->prjLocker.lockForRead();

    ParserTreeItem::Ptr item = d->cachedPrjTrees.value(projectId);
    // calculate current revision
    if (!projectId.isEmpty() && !item.isNull()) {
        // calculate project's revision
        unsigned revision = 0;
        foreach (const QString &file, fileList) {
            const CPlusPlus::Document::Ptr &doc = d->document(file);
            if (doc.isNull())
                continue;
            revision += doc->revision();
        }

        // if even revision is the same, return cached project
        if (revision == d->cachedPrjTreesRevision[projectId]) {
            d->prjLocker.unlock();
            return item;
        }
    }
ParserTreeItem::ConstPtr Parser::parse()
{
    QTime time;
    if (debug)
        time.start();

    ParserTreeItem::Ptr rootItem(new ParserTreeItem());

    // check all projects
    foreach (const Project *prj, SessionManager::projects()) {
        if (!prj)
            continue;

        ParserTreeItem::Ptr item;
        QString prjName(prj->displayName());
        QString prjType(prjName);
        if (prj->document())
            prjType = prj->projectFilePath().toString();
        SymbolInformation inf(prjName, prjType);
        item = ParserTreeItem::Ptr(new ParserTreeItem());

        if (d->flatMode)
            addFlatTree(item, prj->rootProjectNode());
        else
            addProjectNode(item, prj->rootProjectNode());

        item->setIcon(prj->rootProjectNode()->icon());
        rootItem->appendChild(item, inf);
    }

    if (debug)
        qDebug() << "Class View:" << QDateTime::currentDateTime().toString()
            << "Parsed in " << time.elapsed() << "msecs.";

    return rootItem;
}
Example #9
0
void Parser::addSymbol(const ParserTreeItem::Ptr &item, const CPlusPlus::Symbol *symbol)
{
    if (item.isNull() || !symbol)
        return;

    // easy solution - lets add any scoped symbol and
    // any symbol which does not contain :: in the name

//    if (symbol->isDeclaration())
//        return;

    //! \todo collect statistics and reorder to optimize
    if (symbol->isForwardClassDeclaration()
        || symbol->isExtern()
        || symbol->isFriend()
        || symbol->isGenerated()
        || symbol->isUsingNamespaceDirective()
        || symbol->isUsingDeclaration()
        )
        return;

    // skip static local functions
//    if ((!symbol->scope() || symbol->scope()->isClass())
//        && symbol->isStatic() && symbol->isFunction())
//        return;


    const CPlusPlus::Name *symbolName = symbol->name();
    if (symbolName && symbolName->isQualifiedNameId())
        return;

    QString name = d->overview.prettyName(symbol->name()).trimmed();
    QString type = d->overview.prettyType(symbol->type()).trimmed();
    int iconType = CPlusPlus::Icons::iconTypeForSymbol(symbol);

    SymbolInformation information(name, type, iconType);

    ParserTreeItem::Ptr itemAdd;

    // If next line will be removed, 5% speed up for the initial parsing.
    // But there might be a problem for some files ???
    // Better to improve qHash timing
    itemAdd = item->child(information);

    if (itemAdd.isNull())
        itemAdd = ParserTreeItem::Ptr(new ParserTreeItem());

    // locations are 1-based in Symbol, start with 0 for the editor
    SymbolLocation location(QString::fromUtf8(symbol->fileName() , symbol->fileNameLength()),
                            symbol->line(), symbol->column() - 1);
    itemAdd->addSymbolLocation(location);

    // prevent showing a content of the functions
    if (!symbol->isFunction()) {
        const CPlusPlus::Scope *scope = symbol->asScope();
        if (scope) {
            CPlusPlus::Scope::iterator cur = scope->firstMember();
            while (cur != scope->lastMember()) {
                const CPlusPlus::Symbol *curSymbol = *cur;
                ++cur;
                if (!curSymbol)
                    continue;

                //                if (!symbol->isClass() && curSymbol->isStatic() && curSymbol->isFunction())
                //                        return;

                addSymbol(itemAdd, curSymbol);
            }
        }
    }

    bool appendChild = true;

    // if item is empty and has not to be added
    if (symbol->isNamespace() && itemAdd->childCount() == 0)
        appendChild = false;

    if (appendChild)
        item->appendChild(itemAdd, information);
}