aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@digia.com>2013-06-18 15:35:04 +0200
committerTobias Hunger <tobias.hunger@digia.com>2013-06-20 17:15:52 +0200
commit22a2777a898fdef6f2d5fc4f93a8c11682ecf4ea (patch)
tree3bbbfab563eabd4caa44f835bb5efefeb2bacfac
parent590c138dc9fe8ece6d7c21fc61f33012cb0c7691 (diff)
Store list of files that are part of the project
Store a list of all files that are referenced when resolving the project as part of the project. This list is then processed to check whether the project needs to be re-resolved. Change-Id: Iccb8928a5349546c22a9615256a505bebf5de567 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
-rw-r--r--src/lib/api/project.cpp5
-rw-r--r--src/lib/api/project.h2
-rw-r--r--src/lib/buildgraph/buildgraphloader.cpp38
-rw-r--r--src/lib/language/itemreader.cpp6
-rw-r--r--src/lib/language/itemreader.h3
-rw-r--r--src/lib/language/language.cpp2
-rw-r--r--src/lib/language/language.h2
-rw-r--r--src/lib/language/moduleloader.cpp1
-rw-r--r--src/lib/language/moduleloader.h1
-rw-r--r--src/lib/language/projectresolver.cpp5
-rw-r--r--src/lib/language/scriptengine.cpp5
-rw-r--r--src/lib/language/scriptengine.h1
-rw-r--r--src/lib/tools/persistence.cpp2
13 files changed, 64 insertions, 9 deletions
diff --git a/src/lib/api/project.cpp b/src/lib/api/project.cpp
index d1819ec6a..7b2b783e3 100644
--- a/src/lib/api/project.cpp
+++ b/src/lib/api/project.cpp
@@ -491,4 +491,9 @@ QHash<QString, QString> Project::usedEnvironment() const
return d->internalProject->usedEnvironment;
}
+QSet<QString> Project::buildSystemFiles() const
+{
+ return d->internalProject->buildSystemFiles;
+}
+
} // namespace qbs
diff --git a/src/lib/api/project.h b/src/lib/api/project.h
index e69bb5232..291697259 100644
--- a/src/lib/api/project.h
+++ b/src/lib/api/project.h
@@ -105,6 +105,8 @@ public:
QVariantMap projectConfiguration() const;
QHash<QString, QString> usedEnvironment() const;
+ QSet<QString> buildSystemFiles() const;
+
private:
Project();
Project(const Internal::TopLevelProjectPtr &internalProject, const Internal::Logger &logger);
diff --git a/src/lib/buildgraph/buildgraphloader.cpp b/src/lib/buildgraph/buildgraphloader.cpp
index eea9bbd73..181193d03 100644
--- a/src/lib/buildgraph/buildgraphloader.cpp
+++ b/src/lib/buildgraph/buildgraphloader.cpp
@@ -215,12 +215,15 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters &paramet
const QString &buildGraphFilePath, const TopLevelProjectPtr &restoredProject)
{
const FileInfo bgfi(buildGraphFilePath);
+ QSet<QString> buildSystemFiles = restoredProject->buildSystemFiles;
const QList<ResolvedProjectPtr> allRestoredProjects
= restoredProject->allSubProjects() << restoredProject;
bool projectFileChanged = false;
bool subProjectRemoved = false;
foreach (const ResolvedProjectConstPtr &p, allRestoredProjects) {
- FileInfo fi(p->location.fileName());
+ const QString fileName = p->location.fileName();
+ const FileInfo fi(fileName);
+ buildSystemFiles.remove(fileName);
if (!fi.exists()) {
subProjectRemoved = true;
break;
@@ -230,10 +233,16 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters &paramet
break;
}
}
- if (subProjectRemoved)
+ if (subProjectRemoved) {
m_logger.qbsTrace() << "A sub-project was removed, must re-resolve project";
- if (projectFileChanged)
+ // Save build graph to prevent a re-resolve on every run now.
+ restoredProject->buildData->isDirty = true;
+ }
+ if (projectFileChanged) {
m_logger.qbsTrace() << "A project file changed, must re-resolve project.";
+ // Save build graph to prevent a re-resolve on every run now.
+ restoredProject->buildData->isDirty = true;
+ }
bool environmentChanged = false;
for (QHash<QString, QString>::ConstIterator it = restoredProject->usedEnvironment.constBegin();
@@ -247,7 +256,9 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters &paramet
const QList<ResolvedProductPtr> allRestoredProducts = restoredProject->allProducts();
QList<ResolvedProductPtr> changedProducts;
foreach (const ResolvedProductPtr &product, allRestoredProducts) {
- const FileInfo pfi(product->location.fileName());
+ const QString fileName = product->location.fileName();
+ const FileInfo pfi(fileName);
+ buildSystemFiles.remove(fileName);
if (!pfi.exists()) {
productRemoved = true;
} else if (bgfi.lastModified() < pfi.lastModified()) {
@@ -269,10 +280,23 @@ void BuildGraphLoader::trackProjectChanges(const SetupProjectParameters &paramet
}
}
- if (!environmentChanged && !projectFileChanged && !subProjectRemoved && !productRemoved
- && changedProducts.isEmpty()) {
- return;
+ bool filesChanged = false;
+ foreach (const QString &file, buildSystemFiles) {
+ const FileInfo fi(file);
+ if (!fi.exists() || bgfi.lastModified() < fi.lastModified()) {
+ filesChanged = true;
+ break;
+ }
}
+ if (filesChanged) {
+ m_logger.qbsTrace() << "A qbs or js file changed, must re-resolve project";
+ // Save build graph to prevent a re-resolve on every run now.
+ restoredProject->buildData->isDirty = true;
+ }
+
+ if (!filesChanged && !environmentChanged && !projectFileChanged
+ && !subProjectRemoved && !productRemoved && changedProducts.isEmpty())
+ return;
Loader ldr(m_evalContext->engine(), m_logger);
ldr.setSearchPaths(parameters.searchPaths());
diff --git a/src/lib/language/itemreader.cpp b/src/lib/language/itemreader.cpp
index 6222d6f1e..1c2bd6de0 100644
--- a/src/lib/language/itemreader.cpp
+++ b/src/lib/language/itemreader.cpp
@@ -115,6 +115,11 @@ Item *ItemReader::readFile(const QString &filePath)
return internalReadFile(filePath).rootItem;
}
+QSet<QString> ItemReader::filesRead() const
+{
+ return m_filesRead;
+}
+
ItemReaderResult ItemReader::internalReadFile(const QString &filePath)
{
ASTCacheValue &cacheValue = (*m_astCache)[filePath];
@@ -126,6 +131,7 @@ ItemReaderResult ItemReader::internalReadFile(const QString &filePath)
if (Q_UNLIKELY(!file.open(QFile::ReadOnly)))
throw ErrorInfo(Tr::tr("Couldn't open '%1'.").arg(filePath));
+ m_filesRead.insert(filePath);
const QString code = QTextStream(&file).readAll();
QbsQmlJS::Lexer lexer(cacheValue.engine());
lexer.setCode(code, 1);
diff --git a/src/lib/language/itemreader.h b/src/lib/language/itemreader.h
index 484514795..d444c9064 100644
--- a/src/lib/language/itemreader.h
+++ b/src/lib/language/itemreader.h
@@ -80,6 +80,8 @@ public:
Item *readFile(const QString &filePath);
+ QSet<QString> filesRead() const;
+
private:
ItemReaderResult internalReadFile(const QString &filePath);
@@ -91,6 +93,7 @@ private:
class ASTCache;
ASTCache *m_astCache;
+ QSet<QString> m_filesRead;
};
} // namespace Internal
diff --git a/src/lib/language/language.cpp b/src/lib/language/language.cpp
index b95600b80..8be684693 100644
--- a/src/lib/language/language.cpp
+++ b/src/lib/language/language.cpp
@@ -725,6 +725,7 @@ void TopLevelProject::load(PersistentPool &pool)
pool.stream() >> envHash;
for (QHash<QString, QString>::const_iterator i = envHash.begin(); i != envHash.end(); ++i)
environment.insert(i.key(), i.value());
+ pool.stream() >> buildSystemFiles;
buildData.reset(pool.idLoad<ProjectBuildData>());
buildData->isDirty = false;
}
@@ -738,6 +739,7 @@ void TopLevelProject::store(PersistentPool &pool) const
foreach (const QString &key, environment.keys())
envHash.insert(key, environment.value(key));
pool.stream() << envHash;
+ pool.stream() << buildSystemFiles;
pool.store(buildData.data());
}
diff --git a/src/lib/language/language.h b/src/lib/language/language.h
index 4fb477e86..e1a549855 100644
--- a/src/lib/language/language.h
+++ b/src/lib/language/language.h
@@ -368,6 +368,8 @@ public:
QHash<QString, QString> usedEnvironment; // Environment variables requested by the project while resolving.
QScopedPointer<ProjectBuildData> buildData;
+ QSet<QString> buildSystemFiles;
+
void setBuildConfiguration(const QVariantMap &config);
const QVariantMap &buildConfiguration() const { return m_buildConfiguration; }
QString id() const { return m_id; }
diff --git a/src/lib/language/moduleloader.cpp b/src/lib/language/moduleloader.cpp
index 7569e44c8..e4e0204c2 100644
--- a/src/lib/language/moduleloader.cpp
+++ b/src/lib/language/moduleloader.cpp
@@ -114,6 +114,7 @@ ModuleLoaderResult ModuleLoader::load(const QString &filePath, const QVariantMap
handleProject(&result, root);
result.root = root;
+ result.qbsFiles = m_reader->filesRead();
return result;
}
diff --git a/src/lib/language/moduleloader.h b/src/lib/language/moduleloader.h
index 8ea9448fe..2d936a643 100644
--- a/src/lib/language/moduleloader.h
+++ b/src/lib/language/moduleloader.h
@@ -79,6 +79,7 @@ struct ModuleLoaderResult
QSharedPointer<ItemPool> itemPool;
Item *root;
QHash<Item *, ProductInfo> productInfos;
+ QSet<QString> qbsFiles;
};
/*
diff --git a/src/lib/language/projectresolver.cpp b/src/lib/language/projectresolver.cpp
index e48043ce1..9aeba6f9d 100644
--- a/src/lib/language/projectresolver.cpp
+++ b/src/lib/language/projectresolver.cpp
@@ -95,7 +95,9 @@ TopLevelProjectPtr ProjectResolver::resolve(ModuleLoaderResult &loadResult,
m_productContext = 0;
m_moduleContext = 0;
resolveTopLevelProject(loadResult.root, &projectContext);
- return projectContext.project.staticCast<TopLevelProject>();
+ TopLevelProjectPtr top = projectContext.project.staticCast<TopLevelProject>();
+ top->buildSystemFiles.unite(loadResult.qbsFiles);
+ return top;
}
void ProjectResolver::checkCancelation() const
@@ -162,6 +164,7 @@ void ProjectResolver::resolveTopLevelProject(Item *item, ProjectContext *project
resolveProject(item, projectContext);
project->usedEnvironment = m_engine->usedEnvironment();
project->environment = m_environment;
+ project->buildSystemFiles = m_engine->imports();
makeSubProjectNamesUniqe(project);
resolveProductDependencies(projectContext);
}
diff --git a/src/lib/language/scriptengine.cpp b/src/lib/language/scriptengine.cpp
index 5cdaedd8c..d182afbbe 100644
--- a/src/lib/language/scriptengine.cpp
+++ b/src/lib/language/scriptengine.cpp
@@ -238,6 +238,11 @@ void ScriptEngine::addEnvironmentVariable(const QString &name, const QString &va
m_usedEnvironment.insert(name, value);
}
+QSet<QString> ScriptEngine::imports() const
+{
+ return QSet<QString>::fromList(m_jsImportCache.keys());
+}
+
class JSTypeExtender
{
public:
diff --git a/src/lib/language/scriptengine.h b/src/lib/language/scriptengine.h
index fc1560dc7..afbea5889 100644
--- a/src/lib/language/scriptengine.h
+++ b/src/lib/language/scriptengine.h
@@ -77,6 +77,7 @@ public:
void setEnvironment(const QProcessEnvironment &env);
void addEnvironmentVariable(const QString &name, const QString &value);
QHash<QString, QString> usedEnvironment() const { return m_usedEnvironment; }
+ QSet<QString> imports() const;
private:
void extendJavaScriptBuiltins();
diff --git a/src/lib/tools/persistence.cpp b/src/lib/tools/persistence.cpp
index 96de019b1..0488d579b 100644
--- a/src/lib/tools/persistence.cpp
+++ b/src/lib/tools/persistence.cpp
@@ -40,7 +40,7 @@
namespace qbs {
namespace Internal {
-static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-41";
+static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-42";
PersistentPool::PersistentPool(const Logger &logger) : m_logger(logger)
{