ClassView: Use only const pointers to ParserTreeItems

There is no need to use non-const pointers anymore. This also
ensures, that after generating the tree data in the non-gui
thread no-one modifies already created items.

Task-number: QTCREATORBUG-25317
Change-Id: I91f63da8f57ae9798587265adc029ebd0c68504e
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Jarek Kobus
2021-02-16 16:04:50 +01:00
parent d4fe3fdb15
commit 8c5dc305ae
4 changed files with 35 additions and 36 deletions

View File

@@ -92,12 +92,12 @@ public:
struct DocumentCache {
unsigned treeRevision = 0;
ParserTreeItem::Ptr tree;
ParserTreeItem::ConstPtr tree;
CPlusPlus::Document::Ptr document;
};
struct ProjectCache {
unsigned treeRevision = 0;
ParserTreeItem::Ptr tree;
ParserTreeItem::ConstPtr tree;
QStringList fileList;
};
@@ -180,7 +180,7 @@ ParserTreeItem::ConstPtr Parser::parse()
timer->start();
}
QHash<SymbolInformation, ParserTreeItem::Ptr> projectTrees;
QHash<SymbolInformation, ParserTreeItem::ConstPtr> projectTrees;
// TODO: move a call to SessionManager::projects() out of this thread
for (const Project *prj : SessionManager::projects()) {
@@ -188,13 +188,13 @@ ParserTreeItem::ConstPtr Parser::parse()
const QString prjType = prj->projectFilePath().toString();
const SymbolInformation inf(prjName, prjType);
ParserTreeItem::Ptr item = addFlatTree(prj);
ParserTreeItem::ConstPtr item = addFlatTree(prj);
if (item.isNull())
continue;
projectTrees.insert(inf, item);
}
ParserTreeItem::Ptr rootItem(new ParserTreeItem(projectTrees));
ParserTreeItem::ConstPtr rootItem(new ParserTreeItem(projectTrees));
if (debug) {
qDebug() << "Class View:" << QDateTime::currentDateTime().toString()
@@ -210,7 +210,7 @@ ParserTreeItem::ConstPtr Parser::parse()
project.
*/
ParserTreeItem::Ptr Parser::getParseProjectTree(const QStringList &fileList,
ParserTreeItem::ConstPtr Parser::getParseProjectTree(const QStringList &fileList,
const QString &projectId)
{
//! \todo Way to optimize - for documentUpdate - use old cached project and subtract
@@ -231,7 +231,7 @@ ParserTreeItem::Ptr Parser::getParseProjectTree(const QStringList &fileList,
docTrees.append(docTree);
}
ParserTreeItem::Ptr item = ParserTreeItem::mergeTrees(Utils::FilePath::fromString(projectId), docTrees);
ParserTreeItem::ConstPtr item = ParserTreeItem::mergeTrees(Utils::FilePath::fromString(projectId), docTrees);
// update the cache
if (!projectId.isEmpty()) {
@@ -248,7 +248,7 @@ ParserTreeItem::Ptr Parser::getParseProjectTree(const QStringList &fileList,
Updates the internal cached tree for this project.
*/
ParserTreeItem::Ptr Parser::getCachedOrParseProjectTree(const QStringList &fileList,
ParserTreeItem::ConstPtr Parser::getCachedOrParseProjectTree(const QStringList &fileList,
const QString &projectId)
{
const auto it = d->m_projectCache.constFind(projectId);
@@ -286,7 +286,7 @@ ParserTreeItem::ConstPtr Parser::getParseDocumentTree(const CPlusPlus::Document:
if (!d->fileList.contains(fileName))
return ParserTreeItem::ConstPtr();
ParserTreeItem::Ptr itemPtr = ParserTreeItem::parseDocument(doc);
ParserTreeItem::ConstPtr itemPtr = ParserTreeItem::parseDocument(doc);
d->m_documentCache.insert(fileName, { doc->revision(), itemPtr, doc } );
return itemPtr;
@@ -426,7 +426,7 @@ QStringList Parser::getAllFiles(const Project *project)
}
// TODO: don't use Project class in this thread
ParserTreeItem::Ptr Parser::addFlatTree(const Project *project)
ParserTreeItem::ConstPtr Parser::addFlatTree(const Project *project)
{
if (!project)
return {};

View File

@@ -68,13 +68,13 @@ private:
ParserTreeItem::ConstPtr getParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
ParserTreeItem::ConstPtr getCachedOrParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
ParserTreeItem::Ptr getParseProjectTree(const QStringList &fileList, const QString &projectId);
ParserTreeItem::Ptr getCachedOrParseProjectTree(const QStringList &fileList,
ParserTreeItem::ConstPtr getParseProjectTree(const QStringList &fileList, const QString &projectId);
ParserTreeItem::ConstPtr getCachedOrParseProjectTree(const QStringList &fileList,
const QString &projectId);
ParserTreeItem::ConstPtr parse();
QStringList getAllFiles(const ProjectExplorer::Project *project);
ParserTreeItem::Ptr addFlatTree(const ProjectExplorer::Project *project);
ParserTreeItem::ConstPtr addFlatTree(const ProjectExplorer::Project *project);
//! Private class data pointer
ParserPrivate *d;

View File

@@ -66,9 +66,9 @@ class ParserTreeItemPrivate
public:
void mergeWith(const ParserTreeItem::ConstPtr &target);
void mergeSymbol(const CPlusPlus::Symbol *symbol);
ParserTreeItem::Ptr cloneTree() const;
ParserTreeItem::ConstPtr cloneTree() const;
QHash<SymbolInformation, ParserTreeItem::Ptr> m_symbolInformations;
QHash<SymbolInformation, ParserTreeItem::ConstPtr> m_symbolInformations;
QSet<SymbolLocation> m_symbolLocations;
const Utils::FilePath m_projectFilePath;
};
@@ -84,13 +84,13 @@ void ParserTreeItemPrivate::mergeWith(const ParserTreeItem::ConstPtr &target)
for (auto it = target->d->m_symbolInformations.cbegin();
it != target->d->m_symbolInformations.cend(); ++it) {
const SymbolInformation &inf = it.key();
const ParserTreeItem::Ptr &targetChild = it.value();
const ParserTreeItem::ConstPtr &targetChild = it.value();
ParserTreeItem::Ptr child = m_symbolInformations.value(inf);
ParserTreeItem::ConstPtr child = m_symbolInformations.value(inf);
if (!child.isNull()) {
child->d->mergeWith(targetChild);
} else {
const ParserTreeItem::Ptr clone = targetChild.isNull() ? ParserTreeItem::Ptr()
const ParserTreeItem::ConstPtr clone = targetChild.isNull() ? ParserTreeItem::ConstPtr()
: targetChild->d->cloneTree();
m_symbolInformations.insert(inf, clone);
}
@@ -128,10 +128,10 @@ void ParserTreeItemPrivate::mergeSymbol(const CPlusPlus::Symbol *symbol)
// 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
ParserTreeItem::Ptr childItem = m_symbolInformations.value(information);
ParserTreeItem::ConstPtr childItem = m_symbolInformations.value(information);
if (childItem.isNull())
childItem = ParserTreeItem::Ptr(new ParserTreeItem());
childItem = ParserTreeItem::ConstPtr(new ParserTreeItem());
// locations have 1-based column in Symbol, use the same here.
SymbolLocation location(QString::fromUtf8(symbol->fileName() , symbol->fileNameLength()),
@@ -163,9 +163,9 @@ void ParserTreeItemPrivate::mergeSymbol(const CPlusPlus::Symbol *symbol)
/*!
Creates a deep clone of this tree.
*/
ParserTreeItem::Ptr ParserTreeItemPrivate::cloneTree() const
ParserTreeItem::ConstPtr ParserTreeItemPrivate::cloneTree() const
{
ParserTreeItem::Ptr newItem(new ParserTreeItem(m_projectFilePath));
ParserTreeItem::ConstPtr newItem(new ParserTreeItem(m_projectFilePath));
newItem->d->m_symbolLocations = m_symbolLocations;
for (auto it = m_symbolInformations.cbegin(); it != m_symbolInformations.cend(); ++it) {
@@ -197,7 +197,7 @@ ParserTreeItem::ParserTreeItem(const Utils::FilePath &projectFilePath)
{
}
ParserTreeItem::ParserTreeItem(const QHash<SymbolInformation, Ptr> &children)
ParserTreeItem::ParserTreeItem(const QHash<SymbolInformation, ConstPtr> &children)
: d(new ParserTreeItemPrivate({children, {}, {}}))
{
}
@@ -226,7 +226,7 @@ QSet<SymbolLocation> ParserTreeItem::symbolLocations() const
Returns the child item specified by \a inf symbol information.
*/
ParserTreeItem::Ptr ParserTreeItem::child(const SymbolInformation &inf) const
ParserTreeItem::ConstPtr ParserTreeItem::child(const SymbolInformation &inf) const
{
return d->m_symbolInformations.value(inf);
}
@@ -240,9 +240,9 @@ int ParserTreeItem::childCount() const
return d->m_symbolInformations.count();
}
ParserTreeItem::Ptr ParserTreeItem::parseDocument(const CPlusPlus::Document::Ptr &doc)
ParserTreeItem::ConstPtr ParserTreeItem::parseDocument(const CPlusPlus::Document::Ptr &doc)
{
Ptr item(new ParserTreeItem());
ConstPtr item(new ParserTreeItem());
const unsigned total = doc->globalSymbolCount();
for (unsigned i = 0; i < total; ++i)
@@ -251,10 +251,10 @@ ParserTreeItem::Ptr ParserTreeItem::parseDocument(const CPlusPlus::Document::Ptr
return item;
}
ParserTreeItem::Ptr ParserTreeItem::mergeTrees(const Utils::FilePath &projectFilePath,
ParserTreeItem::ConstPtr ParserTreeItem::mergeTrees(const Utils::FilePath &projectFilePath,
const QList<ConstPtr> &docTrees)
{
Ptr item(new ParserTreeItem(projectFilePath));
ConstPtr item(new ParserTreeItem(projectFilePath));
for (const ConstPtr &docTree : docTrees)
item->d->mergeWith(docTree);
@@ -299,13 +299,13 @@ void ParserTreeItem::fetchMore(QStandardItem *item) const
return;
// convert to map - to sort it
QMap<SymbolInformation, Ptr> map;
QMap<SymbolInformation, ConstPtr> map;
for (auto it = d->m_symbolInformations.cbegin(); it != d->m_symbolInformations.cend(); ++it)
map.insert(it.key(), it.value());
for (auto it = map.cbegin(); it != map.cend(); ++it) {
const SymbolInformation &inf = it.key();
Ptr ptr = it.value();
ConstPtr ptr = it.value();
auto add = new QStandardItem;
add->setData(inf.name(), Constants::SymbolNameRole);
@@ -340,7 +340,7 @@ void ParserTreeItem::debugDump(int indent) const
{
for (auto it = d->m_symbolInformations.cbegin(); it != d->m_symbolInformations.cend(); ++it) {
const SymbolInformation &inf = it.key();
const Ptr &child = it.value();
const ConstPtr &child = it.value();
qDebug() << QString(2 * indent, QLatin1Char(' ')) << inf.iconType() << inf.name()
<< inf.type() << child.isNull();
if (!child.isNull())

View File

@@ -43,21 +43,20 @@ class ParserTreeItemPrivate;
class ParserTreeItem
{
public:
using Ptr = QSharedPointer<ParserTreeItem>;
using ConstPtr = QSharedPointer<const ParserTreeItem>;
public:
ParserTreeItem();
ParserTreeItem(const Utils::FilePath &projectFilePath);
ParserTreeItem(const QHash<SymbolInformation, Ptr> &children);
ParserTreeItem(const QHash<SymbolInformation, ConstPtr> &children);
~ParserTreeItem();
static Ptr parseDocument(const CPlusPlus::Document::Ptr &doc);
static Ptr mergeTrees(const Utils::FilePath &projectFilePath, const QList<ConstPtr> &docTrees);
static ConstPtr parseDocument(const CPlusPlus::Document::Ptr &doc);
static ConstPtr mergeTrees(const Utils::FilePath &projectFilePath, const QList<ConstPtr> &docTrees);
Utils::FilePath projectFilePath() const;
QSet<SymbolLocation> symbolLocations() const;
Ptr child(const SymbolInformation &inf) const;
ConstPtr child(const SymbolInformation &inf) const;
int childCount() const;
// Make sure that below two methods are called only from the GUI thread