QbsProjectManager: Sanitize QbsProjectNode.

The current code keeps an instance of QbsProject and of qbs::Project in
every project node, with them being null/invalid everywhere except for
the top-level node. Instead, introduce a dedicated class for the root
node and hold a QbsProject only there. The qbs::Project is held in
QbsProject now.
As a nice side effect, this also fixes QBS-644, presumably because the
dubious-looking use of projectNode() has been removed.

Task-number: QBS-644
Change-Id: I5d36806745b9d67879db6f48aa56bc97868e4f17
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
This commit is contained in:
Christian Kandeler
2014-07-10 17:01:54 +02:00
parent 5e8bd53a79
commit 853497fb4b
4 changed files with 56 additions and 66 deletions

View File

@@ -42,8 +42,6 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <qbs.h>
#include <QDir> #include <QDir>
#include <QStyle> #include <QStyle>
@@ -746,16 +744,8 @@ QbsGroupNode *QbsProductNode::findGroupNode(const QString &name)
// QbsProjectNode: // QbsProjectNode:
// -------------------------------------------------------------------- // --------------------------------------------------------------------
QbsProjectNode::QbsProjectNode(QbsProject *project) :
QbsBaseProjectNode(project->projectFilePath().toString()),
m_project(project)
{
ctor();
}
QbsProjectNode::QbsProjectNode(const QString &path) : QbsProjectNode::QbsProjectNode(const QString &path) :
QbsBaseProjectNode(path), QbsBaseProjectNode(path)
m_project(0)
{ {
ctor(); ctor();
} }
@@ -771,19 +761,6 @@ bool QbsProjectNode::addFiles(const QStringList &filePaths, QStringList *notAdde
return prd ? prd->addFiles(filePaths, notAdded) : false; return prd ? prd->addFiles(filePaths, notAdded) : false;
} }
void QbsProjectNode::setProject(const qbs::Project &prj)
{
m_qbsProject = prj;
}
void QbsProjectNode::update()
{
if (m_qbsProject.isValid())
update(m_qbsProject.projectData());
else
update(qbs::ProjectData());
}
void QbsProjectNode::update(const qbs::ProjectData &prjData) void QbsProjectNode::update(const qbs::ProjectData &prjData)
{ {
QList<ProjectExplorer::ProjectNode *> toAdd; QList<ProjectExplorer::ProjectNode *> toAdd;
@@ -814,7 +791,7 @@ void QbsProjectNode::update(const qbs::ProjectData &prjData)
if (!prjData.name().isEmpty()) if (!prjData.name().isEmpty())
setDisplayName(prjData.name()); setDisplayName(prjData.name());
else else
setDisplayName(m_project->displayName()); setDisplayName(project()->displayName());
removeProjectNodes(toRemove); removeProjectNodes(toRemove);
addProjectNodes(toAdd); addProjectNodes(toAdd);
@@ -822,25 +799,17 @@ void QbsProjectNode::update(const qbs::ProjectData &prjData)
QbsProject *QbsProjectNode::project() const QbsProject *QbsProjectNode::project() const
{ {
if (!m_project && projectNode()) return static_cast<QbsProjectNode *>(parentFolderNode())->project();
return static_cast<QbsProjectNode *>(projectNode())->project();
return m_project;
} }
const qbs::Project QbsProjectNode::qbsProject() const const qbs::Project QbsProjectNode::qbsProject() const
{ {
QbsProjectNode *parent = qobject_cast<QbsProjectNode *>(projectNode()); return project()->qbsProject();
if (!m_qbsProject.isValid() && parent != this)
return parent->qbsProject();
return m_qbsProject;
} }
const qbs::ProjectData QbsProjectNode::qbsProjectData() const const qbs::ProjectData QbsProjectNode::qbsProjectData() const
{ {
if (m_qbsProject.isValid()) return project()->qbsProjectData();
return m_qbsProject.projectData();
else
return qbs::ProjectData();
} }
bool QbsProjectNode::showInSimpleTree() const bool QbsProjectNode::showInSimpleTree() const
@@ -878,5 +847,17 @@ QbsProjectNode *QbsProjectNode::findProjectNode(const QString &name)
return 0; return 0;
} }
QbsRootProjectNode::QbsRootProjectNode(QbsProject *project) :
QbsProjectNode(project->projectFilePath().toString()),
m_project(project)
{
}
void QbsRootProjectNode::update()
{
update(m_project->qbsProjectData());
}
} // namespace Internal } // namespace Internal
} // namespace QbsProjectManager } // namespace QbsProjectManager

View File

