예제 #1
0
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);
        }
    }
예제 #2
0
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());
}
예제 #3
0
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);
}