forked from qt-creator/qt-creator
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:
@@ -92,12 +92,12 @@ public:
|
|||||||
|
|
||||||
struct DocumentCache {
|
struct DocumentCache {
|
||||||
unsigned treeRevision = 0;
|
unsigned treeRevision = 0;
|
||||||
ParserTreeItem::Ptr tree;
|
ParserTreeItem::ConstPtr tree;
|
||||||
CPlusPlus::Document::Ptr document;
|
CPlusPlus::Document::Ptr document;
|
||||||
};
|
};
|
||||||
struct ProjectCache {
|
struct ProjectCache {
|
||||||
unsigned treeRevision = 0;
|
unsigned treeRevision = 0;
|
||||||
ParserTreeItem::Ptr tree;
|
ParserTreeItem::ConstPtr tree;
|
||||||
QStringList fileList;
|
QStringList fileList;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ ParserTreeItem::ConstPtr Parser::parse()
|
|||||||
timer->start();
|
timer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<SymbolInformation, ParserTreeItem::Ptr> projectTrees;
|
QHash<SymbolInformation, ParserTreeItem::ConstPtr> projectTrees;
|
||||||
|
|
||||||
// TODO: move a call to SessionManager::projects() out of this thread
|
// TODO: move a call to SessionManager::projects() out of this thread
|
||||||
for (const Project *prj : SessionManager::projects()) {
|
for (const Project *prj : SessionManager::projects()) {
|
||||||
@@ -188,13 +188,13 @@ ParserTreeItem::ConstPtr Parser::parse()
|
|||||||
const QString prjType = prj->projectFilePath().toString();
|
const QString prjType = prj->projectFilePath().toString();
|
||||||
const SymbolInformation inf(prjName, prjType);
|
const SymbolInformation inf(prjName, prjType);
|
||||||
|
|
||||||
ParserTreeItem::Ptr item = addFlatTree(prj);
|
ParserTreeItem::ConstPtr item = addFlatTree(prj);
|
||||||
if (item.isNull())
|
if (item.isNull())
|
||||||
continue;
|
continue;
|
||||||
projectTrees.insert(inf, item);
|
projectTrees.insert(inf, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParserTreeItem::Ptr rootItem(new ParserTreeItem(projectTrees));
|
ParserTreeItem::ConstPtr rootItem(new ParserTreeItem(projectTrees));
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
qDebug() << "Class View:" << QDateTime::currentDateTime().toString()
|
qDebug() << "Class View:" << QDateTime::currentDateTime().toString()
|
||||||
@@ -210,7 +210,7 @@ ParserTreeItem::ConstPtr Parser::parse()
|
|||||||
project.
|
project.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ParserTreeItem::Ptr Parser::getParseProjectTree(const QStringList &fileList,
|
ParserTreeItem::ConstPtr Parser::getParseProjectTree(const QStringList &fileList,
|
||||||
const QString &projectId)
|
const QString &projectId)
|
||||||
{
|
{
|
||||||
//! \todo Way to optimize - for documentUpdate - use old cached project and subtract
|
//! \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);
|
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
|
// update the cache
|
||||||
if (!projectId.isEmpty()) {
|
if (!projectId.isEmpty()) {
|
||||||
@@ -248,7 +248,7 @@ ParserTreeItem::Ptr Parser::getParseProjectTree(const QStringList &fileList,
|
|||||||
Updates the internal cached tree for this project.
|
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 QString &projectId)
|
||||||
{
|
{
|
||||||
const auto it = d->m_projectCache.constFind(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))
|
if (!d->fileList.contains(fileName))
|
||||||
return ParserTreeItem::ConstPtr();
|
return ParserTreeItem::ConstPtr();
|
||||||
|
|
||||||
ParserTreeItem::Ptr itemPtr = ParserTreeItem::parseDocument(doc);
|
ParserTreeItem::ConstPtr itemPtr = ParserTreeItem::parseDocument(doc);
|
||||||
|
|
||||||
d->m_documentCache.insert(fileName, { doc->revision(), itemPtr, doc } );
|
d->m_documentCache.insert(fileName, { doc->revision(), itemPtr, doc } );
|
||||||
return itemPtr;
|
return itemPtr;
|
||||||
@@ -426,7 +426,7 @@ QStringList Parser::getAllFiles(const Project *project)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't use Project class in this thread
|
// 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)
|
if (!project)
|
||||||
return {};
|
return {};
|
||||||
|
@@ -68,13 +68,13 @@ private:
|
|||||||
|
|
||||||
ParserTreeItem::ConstPtr getParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
ParserTreeItem::ConstPtr getParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
||||||
ParserTreeItem::ConstPtr getCachedOrParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
ParserTreeItem::ConstPtr getCachedOrParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
||||||
ParserTreeItem::Ptr getParseProjectTree(const QStringList &fileList, const QString &projectId);
|
ParserTreeItem::ConstPtr getParseProjectTree(const QStringList &fileList, const QString &projectId);
|
||||||
ParserTreeItem::Ptr getCachedOrParseProjectTree(const QStringList &fileList,
|
ParserTreeItem::ConstPtr getCachedOrParseProjectTree(const QStringList &fileList,
|
||||||
const QString &projectId);
|
const QString &projectId);
|
||||||
ParserTreeItem::ConstPtr parse();
|
ParserTreeItem::ConstPtr parse();
|
||||||
|
|
||||||
QStringList getAllFiles(const ProjectExplorer::Project *project);
|
QStringList getAllFiles(const ProjectExplorer::Project *project);
|
||||||
ParserTreeItem::Ptr addFlatTree(const ProjectExplorer::Project *project);
|
ParserTreeItem::ConstPtr addFlatTree(const ProjectExplorer::Project *project);
|
||||||
|
|
||||||
//! Private class data pointer
|
//! Private class data pointer
|
||||||
ParserPrivate *d;
|
ParserPrivate *d;
|
||||||
|
@@ -66,9 +66,9 @@ class ParserTreeItemPrivate
|
|||||||
public:
|
public:
|
||||||
void mergeWith(const ParserTreeItem::ConstPtr &target);
|
void mergeWith(const ParserTreeItem::ConstPtr &target);
|
||||||
void mergeSymbol(const CPlusPlus::Symbol *symbol);
|
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;
|
QSet<SymbolLocation> m_symbolLocations;
|
||||||
const Utils::FilePath m_projectFilePath;
|
const Utils::FilePath m_projectFilePath;
|
||||||
};
|
};
|
||||||
@@ -84,13 +84,13 @@ void ParserTreeItemPrivate::mergeWith(const ParserTreeItem::ConstPtr &target)
|
|||||||
for (auto it = target->d->m_symbolInformations.cbegin();
|
for (auto it = target->d->m_symbolInformations.cbegin();
|
||||||
it != target->d->m_symbolInformations.cend(); ++it) {
|
it != target->d->m_symbolInformations.cend(); ++it) {
|
||||||
const SymbolInformation &inf = it.key();
|
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()) {
|
if (!child.isNull()) {
|
||||||
child->d->mergeWith(targetChild);
|
child->d->mergeWith(targetChild);
|
||||||
} else {
|
} else {
|
||||||
const ParserTreeItem::Ptr clone = targetChild.isNull() ? ParserTreeItem::Ptr()
|
const ParserTreeItem::ConstPtr clone = targetChild.isNull() ? ParserTreeItem::ConstPtr()
|
||||||
: targetChild->d->cloneTree();
|
: targetChild->d->cloneTree();
|
||||||
m_symbolInformations.insert(inf, clone);
|
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.
|
// If next line will be removed, 5% speed up for the initial parsing.
|
||||||
// But there might be a problem for some files ???
|
// But there might be a problem for some files ???
|
||||||
// Better to improve qHash timing
|
// Better to improve qHash timing
|
||||||
ParserTreeItem::Ptr childItem = m_symbolInformations.value(information);
|
ParserTreeItem::ConstPtr childItem = m_symbolInformations.value(information);
|
||||||
|
|
||||||
if (childItem.isNull())
|
if (childItem.isNull())
|
||||||
childItem = ParserTreeItem::Ptr(new ParserTreeItem());
|
childItem = ParserTreeItem::ConstPtr(new ParserTreeItem());
|
||||||
|
|
||||||
// locations have 1-based column in Symbol, use the same here.
|
// locations have 1-based column in Symbol, use the same here.
|
||||||
SymbolLocation location(QString::fromUtf8(symbol->fileName() , symbol->fileNameLength()),
|
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.
|
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;
|
newItem->d->m_symbolLocations = m_symbolLocations;
|
||||||
|
|
||||||
for (auto it = m_symbolInformations.cbegin(); it != m_symbolInformations.cend(); ++it) {
|
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, {}, {}}))
|
: d(new ParserTreeItemPrivate({children, {}, {}}))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -226,7 +226,7 @@ QSet<SymbolLocation> ParserTreeItem::symbolLocations() const
|
|||||||
Returns the child item specified by \a inf symbol information.
|
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);
|
return d->m_symbolInformations.value(inf);
|
||||||
}
|
}
|
||||||
@@ -240,9 +240,9 @@ int ParserTreeItem::childCount() const
|
|||||||
return d->m_symbolInformations.count();
|
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();
|
const unsigned total = doc->globalSymbolCount();
|
||||||
for (unsigned i = 0; i < total; ++i)
|
for (unsigned i = 0; i < total; ++i)
|
||||||
@@ -251,10 +251,10 @@ ParserTreeItem::Ptr ParserTreeItem::parseDocument(const CPlusPlus::Document::Ptr
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParserTreeItem::Ptr ParserTreeItem::mergeTrees(const Utils::FilePath &projectFilePath,
|
ParserTreeItem::ConstPtr ParserTreeItem::mergeTrees(const Utils::FilePath &projectFilePath,
|
||||||
const QList<ConstPtr> &docTrees)
|
const QList<ConstPtr> &docTrees)
|
||||||
{
|
{
|
||||||
Ptr item(new ParserTreeItem(projectFilePath));
|
ConstPtr item(new ParserTreeItem(projectFilePath));
|
||||||
for (const ConstPtr &docTree : docTrees)
|
for (const ConstPtr &docTree : docTrees)
|
||||||
item->d->mergeWith(docTree);
|
item->d->mergeWith(docTree);
|
||||||
|
|
||||||
@@ -299,13 +299,13 @@ void ParserTreeItem::fetchMore(QStandardItem *item) const
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// convert to map - to sort it
|
// 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)
|
for (auto it = d->m_symbolInformations.cbegin(); it != d->m_symbolInformations.cend(); ++it)
|
||||||
map.insert(it.key(), it.value());
|
map.insert(it.key(), it.value());
|
||||||
|
|
||||||
for (auto it = map.cbegin(); it != map.cend(); ++it) {
|
for (auto it = map.cbegin(); it != map.cend(); ++it) {
|
||||||
const SymbolInformation &inf = it.key();
|
const SymbolInformation &inf = it.key();
|
||||||
Ptr ptr = it.value();
|
ConstPtr ptr = it.value();
|
||||||
|
|
||||||
auto add = new QStandardItem;
|
auto add = new QStandardItem;
|
||||||
add->setData(inf.name(), Constants::SymbolNameRole);
|
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) {
|
for (auto it = d->m_symbolInformations.cbegin(); it != d->m_symbolInformations.cend(); ++it) {
|
||||||
const SymbolInformation &inf = it.key();
|
const SymbolInformation &inf = it.key();
|
||||||
const Ptr &child = it.value();
|
const ConstPtr &child = it.value();
|
||||||
qDebug() << QString(2 * indent, QLatin1Char(' ')) << inf.iconType() << inf.name()
|
qDebug() << QString(2 * indent, QLatin1Char(' ')) << inf.iconType() << inf.name()
|
||||||
<< inf.type() << child.isNull();
|
<< inf.type() << child.isNull();
|
||||||
if (!child.isNull())
|
if (!child.isNull())
|
||||||
|
@@ -43,21 +43,20 @@ class ParserTreeItemPrivate;
|
|||||||
class ParserTreeItem
|
class ParserTreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Ptr = QSharedPointer<ParserTreeItem>;
|
|
||||||
using ConstPtr = QSharedPointer<const ParserTreeItem>;
|
using ConstPtr = QSharedPointer<const ParserTreeItem>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParserTreeItem();
|
ParserTreeItem();
|
||||||
ParserTreeItem(const Utils::FilePath &projectFilePath);
|
ParserTreeItem(const Utils::FilePath &projectFilePath);
|
||||||
ParserTreeItem(const QHash<SymbolInformation, Ptr> &children);
|
ParserTreeItem(const QHash<SymbolInformation, ConstPtr> &children);
|
||||||
~ParserTreeItem();
|
~ParserTreeItem();
|
||||||
|
|
||||||
static Ptr parseDocument(const CPlusPlus::Document::Ptr &doc);
|
static ConstPtr parseDocument(const CPlusPlus::Document::Ptr &doc);
|
||||||
static Ptr mergeTrees(const Utils::FilePath &projectFilePath, const QList<ConstPtr> &docTrees);
|
static ConstPtr mergeTrees(const Utils::FilePath &projectFilePath, const QList<ConstPtr> &docTrees);
|
||||||
|
|
||||||
Utils::FilePath projectFilePath() const;
|
Utils::FilePath projectFilePath() const;
|
||||||
QSet<SymbolLocation> symbolLocations() const;
|
QSet<SymbolLocation> symbolLocations() const;
|
||||||
Ptr child(const SymbolInformation &inf) const;
|
ConstPtr child(const SymbolInformation &inf) const;
|
||||||
int childCount() const;
|
int childCount() const;
|
||||||
|
|
||||||
// Make sure that below two methods are called only from the GUI thread
|
// Make sure that below two methods are called only from the GUI thread
|
||||||
|
Reference in New Issue
Block a user