@@ -36,8 +36,6 @@
#include <QIcon> #include <QIcon>
namespace qbs { class Project; }
namespace QbsProjectManager { namespace QbsProjectManager {
namespace Internal { namespace Internal {
@@ -165,34 +163,46 @@ class QbsProjectNode : public QbsBaseProjectNode
Q_OBJECT Q_OBJECT
public: public:
explicit QbsProjectNode(QbsProject *project);
explicit QbsProjectNode(const QString &path); explicit QbsProjectNode(const QString &path);
~QbsProjectNode(); ~QbsProjectNode();
bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0); bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0);
void setProject(const qbs::Project &prj); // This does *not* update the node tree! virtual QbsProject *project() const;
void update();
QbsProject *project() const;
const qbs::Project qbsProject() const; const qbs::Project qbsProject() const;
const qbs::ProjectData qbsProjectData() const; const qbs::ProjectData qbsProjectData() const;
bool showInSimpleTree() const; bool showInSimpleTree() const;
protected:
void update(const qbs::ProjectData &prjData);
private: private:
void ctor(); void ctor();
void update(const qbs::ProjectData &prjData);
QbsProductNode *findProductNode(const QString &name); QbsProductNode *findProductNode(const QString &name);
QbsProjectNode *findProjectNode(const QString &name); QbsProjectNode *findProjectNode(const QString &name);
QbsProject *m_project;
qbs::Project m_qbsProject;
static QIcon m_projectIcon; static QIcon m_projectIcon;
}; };
class QbsRootProjectNode : public QbsProjectNode
{
Q_OBJECT
public:
explicit QbsRootProjectNode(QbsProject *project);
using QbsProjectNode::update;
void update();
QbsProject *project() const { return m_project; }
private:
QbsProject * const m_project;
};
} // namespace Internal } // namespace Internal
} // namespace QbsProjectManager } // namespace QbsProjectManager

View File

@@ -120,7 +120,7 @@ QbsProject::QbsProject(QbsManager *manager, const QString &fileName) :
updateDocuments(QSet<QString>() << fileName); updateDocuments(QSet<QString>() << fileName);
// NOTE: QbsProjectNode does not use this as a parent! // NOTE: QbsProjectNode does not use this as a parent!
m_rootProjectNode = new QbsProjectNode(this); // needs documents to be initialized! m_rootProjectNode = new QbsRootProjectNode(this); // needs documents to be initialized!
} }
QbsProject::~QbsProject() QbsProject::~QbsProject()
@@ -255,16 +255,14 @@ Utils::FileName QbsProject::defaultBuildDirectory(const QString &projectFilePath
qbs::Project QbsProject::qbsProject() const qbs::Project QbsProject::qbsProject() const
{ {
if (!m_rootProjectNode) return m_qbsProject;
return qbs::Project();
return m_rootProjectNode->qbsProject();
} }
const qbs::ProjectData QbsProject::qbsProjectData() const const qbs::ProjectData QbsProject::qbsProjectData() const
{ {
if (!m_rootProjectNode) if (m_qbsProject.isValid())
return qbs::ProjectData(); return m_qbsProject.projectData();
return m_rootProjectNode->qbsProjectData(); return qbs::ProjectData();
} }
bool QbsProject::needsSpecialDeployment() const bool QbsProject::needsSpecialDeployment() const
@@ -276,12 +274,14 @@ void QbsProject::handleQbsParsingDone(bool success)
{ {
QTC_ASSERT(m_qbsProjectParser, return); QTC_ASSERT(m_qbsProjectParser, return);
qbs::Project project;
if (success)
project = m_qbsProjectParser->qbsProject();
generateErrors(m_qbsProjectParser->error()); generateErrors(m_qbsProjectParser->error());
if (success) {
m_qbsProject = m_qbsProjectParser->qbsProject();
QTC_CHECK(m_qbsProject.isValid());
readQbsData();
}
m_qbsProjectParser->deleteLater(); m_qbsProjectParser->deleteLater();
m_qbsProjectParser = 0; m_qbsProjectParser = 0;
@@ -291,11 +291,6 @@ void QbsProject::handleQbsParsingDone(bool success)
m_qbsUpdateFutureInterface = 0; m_qbsUpdateFutureInterface = 0;
} }
if (project.isValid())
m_rootProjectNode->setProject(project);
readQbsData();
emit projectParsingDone(success); emit projectParsingDone(success);
} }

View File

@@ -38,6 +38,8 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <qbs.h>
#include <QFuture> #include <QFuture>
#include <QTimer> #include <QTimer>
#include <QVariantMap> #include <QVariantMap>
@@ -62,6 +64,7 @@ namespace QbsProjectManager {
namespace Internal { namespace Internal {
class QbsProjectNode; class QbsProjectNode;
class QbsRootProjectNode;
class QbsProjectParser; class QbsProjectParser;
class QbsBuildConfiguration; class QbsBuildConfiguration;
@@ -137,8 +140,9 @@ private:
QbsManager *const m_manager; QbsManager *const m_manager;
const QString m_projectName; const QString m_projectName;
const QString m_fileName; const QString m_fileName;
qbs::Project m_qbsProject;
QSet<Core::IDocument *> m_qbsDocuments; QSet<Core::IDocument *> m_qbsDocuments;
QbsProjectNode *m_rootProjectNode; QbsRootProjectNode *m_rootProjectNode;
QbsProjectParser *m_qbsProjectParser; QbsProjectParser *m_qbsProjectParser;