diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2018-01-19 10:58:43 +0100 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2018-01-19 10:58:43 +0100 |
commit | 13e8c5371709c9e1c337c664062aec19930c306b (patch) | |
tree | 5cf5ad7eeffbf136f0bfcb17375a118d8160f584 /src | |
parent | 8ba1aa806bdb313161acad22d9b16c33b295e607 (diff) | |
parent | d3e137c20248f6852a91341782011ca58534ed21 (diff) |
Merge 1.10 into 1.11
Change-Id: Iae805216e202e582923a70733caa842e8070cc7e
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/corelib/language/item.h | 1 | ||||
-rw-r--r-- | src/lib/corelib/language/moduleloader.cpp | 62 |
2 files changed, 44 insertions, 19 deletions
diff --git a/src/lib/corelib/language/item.h b/src/lib/corelib/language/item.h index b86c50a3c..97ca3ad91 100644 --- a/src/lib/corelib/language/item.h +++ b/src/lib/corelib/language/item.h @@ -164,7 +164,6 @@ private: }; inline bool operator<(const Item::Module &m1, const Item::Module &m2) { return m1.name < m2.name; } -inline bool operator==(const Item::Module &m1, const Item::Module &m2) { return m1.item == m2.item; } } // namespace Internal } // namespace qbs diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index 81d1088b5..35d0636b6 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -1000,17 +1000,42 @@ void ModuleLoader::setupProductDependencies(ProductContext *productContext) productContext->project->result->productInfos.insert(item, productContext->info); } -// Non-dependencies first. +// Leaf modules first. static void createSortedModuleList(const Item::Module &parentModule, Item::Modules &modules) { - if (contains(modules, parentModule)) + if (std::find_if(modules.cbegin(), modules.cend(), + [parentModule](const Item::Module &m) { return m.name == parentModule.name;}) + != modules.cend()) { return; + } for (const Item::Module &dep : parentModule.item->modules()) createSortedModuleList(dep, modules); modules.push_back(parentModule); return; } +static Item::Modules modulesSortedByDependency(const Item *productItem) +{ + QBS_CHECK(productItem->type() == ItemType::Product); + Item::Modules sortedModules; + const Item::Modules &unsortedModules = productItem->modules(); + for (const Item::Module &module : unsortedModules) + createSortedModuleList(module, sortedModules); + QBS_CHECK(sortedModules.size() == unsortedModules.size()); + + // Make sure the top-level items stay the same. + for (Item::Module &s : sortedModules) { + for (const Item::Module &u : unsortedModules) { + if (s.name == u.name) { + s.item = u.item; + break; + } + } + } + return sortedModules; +} + + template<typename T> bool insertIntoSet(Set<T> &set, const T &value) { const auto insertionResult = set.insert(value); @@ -1045,21 +1070,22 @@ void ModuleLoader::handleProduct(ModuleLoader::ProductContext *productContext) Item * const item = productContext->item; - Item::Modules mergedModules; - for (const Item::Module &module : Item::Modules(item->modules())) { - Item::Module mergedModule = module; - ModuleMerger(m_logger, item, mergedModule).start(); - mergedModules << mergedModule; - } - item->setModules(mergedModules); - - // Must happen after all modules have been merged, so needs to be a second loop. - Item::Modules sortedModules; - for (const Item::Module &module : item->modules()) - createSortedModuleList(module, sortedModules); - QBS_CHECK(sortedModules.size() == item->modules().size()); - - for (const Item::Module &module : qAsConst(sortedModules)) { + // It is important that dependent modules are merged after their dependency, because + // the dependent module's merger potentially needs to replace module items that were + // set by the dependency module's merger (namely, scopes of defining items; see + // ModuleMerger::replaceItemInScopes()). + Item::Modules topSortedModules = modulesSortedByDependency(item); + for (Item::Module &module : topSortedModules) + ModuleMerger(m_logger, item, module).start(); + + // Re-sort the modules by name. This is more stable; see QBS-818. + // The list of modules in the product now has the same order as before, + // only the items have been replaced by their merged counterparts. + Item::Modules lexicographicallySortedModules = topSortedModules; + std::sort(lexicographicallySortedModules.begin(), lexicographicallySortedModules.end()); + item->setModules(lexicographicallySortedModules); + + for (const Item::Module &module : topSortedModules) { if (!module.item->isPresentModule()) continue; try { @@ -1101,7 +1127,7 @@ void ModuleLoader::handleProduct(ModuleLoader::ProductContext *productContext) // Module validation must happen in an extra pass, after all Probes have been resolved. EvalCacheEnabler cacheEnabler(m_evaluator); - for (const Item::Module &module : qAsConst(sortedModules)) { + for (const Item::Module &module : topSortedModules) { if (!module.item->isPresentModule()) continue; try { |