QDeclarativeCustomParserProperty 
QDeclarativeCustomParserNodePrivate::fromProperty(QDeclarativeParser::Property *p)
{
    QDeclarativeCustomParserProperty prop;
    prop.d->name = p->name;
    prop.d->isList = (p->values.count() > 1);
    prop.d->location = p->location.start;

    if (p->value) {
        QDeclarativeCustomParserNode node = fromObject(p->value);
        QList<QDeclarativeCustomParserProperty> props = node.properties();
        for (int ii = 0; ii < props.count(); ++ii)
            prop.d->values << QVariant::fromValue(props.at(ii));
    } else {
        for(int ii = 0; ii < p->values.count(); ++ii) {
            QDeclarativeParser::Value *v = p->values.at(ii);
            v->type = QDeclarativeParser::Value::Literal;

            if(v->object) {
                QDeclarativeCustomParserNode node = fromObject(v->object);
                prop.d->values << QVariant::fromValue(node);
            } else {
                prop.d->values << QVariant::fromValue(v->value);
            }

        }
    }

    return prop;
}
/*!
    Reports an error in parsing \a node, with the given \a description.

    An error is generated referring to the position of \a node in the source file.
*/
void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, const QString& description)
{
    QDeclarativeError error;
    QString exceptionDescription;
    error.setLine(node.location().line);
    error.setColumn(node.location().column);
    error.setDescription(description);
    exceptions << error;
}
Beispiel #3
0
bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data)
{
    QList<QVariant> values = prop.assignedValues();
    for(int ii = 0; ii < values.count(); ++ii) {
        const QVariant &value = values.at(ii);

        if(value.userType() == qMetaTypeId<QDeclarativeCustomParserNode>()) {
            QDeclarativeCustomParserNode node =
                qvariant_cast<QDeclarativeCustomParserNode>(value);

            if (node.name() != listElementTypeName) {
                const QMetaObject *mo = resolveType(node.name());
                if (mo != &QDeclarativeListElement::staticMetaObject) {
                    error(node, QDeclarativeListModel::tr("ListElement: cannot contain nested elements"));
                    return false;
                }
                listElementTypeName = node.name(); // cache right name for next time
            }

            {
            ListInstruction li;
            li.type = ListInstruction::Push;
            li.dataIdx = -1;
            instr << li;
            }

            QList<QDeclarativeCustomParserProperty> props = node.properties();
            for(int jj = 0; jj < props.count(); ++jj) {
                const QDeclarativeCustomParserProperty &nodeProp = props.at(jj);
                if (nodeProp.name().isEmpty()) {
                    error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot contain nested elements"));
                    return false;
                }
                if (nodeProp.name() == "id") {
                    error(nodeProp, QDeclarativeListModel::tr("ListElement: cannot use reserved \"id\" property"));
                    return false;
                }

                ListInstruction li;
                int ref = data.count();
                data.append(nodeProp.name());
                data.append('\0');
                li.type = ListInstruction::Set;
                li.dataIdx = ref;
                instr << li;

                if(!compileProperty(nodeProp, instr, data))
                    return false;

                li.type = ListInstruction::Pop;
                li.dataIdx = -1;
                instr << li;
            }

            {
            ListInstruction li;
            li.type = ListInstruction::Pop;
            li.dataIdx = -1;
            instr << li;
            }

        } else {

            QDeclarativeParser::Variant variant =
                qvariant_cast<QDeclarativeParser::Variant>(value);

            int ref = data.count();

            QByteArray d;
            d += char(variant.type()); // type tag
            if (variant.isString()) {
                d += variant.asString().toUtf8();
            } else if (variant.isNumber()) {
                d += QByteArray::number(variant.asNumber(),'g',20);
            } else if (variant.isBoolean()) {
                d += char(variant.asBoolean());
            } else if (variant.isScript()) {
                if (definesEmptyList(variant.asScript())) {
                    d[0] = char(QDeclarativeParser::Variant::Invalid); // marks empty list
                } else {
                    QByteArray script = variant.asScript().toUtf8();
                    int v = evaluateEnum(script);
                    if (v<0) {
                        if (script.startsWith("QT_TR_NOOP(\"") && script.endsWith("\")")) {
                            d[0] = char(QDeclarativeParser::Variant::String);
                            d += script.mid(12,script.length()-14);
                        } else {
                            error(prop, QDeclarativeListModel::tr("ListElement: cannot use script for property value"));
                            return false;
                        }
                    } else {
                        d[0] = char(QDeclarativeParser::Variant::Number);
                        d += QByteArray::number(v);
                    }
                }
            }
            d.append('\0');
            data.append(d);

            ListInstruction li;
            li.type = ListInstruction::Value;
            li.dataIdx = ref;
            instr << li;
        }
    }

    return true;
}