void ModuleMerger::mergeOutProps(Item::PropertyMap *dst, const Item::PropertyMap &src) { for (auto it = src.constBegin(); it != src.constEnd(); ++it) { ValuePtr &v = (*dst)[it.key()]; if (!v) { v = it.value(); QBS_ASSERT(it.value(), continue); continue; } // possible conflict JSSourceValuePtr dstVal = v.dynamicCast<JSSourceValue>(); if (!dstVal) continue; JSSourceValuePtr srcVal = it.value().dynamicCast<JSSourceValue>(); if (!srcVal) continue; const PropertyDeclaration pd = m_decls.value(srcVal); if (!pd.isValid()) continue; if (pd.isScalar()) { if (dstVal->sourceCode() != srcVal->sourceCode()) { m_logger.qbsWarning() << Tr::tr("Conflicting scalar values at %1 and %2.").arg( dstVal->location().toString(), srcVal->location().toString()); // TODO: yield error with a hint how to solve the conflict. } v = it.value(); } else { lastInNextChain(dstVal)->setNext(srcVal); } }
void ModuleMerger::pushScalarProperties(Item::PropertyMap *dst, Item *srcItem) { Item *origSrcItem = srcItem; do { if (!m_seenInstancesTopDown.contains(srcItem)) { m_seenInstancesTopDown.insert(srcItem); for (auto it = srcItem->properties().constBegin(); it != srcItem->properties().constEnd(); ++it) { const ValuePtr &srcVal = it.value(); if (srcVal->type() != Value::JSSourceValueType) continue; const PropertyDeclaration srcDecl = srcItem->propertyDeclaration(it.key()); if (!srcDecl.isValid() || !srcDecl.isScalar()) continue; ValuePtr &v = (*dst)[it.key()]; if (v) continue; ValuePtr clonedVal = srcVal->clone(); m_decls[clonedVal] = srcDecl; clonedVal->setDefiningItem(origSrcItem); v = clonedVal; } } srcItem = srcItem->prototype(); } while (srcItem && srcItem->isModuleInstance()); }
void ModuleMerger::insertProperties(Item::PropertyMap *dst, Item *srcItem, PropertiesType type) { QSet<const Item *> &seenInstances = type == ScalarProperties ? m_seenInstancesTopDown : m_seenInstancesBottomUp; Item *origSrcItem = srcItem; do { if (!seenInstances.contains(srcItem)) { seenInstances.insert(srcItem); for (Item::PropertyMap::const_iterator it = srcItem->properties().constBegin(); it != srcItem->properties().constEnd(); ++it) { const ValuePtr &srcVal = it.value(); if (srcVal->type() != Value::JSSourceValueType) continue; const PropertyDeclaration srcDecl = srcItem->propertyDeclaration(it.key()); if (!srcDecl.isValid() || srcDecl.isScalar() != (type == ScalarProperties)) continue; ValuePtr &v = (*dst)[it.key()]; if (v && type == ScalarProperties) continue; ValuePtr clonedVal = srcVal->clone(); m_decls[clonedVal] = srcDecl; clonedVal->setDefiningItem(origSrcItem); if (v) { QBS_CHECK(!clonedVal->next()); clonedVal->setNext(v); } v = clonedVal; } } srcItem = srcItem->prototype(); } while (srcItem && srcItem->type() == ItemType::ModuleInstance); }