ParserTreeItem::ConstPtr Parser::findItemByRoot(const QStandardItem *item, bool skipRoot) const { if (!item) return ParserTreeItem::ConstPtr(); // go item by item to the root QList<const QStandardItem *> uiList; const QStandardItem *cur = item; while (cur) { uiList.append(cur); cur = cur->parent(); } if (skipRoot && uiList.count() > 0) uiList.removeLast(); QReadLocker locker(&d->rootItemLocker); // using internal root - search correct item ParserTreeItem::ConstPtr internal = d->rootItem; while (uiList.count() > 0) { cur = uiList.last(); uiList.removeLast(); const SymbolInformation &inf = Utils::symbolInformationFromItem(cur); internal = internal->child(inf); if (internal.isNull()) break; } return internal; }
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; } }
ParserTreeItem::Ptr Parser::getParseProjectTree(const QStringList &fileList, const QString &projectId) { //! \todo Way to optimize - for documentUpdate - use old cached project and subtract //! changed files only (old edition), and add curent editions ParserTreeItem::Ptr item(new ParserTreeItem()); unsigned revision = 0; foreach (const QString &file, fileList) { // ? locker for document?.. const CPlusPlus::Document::Ptr &doc = d->document(file); if (doc.isNull()) continue; revision += doc->revision(); ParserTreeItem::ConstPtr list = getCachedOrParseDocumentTree(doc); if (list.isNull()) continue; // add list to out document item->add(list); } // update the cache if (!projectId.isEmpty()) { QWriteLocker locker(&d->prjLocker); d->cachedPrjTrees[projectId] = item; d->cachedPrjTreesRevision[projectId] = revision; } return item; }
void ParserTreeItem::copyTree(const ParserTreeItem::ConstPtr &target) { if (target.isNull()) return; // copy content d->symbolLocations = target->d->symbolLocations; d->icon = target->d->icon; d->symbolInformations.clear(); // reserve memory // int amount = qMin(100 , target->d_ptr->symbolInformations.count() * 2); // d_ptr->symbolInformations.reserve(amount); // every child QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator cur = target->d->symbolInformations.constBegin(); QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator end = target->d->symbolInformations.constEnd(); for (; cur != end; cur++) { ParserTreeItem::Ptr item(new ParserTreeItem()); item->copyTree(cur.value()); appendChild(item, cur.key()); } }
bool Parser::hasChildren(QStandardItem *item) const { ParserTreeItem::ConstPtr ptr = findItemByRoot(item); if (ptr.isNull()) return false; return ptr->childCount() != 0; }
void Parser::fetchMore(QStandardItem *item, bool skipRoot) const { ParserTreeItem::ConstPtr ptr = findItemByRoot(item, skipRoot); if (ptr.isNull()) return; ptr->fetchMore(item); }
void ParserTreeItem::copy(const ParserTreeItem::ConstPtr &from) { if (from.isNull()) return; d->symbolLocations = from->d->symbolLocations; d->icon = from->d->icon; d->symbolInformations = from->d->symbolInformations; }
void ParserTreeItem::subtract(const ParserTreeItem::ConstPtr &target) { if (target.isNull()) return; // every target child QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator cur = target->d->symbolInformations.constBegin(); QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator end = target->d->symbolInformations.constEnd(); while(cur != end) { const SymbolInformation &inf = cur.key(); if (d->symbolInformations.contains(inf)) { // this item has the same child node if (!d->symbolInformations[inf].isNull()) d->symbolInformations[inf]->subtract(cur.value()); if (d->symbolInformations[inf].isNull() || d->symbolInformations[inf]->childCount() == 0) d->symbolInformations.remove(inf); } // next item ++cur; } }
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 QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator cur = target->d->symbolInformations.constBegin(); QHash<SymbolInformation, ParserTreeItem::Ptr>::const_iterator end = target->d->symbolInformations.constEnd(); while(cur != end) { const SymbolInformation &inf = cur.key(); const ParserTreeItem::Ptr &targetChild = cur.value(); if (d->symbolInformations.contains(inf)) { // this item has the same child node const ParserTreeItem::Ptr &child = d->symbolInformations[inf]; if (!child.isNull()) { child->add(targetChild); } else { ParserTreeItem::Ptr add(new ParserTreeItem()); add->copyTree(targetChild); d->symbolInformations[inf] = add; } } else { ParserTreeItem::Ptr add(new ParserTreeItem()); add->copyTree(targetChild); d->symbolInformations[inf] = add; } // next item ++cur; } }