diff options
author | Tobias Hunger <tobias.hunger@digia.com> | 2013-06-18 15:35:04 +0200 |
---|---|---|
committer | Tobias Hunger <tobias.hunger@digia.com> | 2013-06-20 17:15:52 +0200 |
commit | 22a2777a898fdef6f2d5fc4f93a8c11682ecf4ea (patch) | |
tree | 3bbbfab563eabd4caa44f835bb5efefeb2bacfac | |
parent | 590c138dc9fe8ece6d7c21fc61f33012cb0c7691 (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.cpp | 5 | ||||
-rw-r--r-- | src/lib/api/project.h | 2 | ||||
-rw-r--r-- | src/lib/buildgraph/buildgraphloader.cpp | 38 | ||||
-rw-r--r-- | src/lib/language/itemreader.cpp | 6 | ||||
-rw-r--r-- | src/lib/language/itemreader.h | 3 | ||||
-rw-r--r-- | src/lib/language/language.cpp | 2 | ||||
-rw-r--r-- | src/lib/language/language.h | 2 | ||||
-rw-r--r-- | src/lib/language/moduleloader.cpp | 1 | ||||
-rw-r--r-- | src/lib/language/moduleloader.h | 1 | ||||
-rw-r--r-- | src/lib/language/projectresolver.cpp | 5 | ||||
-rw-r--r-- | src/lib/language/scriptengine.cpp | 5 | ||||
-rw-r--r-- | src/lib/language/scriptengine.h | 1 | ||||
-rw-r--r-- | src/lib/tools/persistence.cpp | 2 |
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 ¶met 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 ¶met 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 ¶met 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 ¶met } } - 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) { |