aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/language/modulemerger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/corelib/language/modulemerger.cpp')
-rw-r--r--src/lib/corelib/language/modulemerger.cpp267
1 files changed, 0 insertions, 267 deletions
diff --git a/src/lib/corelib/language/modulemerger.cpp b/src/lib/corelib/language/modulemerger.cpp
deleted file mode 100644
index 6ad8e2259..000000000
--- a/src/lib/corelib/language/modulemerger.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qbs.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "modulemerger.h"
-
-#include "value.h"
-
-#include <logging/translator.h>
-#include <tools/qbsassert.h>
-#include <tools/qttools.h>
-#include <tools/stlutils.h>
-#include <tools/stringconstants.h>
-
-namespace qbs {
-namespace Internal {
-
-ModuleMerger::ModuleMerger(Logger &logger, Item *productItem, const QString &productName,
- const Item::Modules::iterator &modulesBegin,
- const Item::Modules::iterator &modulesEnd)
- : m_logger(logger)
- , m_productItem(productItem)
- , m_mergedModule(*modulesBegin)
- , m_isBaseModule(m_mergedModule.name.first() == StringConstants::qbsModule())
- , m_isShadowProduct(productName.startsWith(StringConstants::shadowProductPrefix()))
- , m_modulesBegin(std::next(modulesBegin))
- , m_modulesEnd(modulesEnd)
-{
- QBS_CHECK(modulesBegin->item->type() == ItemType::ModuleInstance);
-}
-
-void ModuleMerger::replaceItemInValues(QualifiedId moduleName, Item *containerItem, Item *toReplace)
-{
- QBS_CHECK(!moduleName.empty());
- QBS_CHECK(containerItem != m_mergedModule.item);
- const QString moduleNamePrefix = moduleName.takeFirst();
- const Item::PropertyMap &properties = containerItem->properties();
- for (auto it = properties.begin(); it != properties.end(); ++it) {
- if (it.key() != moduleNamePrefix)
- continue;
- Value * const val = it.value().get();
- QBS_CHECK(val);
- QBS_CHECK(val->type() == Value::ItemValueType);
- const auto itemVal = static_cast<ItemValue *>(val);
- if (moduleName.empty()) {
- QBS_CHECK(itemVal->item() == toReplace);
- itemVal->setItem(m_mergedModule.item);
- } else {
- replaceItemInValues(moduleName, itemVal->item(), toReplace);
- }
- }
-}
-
-void ModuleMerger::start()
-{
- // Iterate over any module that our product depends on. These modules
- // may depend on m_mergedModule and contribute property assignments.
- Item::PropertyMap props;
- for (auto module = m_modulesBegin; module != m_modulesEnd; module++)
- mergeModule(&props, *module);
-
- // Module property assignments in the product have the highest priority
- // and are thus prepended.
- Item::Module m;
- m.item = m_productItem;
- mergeModule(&props, m);
-
- // The module's prototype is the essential unmodified module as loaded
- // from the cache.
- Item *moduleProto = m_mergedModule.item->prototype();
- while (moduleProto->prototype())
- moduleProto = moduleProto->prototype();
-
- // The prototype item might contain default values which get appended in
- // case of list properties. Scalar properties will only be set if not
- // already specified above.
- Item::PropertyMap mergedProps = m_mergedModule.item->properties();
- for (auto it = props.constBegin(); it != props.constEnd(); ++it) {
- appendPrototypeValueToNextChain(moduleProto, it.key(), it.value());
- mergedProps[it.key()] = it.value();
- }
-
- m_mergedModule.item->setProperties(mergedProps);
-
- // Update all sibling instances of the to-be-merged module to behave identical
- // to the merged module.
- for (Item *moduleInstanceContainer : qAsConst(m_moduleInstanceContainers)) {
- Item::Modules modules;
- for (const Item::Module &dep : moduleInstanceContainer->modules()) {
- const bool isTheModule = dep.name == m_mergedModule.name;
- Item::Module m = dep;
- if (isTheModule && m.item != m_mergedModule.item) {
- QBS_CHECK(m.item->type() == ItemType::ModuleInstance);
- replaceItemInValues(m.name, moduleInstanceContainer, m.item);
- m.item = m_mergedModule.item;
- m.required = m_mergedModule.required;
- m.versionRange = m_mergedModule.versionRange;
- m.fallbackEnabled = m_mergedModule.fallbackEnabled;
- }
- modules << m;
- }
- moduleInstanceContainer->setModules(modules);
- }
-}
-
-void ModuleMerger::mergeModule(Item::PropertyMap *dstProps, const Item::Module &module)
-{
- const Item::Module *dep = findModule(module.item, m_mergedModule.name);
- if (!dep)
- return;
-
- const bool mergingProductItem = (module.item == m_productItem);
- Item *srcItem = dep->item;
- Item *origSrcItem = srcItem;
- do {
- if (m_seenInstances.insert(srcItem).second) {
- for (auto it = srcItem->properties().constBegin();
- it != srcItem->properties().constEnd(); ++it) {
- const ValuePtr &srcVal = it.value();
- if (srcVal->type() == Value::ItemValueType)
- continue;
- if (it.key() == StringConstants::qbsSourceDirPropertyInternal())
- continue;
- const PropertyDeclaration srcDecl = srcItem->propertyDeclaration(it.key());
- if (!srcDecl.isValid())
- continue;
-
- // Scalar variant values could stem from product multiplexing, in which case
- // the merged qbs module instance needs to get that value.
- if (srcVal->type() == Value::VariantValueType
- && (!srcDecl.isScalar() || !m_isBaseModule)) {
- continue;
- }
-
- ValuePtr clonedSrcVal = srcVal->clone();
- clonedSrcVal->setDefiningItem(origSrcItem);
-
- ValuePtr &dstVal = (*dstProps)[it.key()];
- if (dstVal) {
- if (srcDecl.isScalar()) {
- // Scalar properties get replaced.
- if ((dstVal->type() == Value::JSSourceValueType)
- && (srcVal->type() == Value::JSSourceValueType)) {
- // Warn only about conflicting source code values
- const JSSourceValuePtr dstJsVal =
- std::static_pointer_cast<JSSourceValue>(dstVal);
- const JSSourceValuePtr srcJsVal =
- std::static_pointer_cast<JSSourceValue>(srcVal);
- const bool overriddenInProduct =
- m_mergedModule.item->properties().contains(it.key());
-
- if (dstJsVal->sourceCode() != srcJsVal->sourceCode()
- && !mergingProductItem && !overriddenInProduct
- && !m_isShadowProduct) {
- m_logger.qbsWarning()
- << Tr::tr("Conflicting scalar values at %1 and %2.").arg(
- dstJsVal->location().toString(),
- srcJsVal->location().toString());
- }
- }
- } else {
- // List properties get prepended
- QBS_CHECK(!clonedSrcVal->next());
- clonedSrcVal->setNext(dstVal);
- }
- }
- dstVal = clonedSrcVal;
- }
- }
- srcItem = srcItem->prototype();
- } while (srcItem && srcItem->type() == ItemType::ModuleInstance);
-
- // Update dependency constraints
- if (dep->required)
- m_mergedModule.required = true;
- // if one dep has fallback disabled, disable it for the merged module
- m_mergedModule.fallbackEnabled = m_mergedModule.fallbackEnabled && dep->fallbackEnabled;
- m_mergedModule.versionRange.narrowDown(dep->versionRange);
-
- // We need to touch the unmerged module instances later once more
- m_moduleInstanceContainers << module.item;
-}
-
-void ModuleMerger::appendPrototypeValueToNextChain(Item *moduleProto, const QString &propertyName,
- const ValuePtr &sv)
-{
- const PropertyDeclaration pd = m_mergedModule.item->propertyDeclaration(propertyName);
- if (pd.isScalar())
- return;
- if (!m_clonedModulePrototype) {
- m_clonedModulePrototype = Item::create(moduleProto->pool(), ItemType::Module);
- m_clonedModulePrototype->setScope(m_mergedModule.item);
- m_clonedModulePrototype->setLocation(moduleProto->location());
- moduleProto->copyProperty(StringConstants::nameProperty(), m_clonedModulePrototype);
- }
- const ValuePtr &protoValue = moduleProto->property(propertyName);
- QBS_CHECK(protoValue);
- const ValuePtr clonedValue = protoValue->clone();
- lastInNextChain(sv)->setNext(clonedValue);
- clonedValue->setDefiningItem(m_clonedModulePrototype);
- m_clonedModulePrototype->setPropertyDeclaration(propertyName, pd);
- m_clonedModulePrototype->setProperty(propertyName, clonedValue);
-}
-
-ValuePtr ModuleMerger::lastInNextChain(const ValuePtr &v)
-{
- ValuePtr n = v;
- while (n->next())
- n = n->next();
- return n;
-}
-
-const Item::Module *ModuleMerger::findModule(const Item *item, const QualifiedId &name)
-{
- for (const auto &module : item->modules()) {
- if (module.name == name)
- return &module;
- }
- return nullptr;
-}
-
-void ModuleMerger::merge(Logger &logger, Item *product, const QString &productName,
- Item::Modules *topSortedModules)
-{
- for (auto it = topSortedModules->begin(); it != topSortedModules->end(); ++it)
- ModuleMerger(logger, product, productName, it, topSortedModules->end()).start();
-}
-
-
-
-} // namespace Internal
-} // namespace qbs