aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/classview/classviewparser.cpp
diff options
context:
space:
mode:
authorPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2013-12-04 13:46:12 +0100
committerPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2014-05-28 07:19:56 +0200
commitfa33294f17082eecf0195d491c7dc76c6f7c6e9c (patch)
treeea902eb706c370b13df2a50d31ce39c65ebd754c /src/plugins/classview/classviewparser.cpp
parentc35ad8c62a10fba462bee253de541f3877212dd4 (diff)
ClassView: improvements of performance for flat tree view
Improved lazy loading mechanism. The main problem here was that fetchMore function creates children items not only for selected item but also for children items. When one changed something in code then whole treeview was rebuilt (and fetchMore function was called). Replaced using "contains" and operator[] with 'value'. Task-number: QTCREATORBUG-8813 Task-number: QTCREATORBUG-8801(partially) Change-Id: If1ab69a0a67ff828275176ad99c3c63d2a1fa4a2 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
Diffstat (limited to 'src/plugins/classview/classviewparser.cpp')
-rw-r--r--src/plugins/classview/classviewparser.cpp141
1 files changed, 77 insertions, 64 deletions
diff --git a/src/plugins/classview/classviewparser.cpp b/src/plugins/classview/classviewparser.cpp
index 44100865716..c1ff497d642 100644
--- a/src/plugins/classview/classviewparser.cpp
+++ b/src/plugins/classview/classviewparser.cpp
@@ -94,6 +94,8 @@ namespace Internal {
class ParserPrivate
{
public:
+ typedef QHash<QString, CPlusPlus::Document::Ptr>::const_iterator CitDocumentList;
+
//! Constructor
ParserPrivate() : flatMode(false) {}
@@ -147,9 +149,10 @@ public:
CPlusPlus::Document::Ptr ParserPrivate::document(const QString &fileName) const
{
- if (!documentList.contains(fileName))
+ CitDocumentList cit = documentList.find(fileName);
+ if (cit == documentList.end())
return CPlusPlus::Document::Ptr();
- return documentList[fileName];
+ return cit.value();
}
// ----------------------------- Parser ---------------------------------
@@ -186,9 +189,9 @@ Parser::~Parser()
Checks \a item for lazy data population of a QStandardItemModel.
*/
-bool Parser::canFetchMore(QStandardItem *item) const
+bool Parser::canFetchMore(QStandardItem *item, bool skipRoot) const
{
- ParserTreeItem::ConstPtr ptr = findItemByRoot(item);
+ ParserTreeItem::ConstPtr ptr = findItemByRoot(item, skipRoot);
if (ptr.isNull())
return false;
return ptr->canFetchMore(item);
@@ -207,6 +210,14 @@ void Parser::fetchMore(QStandardItem *item, bool skipRoot) const
ptr->fetchMore(item);
}
+bool Parser::hasChildren(QStandardItem *item) const
+{
+ ParserTreeItem::ConstPtr ptr = findItemByRoot(item);
+ if (ptr.isNull())
+ return false;
+ return ptr->childCount() != 0;
+}
+
/*!
Switches to flat mode (without subprojects) if \a flat returns \c true.
*/
@@ -281,24 +292,18 @@ ParserTreeItem::ConstPtr Parser::parse()
continue;
ParserTreeItem::Ptr item;
- if (!d->flatMode)
- item = ParserTreeItem::Ptr(new ParserTreeItem());
-
QString prjName(prj->displayName());
QString prjType(prjName);
if (prj->document())
prjType = prj->projectFilePath().toString();
SymbolInformation inf(prjName, prjType);
+ item = ParserTreeItem::Ptr(new ParserTreeItem());
- QStringList projectList = addProjectNode(item, prj->rootProjectNode());
+ if (d->flatMode)
+ addFlatTree(item, prj->rootProjectNode());
+ else
+ addProjectNode(item, prj->rootProjectNode());
- if (d->flatMode) {
- // use prj path (prjType) as a project id
-// addProject(item, prj->files(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);
}
@@ -339,9 +344,6 @@ void Parser::addSymbol(const ParserTreeItem::Ptr &item, const CPlusPlus::Symbol
// 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()
@@ -352,17 +354,11 @@ void Parser::addSymbol(const ParserTreeItem::Ptr &item, const CPlusPlus::Symbol
)
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 name = d->overview.prettyName(symbolName).trimmed();
QString type = d->overview.prettyType(symbol->type()).trimmed();
int iconType = CPlusPlus::Icons::iconTypeForSymbol(symbol);
@@ -385,52 +381,26 @@ void Parser::addSymbol(const ParserTreeItem::Ptr &item, const CPlusPlus::Symbol
// prevent showing a content of the functions
if (!symbol->isFunction()) {
- const CPlusPlus::Scope *scope = symbol->asScope();
- if (scope) {
+ if (const CPlusPlus::Scope *scope = symbol->asScope()) {
CPlusPlus::Scope::iterator cur = scope->firstMember();
- while (cur != scope->lastMember()) {
+ CPlusPlus::Scope::iterator last = scope->lastMember();
+ while (cur != last) {
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)
+ if (!(symbol->isNamespace() && itemAdd->childCount() == 0))
item->appendChild(itemAdd, information);
}
/*!
- Creates a flat tree from the list of projects specified by \a projectList.
-*/
-
-ParserTreeItem::Ptr Parser::createFlatTree(const QStringList &projectList)
-{
- QReadLocker locker(&d->prjLocker);
-
- ParserTreeItem::Ptr item(new ParserTreeItem());
- foreach (const QString &project, projectList) {
- if (!d->cachedPrjTrees.contains(project))
- continue;
- ParserTreeItem::ConstPtr list = d->cachedPrjTrees[project];
- item->add(list);
- }
- return item;
-}
-
-/*!
Parses the project with the \a projectId and adds the documents from the
\a fileList to the project. Updates the internal cached tree for this
project.
@@ -480,8 +450,9 @@ ParserTreeItem::Ptr Parser::getCachedOrParseProjectTree(const QStringList &fileL
{
d->prjLocker.lockForRead();
+ ParserTreeItem::Ptr item = d->cachedPrjTrees.value(projectId);
// calculate current revision
- if (!projectId.isEmpty() && d->cachedPrjTrees.contains(projectId)) {
+ if (!projectId.isEmpty() && !item.isNull()) {
// calculate project's revision
unsigned revision = 0;
foreach (const QString &file, fileList) {
@@ -494,7 +465,7 @@ ParserTreeItem::Ptr Parser::getCachedOrParseProjectTree(const QStringList &fileL
// if even revision is the same, return cached project
if (revision == d->cachedPrjTreesRevision[projectId]) {
d->prjLocker.unlock();
- return d->cachedPrjTrees[projectId];
+ return item;
}
}
@@ -520,7 +491,7 @@ ParserTreeItem::ConstPtr Parser::getParseDocumentTree(const CPlusPlus::Document:
ParserTreeItem::Ptr itemPtr(new ParserTreeItem());
- unsigned total = doc->globalSymbolCount();
+ const unsigned total = doc->globalSymbolCount();
for (unsigned i = 0; i < total; ++i)
addSymbol(itemPtr, doc->globalSymbolAt(i));
@@ -547,11 +518,13 @@ ParserTreeItem::ConstPtr Parser::getCachedOrParseDocumentTree(const CPlusPlus::D
const QString &fileName = doc->fileName();
d->docLocker.lockForRead();
- if (d->cachedDocTrees.contains(fileName)
- && d->cachedDocTreesRevision.contains(fileName)
- && d->cachedDocTreesRevision[fileName] == doc->revision()) {
+ ParserTreeItem::ConstPtr item = d->cachedDocTrees.value(fileName);
+ CitCachedDocTreeRevision citCachedDocTreeRevision = d->cachedDocTreesRevision.find(fileName);
+ if (!item.isNull()
+ && citCachedDocTreeRevision != d->cachedDocTreesRevision.end()
+ && citCachedDocTreeRevision.value() == doc->revision()) {
d->docLocker.unlock();
- return d->cachedDocTrees[fileName];
+ return item;
}
d->docLocker.unlock();
return getParseDocumentTree(doc);
@@ -788,9 +761,10 @@ QStringList Parser::addProjectNode(const ParserTreeItem::Ptr &item,
// our own files
QStringList fileList;
+ CitCachedPrjFileLists cit = d->cachedPrjFileLists.find(nodePath);
// try to improve parsing speed by internal cache
- if (d->cachedPrjFileLists.contains(nodePath)) {
- fileList = d->cachedPrjFileLists[nodePath];
+ if (cit != d->cachedPrjFileLists.end()) {
+ fileList = cit.value();
} else {
fileList = projectNodeFileList(node);
d->cachedPrjFileLists[nodePath] = fileList;
@@ -819,5 +793,44 @@ QStringList Parser::addProjectNode(const ParserTreeItem::Ptr &item,
return projectList;
}
+QStringList Parser::getAllFiles(const ProjectNode *node)
+{
+ QStringList fileList;
+
+ if (!node)
+ return fileList;
+
+ const QString &nodePath = node->path();
+
+ CitCachedPrjFileLists cit = d->cachedPrjFileLists.find(nodePath);
+ // try to improve parsing speed by internal cache
+ if (cit != d->cachedPrjFileLists.end()) {
+ fileList = cit.value();
+ } else {
+ fileList = projectNodeFileList(node);
+ d->cachedPrjFileLists[nodePath] = fileList;
+ }
+ // subnodes
+ QList<ProjectExplorer::ProjectNode *> projectNodes = node->subProjectNodes();
+
+ foreach (const ProjectExplorer::ProjectNode *project, projectNodes) {
+ fileList += getAllFiles(project);
+ }
+ return fileList;
+}
+
+void Parser::addFlatTree(const ParserTreeItem::Ptr &item, const ProjectNode *node)
+{
+ if (!node)
+ return;
+
+ QStringList fileList = getAllFiles(node);
+ fileList.removeDuplicates();
+
+ if (fileList.count() > 0) {
+ addProject(item, fileList, node->path());
+ }
+}
+
} // namespace Internal
} // namespace ClassView