X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fdeclarative%2Fqml%2Fqdeclarativecompiler.cpp;h=c75570dc805b1899841bdeacbcee5993ae2c7c26;hb=a6da3b26f5959986010deb85703cd51a0edb48e0;hp=543ecb24b328b929ea8c8a05df018883dd1756f8;hpb=3d958cec8d53094a1bbab895377e451b07716e1f;p=profile%2Fivi%2Fqtdeclarative.git diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 543ecb2..c75570d 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -123,6 +123,11 @@ QList QDeclarativeCompiler::errors() const */ bool QDeclarativeCompiler::isAttachedPropertyName(const QString &name) { + return isAttachedPropertyName(QStringRef(&name)); +} + +bool QDeclarativeCompiler::isAttachedPropertyName(const QStringRef &name) +{ return !name.isEmpty() && name.at(0) >= 'A' && name.at(0) <= 'Z'; } @@ -139,6 +144,11 @@ bool QDeclarativeCompiler::isAttachedPropertyName(const QString &name) */ bool QDeclarativeCompiler::isSignalPropertyName(const QString &name) { + return isSignalPropertyName(QStringRef(&name)); +} + +bool QDeclarativeCompiler::isSignalPropertyName(const QStringRef &name) +{ if (name.length() < 3) return false; if (!name.startsWith(on_string)) return false; int ns = name.size(); @@ -195,27 +205,33 @@ bool QDeclarativeCompiler::isSignalPropertyName(const QString &name) This test corresponds to action taken by genLiteralAssignment(). Any change made here, must have a corresponding action in genLiteralAssigment(). */ -bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop, +bool QDeclarativeCompiler::testLiteralAssignment(QDeclarativeParser::Property *prop, QDeclarativeParser::Value *v) { const QDeclarativeParser::Variant &value = v->value; - if (!prop.isWritable()) - COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name()))); + if (!prop->core.isWritable()) + COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString())); - if (prop.isEnumType()) { + if (prop->core.isEnum()) { + QMetaProperty p = prop->parent->metaObject()->property(prop->index); int enumValue; - if (prop.isFlagType()) { - enumValue = prop.enumerator().keysToValue(value.asString().toUtf8().constData()); + if (p.isFlagType()) { + enumValue = p.enumerator().keysToValue(value.asString().toUtf8().constData()); } else - enumValue = prop.enumerator().keyToValue(value.asString().toUtf8().constData()); + enumValue = p.enumerator().keyToValue(value.asString().toUtf8().constData()); + if (enumValue == -1) COMPILE_EXCEPTION(v, tr("Invalid property assignment: unknown enumeration")); + + v->value = QDeclarativeParser::Variant((double)enumValue); return true; } - int type = prop.userType(); + + int type = prop->type; + switch(type) { - case -1: + case QMetaType::QVariant: break; case QVariant::String: if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected")); @@ -329,11 +345,9 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop, break; default: { - int t = prop.userType(); - QDeclarativeMetaType::StringConverter converter = - QDeclarativeMetaType::customStringConverter(t); + QDeclarativeMetaType::StringConverter converter = QDeclarativeMetaType::customStringConverter(type); if (!converter) - COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName(prop.type())))); + COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName((QVariant::Type)type)))); } break; } @@ -346,52 +360,45 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop, Any literal assignment that is approved in testLiteralAssignment() must have a corresponding action in this method. */ -void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, +void QDeclarativeCompiler::genLiteralAssignment(QDeclarativeParser::Property *prop, QDeclarativeParser::Value *v) { QDeclarativeInstruction instr; - if (prop.isEnumType()) { - int value; - if (v->value.isNumber()) { - // Preresolved enum - value = (int)v->value.asNumber(); - } else { - // Must be a string - if (prop.isFlagType()) { - value = prop.enumerator().keysToValue(v->value.asString().toUtf8().constData()); - } else - value = prop.enumerator().keyToValue(v->value.asString().toUtf8().constData()); - } + + if (prop->core.isEnum()) { + Q_ASSERT(v->value.isNumber()); + // Preresolved value + int value = (int)v->value.asNumber(); instr.setType(QDeclarativeInstruction::StoreInteger); - instr.storeInteger.propertyIndex = prop.propertyIndex(); + instr.storeInteger.propertyIndex = prop->index; instr.storeInteger.value = value; output->addInstruction(instr); return; } - int type = prop.userType(); + int type = prop->type; switch(type) { - case -1: + case QMetaType::QVariant: { if (v->value.isNumber()) { double n = v->value.asNumber(); if (double(int(n)) == n) { instr.setType(QDeclarativeInstruction::StoreVariantInteger); - instr.storeInteger.propertyIndex = prop.propertyIndex(); + instr.storeInteger.propertyIndex = prop->index; instr.storeInteger.value = int(n); } else { instr.setType(QDeclarativeInstruction::StoreVariantDouble); - instr.storeDouble.propertyIndex = prop.propertyIndex(); + instr.storeDouble.propertyIndex = prop->index; instr.storeDouble.value = n; } } else if(v->value.isBoolean()) { instr.setType(QDeclarativeInstruction::StoreVariantBool); - instr.storeBool.propertyIndex = prop.propertyIndex(); + instr.storeBool.propertyIndex = prop->index; instr.storeBool.value = v->value.asBoolean(); } else { instr.setType(QDeclarativeInstruction::StoreVariant); - instr.storeString.propertyIndex = prop.propertyIndex(); + instr.storeString.propertyIndex = prop->index; instr.storeString.value = output->indexForString(v->value.asString()); } } @@ -399,14 +406,14 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, case QVariant::String: { instr.setType(QDeclarativeInstruction::StoreString); - instr.storeString.propertyIndex = prop.propertyIndex(); + instr.storeString.propertyIndex = prop->index; instr.storeString.value = output->indexForString(v->value.asString()); } break; case QVariant::ByteArray: { instr.setType(QDeclarativeInstruction::StoreByteArray); - instr.storeByteArray.propertyIndex = prop.propertyIndex(); + instr.storeByteArray.propertyIndex = prop->index; instr.storeByteArray.value = output->indexForByteArray(v->value.asString().toLatin1()); } break; @@ -415,35 +422,35 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, instr.setType(QDeclarativeInstruction::StoreUrl); QString string = v->value.asString(); QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string)); - instr.storeUrl.propertyIndex = prop.propertyIndex(); + instr.storeUrl.propertyIndex = prop->index; instr.storeUrl.value = output->indexForUrl(u); } break; case QVariant::UInt: { instr.setType(QDeclarativeInstruction::StoreInteger); - instr.storeInteger.propertyIndex = prop.propertyIndex(); + instr.storeInteger.propertyIndex = prop->index; instr.storeInteger.value = uint(v->value.asNumber()); } break; case QVariant::Int: { instr.setType(QDeclarativeInstruction::StoreInteger); - instr.storeInteger.propertyIndex = prop.propertyIndex(); + instr.storeInteger.propertyIndex = prop->index; instr.storeInteger.value = int(v->value.asNumber()); } break; case QMetaType::Float: { instr.setType(QDeclarativeInstruction::StoreFloat); - instr.storeFloat.propertyIndex = prop.propertyIndex(); + instr.storeFloat.propertyIndex = prop->index; instr.storeFloat.value = float(v->value.asNumber()); } break; case QVariant::Double: { instr.setType(QDeclarativeInstruction::StoreDouble); - instr.storeDouble.propertyIndex = prop.propertyIndex(); + instr.storeDouble.propertyIndex = prop->index; instr.storeDouble.value = v->value.asNumber(); } break; @@ -451,7 +458,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, { QColor c = QDeclarativeStringConverters::colorFromString(v->value.asString()); instr.setType(QDeclarativeInstruction::StoreColor); - instr.storeColor.propertyIndex = prop.propertyIndex(); + instr.storeColor.propertyIndex = prop->index; instr.storeColor.value = c.rgba(); } break; @@ -460,7 +467,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, { QDate d = QDeclarativeStringConverters::dateFromString(v->value.asString()); instr.setType(QDeclarativeInstruction::StoreDate); - instr.storeDate.propertyIndex = prop.propertyIndex(); + instr.storeDate.propertyIndex = prop->index; instr.storeDate.value = d.toJulianDay(); } break; @@ -468,9 +475,9 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, { QTime time = QDeclarativeStringConverters::timeFromString(v->value.asString()); instr.setType(QDeclarativeInstruction::StoreTime); - instr.storeTime.propertyIndex = prop.propertyIndex(); + instr.storeTime.propertyIndex = prop->index; Q_ASSERT(sizeof(instr.storeTime.time) == sizeof(QTime)); - ::memcpy(&instr.storeTime.time, &time, sizeof(QTime)); + ::memcpy(&instr.storeTime.time, &time, sizeof(QTime)); } } break; case QVariant::DateTime: @@ -478,7 +485,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, QDateTime dateTime = QDeclarativeStringConverters::dateTimeFromString(v->value.asString()); QTime time = dateTime.time(); instr.setType(QDeclarativeInstruction::StoreDateTime); - instr.storeDateTime.propertyIndex = prop.propertyIndex(); + instr.storeDateTime.propertyIndex = prop->index; instr.storeDateTime.date = dateTime.date().toJulianDay(); Q_ASSERT(sizeof(instr.storeDateTime.time) == sizeof(QTime)); ::memcpy(&instr.storeDateTime.time, &time, sizeof(QTime)); @@ -490,7 +497,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, bool ok; QPoint point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok).toPoint(); instr.setType(QDeclarativeInstruction::StorePoint); - instr.storePoint.propertyIndex = prop.propertyIndex(); + instr.storePoint.propertyIndex = prop->index; instr.storePoint.point.xp = point.x(); instr.storePoint.point.yp = point.y(); } @@ -500,7 +507,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, bool ok; QPointF point = QDeclarativeStringConverters::pointFFromString(v->value.asString(), &ok); instr.setType(QDeclarativeInstruction::StorePointF); - instr.storePointF.propertyIndex = prop.propertyIndex(); + instr.storePointF.propertyIndex = prop->index; instr.storePointF.point.xp = point.x(); instr.storePointF.point.yp = point.y(); } @@ -510,7 +517,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, bool ok; QSize size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok).toSize(); instr.setType(QDeclarativeInstruction::StoreSize); - instr.storeSize.propertyIndex = prop.propertyIndex(); + instr.storeSize.propertyIndex = prop->index; instr.storeSize.size.wd = size.width(); instr.storeSize.size.ht = size.height(); } @@ -520,7 +527,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, bool ok; QSizeF size = QDeclarativeStringConverters::sizeFFromString(v->value.asString(), &ok); instr.setType(QDeclarativeInstruction::StoreSizeF); - instr.storeSizeF.propertyIndex = prop.propertyIndex(); + instr.storeSizeF.propertyIndex = prop->index; instr.storeSizeF.size.wd = size.width(); instr.storeSizeF.size.ht = size.height(); } @@ -530,7 +537,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, bool ok; QRect rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok).toRect(); instr.setType(QDeclarativeInstruction::StoreRect); - instr.storeRect.propertyIndex = prop.propertyIndex(); + instr.storeRect.propertyIndex = prop->index; instr.storeRect.rect.x1 = rect.left(); instr.storeRect.rect.y1 = rect.top(); instr.storeRect.rect.x2 = rect.right(); @@ -542,7 +549,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, bool ok; QRectF rect = QDeclarativeStringConverters::rectFFromString(v->value.asString(), &ok); instr.setType(QDeclarativeInstruction::StoreRectF); - instr.storeRectF.propertyIndex = prop.propertyIndex(); + instr.storeRectF.propertyIndex = prop->index; instr.storeRectF.rect.xp = rect.left(); instr.storeRectF.rect.yp = rect.top(); instr.storeRectF.rect.w = rect.width(); @@ -553,7 +560,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, { bool b = v->value.asBoolean(); instr.setType(QDeclarativeInstruction::StoreBool); - instr.storeBool.propertyIndex = prop.propertyIndex(); + instr.storeBool.propertyIndex = prop->index; instr.storeBool.value = b; } break; @@ -562,7 +569,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, bool ok; QVector3D vector = QDeclarativeStringConverters::vector3DFromString(v->value.asString(), &ok); instr.setType(QDeclarativeInstruction::StoreVector3D); - instr.storeVector3D.propertyIndex = prop.propertyIndex(); + instr.storeVector3D.propertyIndex = prop->index; instr.storeVector3D.vector.xp = vector.x(); instr.storeVector3D.vector.yp = vector.y(); instr.storeVector3D.vector.zp = vector.z(); @@ -582,11 +589,10 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, break; default: { - int t = prop.userType(); instr.setType(QDeclarativeInstruction::AssignCustomType); - instr.assignCustomType.propertyIndex = prop.propertyIndex(); + instr.assignCustomType.propertyIndex = prop->index; instr.assignCustomType.primitive = output->indexForString(v->value.asString()); - instr.assignCustomType.type = t; + instr.assignCustomType.type = type; } break; } @@ -601,7 +607,7 @@ void QDeclarativeCompiler::reset(QDeclarativeCompiledData *data) data->types.clear(); data->primitives.clear(); data->datas.clear(); - data->bytecode.clear(); + data->bytecode.resize(0); } /*! @@ -769,6 +775,15 @@ void QDeclarativeCompiler::compileTree(QDeclarativeParser::Object *tree) enginePrivate->registerCompositeType(output); } +static bool QStringList_contains(const QStringList &list, const QStringRef &string) +{ + for (int ii = 0; ii < list.count(); ++ii) + if (list.at(ii) == string) + return true; + + return false; +} + bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const BindingContext &ctxt) { if (componentStats) @@ -913,7 +928,7 @@ bool QDeclarativeCompiler::buildObject(QDeclarativeParser::Object *obj, const Bi canDefer = ids == compileState->ids.count(); } - if (canDefer && !deferredList.isEmpty() && deferredList.contains(prop->name())) + if (canDefer && !deferredList.isEmpty() && QStringList_contains(deferredList, prop->name())) prop->isDeferred = true; } @@ -1042,7 +1057,8 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) ss.storeScriptString.propertyIndex = prop->index; ss.storeScriptString.value = output->indexForString(script); ss.storeScriptString.scope = prop->scriptStringScope; - ss.storeScriptString.bindingId = rewriteBinding(script, prop->name()); +// ss.storeScriptString.bindingId = rewriteBinding(script, prop->name()); + ss.storeScriptString.bindingId = rewriteBinding(script, QString()); // XXX ss.storeScriptString.line = prop->location.start.line; output->addInstruction(ss); } @@ -1095,20 +1111,17 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) QDeclarativeInstruction assign; assign.setType(QDeclarativeInstruction::AssignSignalObject); assign.assignSignalObject.line = v->location.start.line; - assign.assignSignalObject.signal = - output->indexForString(prop->name()); + assign.assignSignalObject.signal = output->indexForString(prop->name().toString()); output->addInstruction(assign); } else if (v->type == Value::SignalExpression) { - BindingContext ctxt = compileState->signalExpressions.value(v); - QDeclarativeInstruction store; store.setType(QDeclarativeInstruction::StoreSignal); store.storeSignal.signalIndex = prop->index; store.storeSignal.value = output->indexForString(v->value.asScript().trimmed()); - store.storeSignal.context = ctxt.stack; + store.storeSignal.context = v->signalExpressionContextStack; store.storeSignal.name = output->indexForByteArray(prop->name().toUtf8()); store.storeSignal.line = v->location.start.line; output->addInstruction(store); @@ -1292,7 +1305,7 @@ bool QDeclarativeCompiler::buildComponent(QDeclarativeParser::Object *obj, QString idVal = idProp->values.first()->primitive(); - if (compileState->ids.contains(idVal)) + if (compileState->ids.value(idVal)) COMPILE_EXCEPTION(idProp, tr("id is not unique")); obj->id = idVal; @@ -1398,9 +1411,9 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl { Q_ASSERT(obj->metaObject()); - QString name = prop->name(); - Q_ASSERT(name.startsWith(on_string)); - name = name.mid(2); + QStringRef propName = prop->name(); + Q_ASSERT(propName.startsWith(on_string)); + QString name = propName.string()->mid(propName.position() + 2, propName.length() - 2); // Note that the property name could start with any alpha or '_' or '$' character, // so we need to do the lower-casing of the first alpha character. @@ -1412,18 +1425,19 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl } bool notInRevision = false; - int sigIdx = indexOfSignal(obj, name, ¬InRevision); - if (sigIdx == -1) { + QDeclarativePropertyCache::Data *sig = signal(obj, QStringRef(&name), ¬InRevision); + + if (sig == 0) { - if (notInRevision && -1 == indexOfProperty(obj, prop->name(), 0)) { + if (notInRevision && 0 == property(obj, propName, 0)) { Q_ASSERT(obj->type != -1); const QList &resolvedTypes = unit->resolvedTypes(); const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type); if (type.type) { - COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion)); + COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name().toString()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion)); } else { - COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name())); + COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name().toString())); } } @@ -1436,7 +1450,9 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl if (prop->value || !prop->values.isOne()) COMPILE_EXCEPTION(prop, tr("Incorrectly specified signal assignment")); - prop->index = sigIdx; + prop->index = sig->coreIndex; + prop->core = *sig; + obj->addSignalProperty(prop); if (prop->values.first()->object) { @@ -1452,7 +1468,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl if (script.isEmpty()) COMPILE_EXCEPTION(prop, tr("Empty signal assignment")); - compileState->signalExpressions.insert(prop->values.first(), ctxt); + prop->values.first()->signalExpressionContextStack = ctxt.stack; } } @@ -1469,18 +1485,13 @@ bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop, if(isAttachedPropertyName(prop->name()) || prop->name() == id_string) return true; - const QMetaObject *mo = obj->metaObject(); - if (mo) { - if (prop->isDefault) { - QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo); - return p.name() != 0; - } else { - int idx = indexOfProperty(obj, prop->name()); - return idx != -1 && mo->property(idx).isScriptable(); - } + if (prop->isDefault) { + const QMetaObject *mo = obj->metaObject(); + QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo); + return p.name() != 0; + } else { + return property(obj, prop->name()) != 0; } - - return false; } bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, @@ -1523,44 +1534,40 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, prop->value->metatype = type->attachedPropertiesType(); } else { // Setup regular property data - QMetaProperty p; if (prop->isDefault) { - p = QDeclarativeMetaType::defaultProperty(metaObject); + QMetaProperty p = QDeclarativeMetaType::defaultProperty(metaObject); if (p.name()) { - prop->index = p.propertyIndex(); prop->setName(QString::fromLatin1(p.name())); + + QDeclarativePropertyCache::Data *d = property(obj, p.propertyIndex()); + prop->index = d->coreIndex; + prop->core = *d; } } else { bool notInRevision = false; - prop->index = indexOfProperty(obj, prop->name(), ¬InRevision); - if (prop->index == -1 && notInRevision) { + QDeclarativePropertyCache::Data *d = property(obj, prop->name(), ¬InRevision); + + if (d == 0 && notInRevision) { const QList &resolvedTypes = unit->resolvedTypes(); const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type); if (type.type) { - COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion)); + COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name().toString()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion)); } else { - COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name())); - } - } - - if (prop->index != -1) { - p = metaObject->property(prop->index); - Q_ASSERT(p.name()); - - if (!p.isScriptable()) { - prop->index = -1; - p = QMetaProperty(); + COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name().toString())); } + } else if (d) { + prop->index = d->coreIndex; + prop->core = *d; } } // We can't error here as the "id" property does not require a // successful index resolution - if (p.name()) - prop->type = p.userType(); + if (prop->index != -1) + prop->type = prop->core.propType; // Check if this is an alias if (prop->index != -1 && @@ -1596,7 +1603,7 @@ bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop, if (prop->isDefault) { COMPILE_EXCEPTION(prop->values.first(), tr("Cannot assign to non-existent default property")); } else { - COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name())); + COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name().toString())); } } else if (prop->value) { @@ -1727,7 +1734,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p store.storeObject.propertyIndex = prop->index; output->addInstruction(store); - } else if (prop->type == -1) { + } else if (prop->type == QMetaType::QVariant) { QDeclarativeInstruction store; store.setType(QDeclarativeInstruction::StoreVariantObject); @@ -1750,8 +1757,7 @@ void QDeclarativeCompiler::genPropertyAssignment(QDeclarativeParser::Property *p } else if (v->type == Value::Literal) { - QMetaProperty mp = obj->metaObject()->property(prop->index); - genLiteralAssignment(mp, v); + genLiteralAssignment(prop, v); } @@ -1811,7 +1817,7 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop, COMPILE_CHECK(checkValidId(idValue, val)); - if (compileState->ids.contains(val)) + if (compileState->ids.value(val)) COMPILE_EXCEPTION(prop, tr("id is not unique")); prop->values.first()->type = Value::Id; @@ -1824,10 +1830,10 @@ bool QDeclarativeCompiler::buildIdProperty(QDeclarativeParser::Property *prop, void QDeclarativeCompiler::addId(const QString &id, QDeclarativeParser::Object *obj) { - Q_ASSERT(!compileState->ids.contains(id)); + Q_ASSERT(!compileState->ids.value(id)); Q_ASSERT(obj->id == id); obj->idIndex = compileState->ids.count(); - compileState->ids.insert(id, obj); + compileState->ids.append(obj); } void QDeclarativeCompiler::addBindingReference(BindingReference *ref) @@ -1889,7 +1895,7 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr Q_ASSERT(prop->index != -1); if (QDeclarativeValueTypeFactory::isValueType(prop->type)) { - if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) { + if (prop->type >= 0 && enginePrivate->valueTypes[prop->type]) { if (!prop->values.isEmpty()) { if (prop->values.first()->location < prop->value->location) { @@ -1900,7 +1906,7 @@ bool QDeclarativeCompiler::buildGroupedProperty(QDeclarativeParser::Property *pr } if (!obj->metaObject()->property(prop->index).isWritable()) { - COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(prop->name())); + COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString())); } @@ -1944,14 +1950,14 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type, obj->metatype = type->metaObject(); for (Property *prop = obj->properties.first(); prop; prop = obj->properties.next(prop)) { - int idx = type->metaObject()->indexOfProperty(prop->name().toUtf8().constData()); - if (idx == -1) - COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name())); - QMetaProperty p = type->metaObject()->property(idx); - if (!p.isScriptable()) - COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name())); - prop->index = idx; - prop->type = p.userType(); + + QDeclarativePropertyCache::Data *d = property(obj, prop->name()); + if (d == 0) + COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(prop->name().toString())); + + prop->index = d->coreIndex; + prop->type = d->propType; + prop->core = *d; prop->isValueTypeSubProperty = true; if (prop->value) @@ -1969,7 +1975,11 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type, //optimization for . enum assignments bool isEnumAssignment = false; - COMPILE_CHECK(testQualifiedEnumAssignment(p, obj, value, &isEnumAssignment)); + + if (prop->core.isEnum()) + COMPILE_CHECK(testQualifiedEnumAssignment(obj->metatype->property(prop->index), obj, + value, &isEnumAssignment)); + if (isEnumAssignment) { value->type = Value::Literal; } else { @@ -1983,7 +1993,7 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type, value->type = Value::PropertyBinding; } } else { - COMPILE_CHECK(testLiteralAssignment(p, value)); + COMPILE_CHECK(testLiteralAssignment(prop, value)); value->type = Value::Literal; } } @@ -2102,7 +2112,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro Q_ASSERT(v->object->type != -1); if (!obj->metaObject()->property(prop->index).isWritable()) - COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name())); + COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString())); if (QDeclarativeMetaType::isInterface(prop->type)) { @@ -2111,7 +2121,7 @@ bool QDeclarativeCompiler::buildPropertyObjectAssignment(QDeclarativeParser::Pro v->type = Value::CreatedObject; - } else if (prop->type == -1) { + } else if (prop->type == QMetaType::QVariant) { // Assigning an object to a QVariant COMPILE_CHECK(buildObject(v->object, ctxt)); @@ -2183,7 +2193,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert Q_ASSERT(v->object->type != -1); if (!obj->metaObject()->property(prop->index).isWritable()) - COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name())); + COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString())); // Normally buildObject() will set this up, but we need the static @@ -2210,7 +2220,7 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert buildDynamicMeta(baseObj, ForceCreation); v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor; } else { - COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(prop->name())); + COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(prop->name().toString())); } return true; @@ -2218,20 +2228,23 @@ bool QDeclarativeCompiler::buildPropertyOnAssignment(QDeclarativeParser::Propert // Compile assigning a literal or binding to a regular property bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop, - QDeclarativeParser::Object *obj, - QDeclarativeParser::Value *v, - const BindingContext &ctxt) + QDeclarativeParser::Object *obj, + QDeclarativeParser::Value *v, + const BindingContext &ctxt) { Q_ASSERT(prop->index != -1); if (v->value.isScript()) { //optimization for . enum assignments - bool isEnumAssignment = false; - COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj, v, &isEnumAssignment)); - if (isEnumAssignment) { - v->type = Value::Literal; - return true; + if (prop->core.isEnum()) { + bool isEnumAssignment = false; + COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj, + v, &isEnumAssignment)); + if (isEnumAssignment) { + v->type = Value::Literal; + return true; + } } COMPILE_CHECK(buildBinding(v, prop, ctxt)); @@ -2240,7 +2253,7 @@ bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Pr } else { - COMPILE_CHECK(testLiteralAssignment(obj->metaObject()->property(prop->index), v)); + COMPILE_CHECK(testLiteralAssignment(prop, v)); v->type = Value::Literal; } @@ -2249,9 +2262,9 @@ bool QDeclarativeCompiler::buildPropertyLiteralAssignment(QDeclarativeParser::Pr } bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop, - QDeclarativeParser::Object *obj, - QDeclarativeParser::Value *v, - bool *isAssignment) + QDeclarativeParser::Object *obj, + QDeclarativeParser::Value *v, + bool *isAssignment) { *isAssignment = false; if (!prop.isEnumType()) @@ -2510,12 +2523,12 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn { QByteArray customTypeName; QDeclarativeType *qmltype = 0; - QUrl url; + QString url; if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0)) COMPILE_EXCEPTION(&p, tr("Invalid property type")); if (!qmltype) { - QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(url); + QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(QUrl(url)); Q_ASSERT(tdata); Q_ASSERT(tdata->isComplete()); @@ -2665,8 +2678,8 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn obj->metadata = builder.toRelocatableData(); builder.fromRelocatableData(&obj->extObject, obj->metatype, obj->metadata); - if (mode == IgnoreAliases && hasAlias) - compileState->aliasingObjects << obj; + if (mode == IgnoreAliases && hasAlias) + compileState->aliasingObjects.append(obj); obj->synthdata = dynamicData; @@ -2717,7 +2730,7 @@ static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node) { if (node->kind == QDeclarativeJS::AST::Node::Kind_IdentifierExpression) { QString name = - static_cast(node)->name->asString(); + static_cast(node)->name.toString(); return QStringList() << name; } else if (node->kind == QDeclarativeJS::AST::Node::Kind_FieldMemberExpression) { QDeclarativeJS::AST::FieldMemberExpression *expr = static_cast(node); @@ -2725,7 +2738,7 @@ static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node) QStringList rv = astNodeToStringList(expr->base); if (rv.isEmpty()) return rv; - rv.append(expr->name->asString()); + rv.append(expr->name.toString()); return rv; } return QStringList(); @@ -2753,11 +2766,10 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder, if (alias.count() < 1 || alias.count() > 3) COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as , . or ..")); - if (!compileState->ids.contains(alias.at(0))) + QDeclarativeParser::Object *idObject = compileState->ids.value(alias.at(0)); + if (!idObject) COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0))); - QDeclarativeParser::Object *idObject = compileState->ids[alias.at(0)]; - QByteArray typeName; int propIdx = -1; @@ -2765,7 +2777,7 @@ bool QDeclarativeCompiler::compileAlias(QMetaObjectBuilder &builder, bool writable = false; bool resettable = false; if (alias.count() == 2 || alias.count() == 3) { - propIdx = indexOfProperty(idObject, alias.at(1).toUtf8()); + propIdx = indexOfProperty(idObject, alias.at(1)); if (-1 == propIdx) { COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location")); @@ -2837,7 +2849,7 @@ bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value, QMetaProperty mp = prop->parent->metaObject()->property(prop->index); if (!mp.isWritable() && !QDeclarativeMetaType::isList(prop->type)) - COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name())); + COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString())); BindingReference *reference = pool->New(); reference->expression = value->value; @@ -2917,11 +2929,9 @@ int QDeclarativeCompiler::genContextCache() return -1; QDeclarativeIntegerCache *cache = new QDeclarativeIntegerCache(); - - for (QHash::ConstIterator iter = compileState->ids.begin(); - iter != compileState->ids.end(); - ++iter) - cache->add(iter.key(), (*iter)->idIndex); + cache->reserve(compileState->ids.count()); + for (Object *o = compileState->ids.first(); o; o = compileState->ids.next(o)) + cache->add(o->id, o->idIndex); output->contextCaches.append(cache); return output->contextCaches.count() - 1; @@ -2951,16 +2961,14 @@ bool QDeclarativeCompiler::completeComponentBuild() if (componentStats) componentStats->componentStat.ids = compileState->ids.count(); - for (int ii = 0; ii < compileState->aliasingObjects.count(); ++ii) { - QDeclarativeParser::Object *aliasObject = compileState->aliasingObjects.at(ii); + for (Object *aliasObject = compileState->aliasingObjects.first(); aliasObject; + aliasObject = compileState->aliasingObjects.next(aliasObject)) COMPILE_CHECK(buildDynamicMeta(aliasObject, ResolveAliases)); - } - QDeclarativeV4Compiler::Expression expr; + QDeclarativeV4Compiler::Expression expr(unit->imports()); expr.component = compileState->root; - expr.ids = compileState->ids; + expr.ids = &compileState->ids; expr.importCache = output->importCache; - expr.imports = unit->imports(); QDeclarativeV4Compiler bindingCompiler; @@ -3158,48 +3166,52 @@ QStringList QDeclarativeCompiler::deferredProperties(QDeclarativeParser::Object return rv; } -// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName -int QDeclarativeCompiler::indexOfSignal(QDeclarativeParser::Object *object, const QString &name, - bool *notInRevision) +QDeclarativePropertyCache::Data * +QDeclarativeCompiler::property(QDeclarativeParser::Object *object, int index) { - if (notInRevision) *notInRevision = false; + QDeclarativePropertyCache *cache = 0; - if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) { - QDeclarativePropertyCache *cache = - object->synthCache?object->synthCache:output->types.at(object->type).propertyCache(); + if (object->synthCache) + cache = object->synthCache; + else if (object->type != -1) + cache = output->types[object->type].createPropertyCache(engine); + else + cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject()); - QDeclarativePropertyCache::Data *d = cache->property(name); - if (notInRevision) *notInRevision = false; + return cache->property(index); +} - while (d && !(d->isFunction())) - d = cache->overrideData(d); +QDeclarativePropertyCache::Data * +QDeclarativeCompiler::property(QDeclarativeParser::Object *object, const QStringRef &name, bool *notInRevision) +{ + if (notInRevision) *notInRevision = false; - if (d && !cache->isAllowedInRevision(d)) { - if (notInRevision) *notInRevision = true; - return -1; - } else if (d) { - return d->coreIndex; - } + QDeclarativePropertyCache *cache = 0; + + if (object->synthCache) + cache = object->synthCache; + else if (object->type != -1) + cache = output->types[object->type].createPropertyCache(engine); + else + cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject()); - if (name.endsWith(Changed_string)) { - QString propName = name.mid(0, name.length() - 7); + QDeclarativePropertyCache::Data *d = cache->property(QHashedStringRef(name.constData(), name.length())); - int propIndex = indexOfProperty(object, propName, notInRevision); - if (propIndex != -1) { - d = cache->property(propIndex); - return d->notifyIndex; - } - } + // Find the first property + while (d && d->isFunction()) + d = cache->overrideData(d); - return -1; + if (d && !cache->isAllowedInRevision(d)) { + if (notInRevision) *notInRevision = true; + return 0; } else { - return QDeclarativePropertyPrivate::findSignalByName(object->metaObject(), name.toUtf8()).methodIndex(); + return d; } - } -int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, const QString &name, - bool *notInRevision) +// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName +QDeclarativePropertyCache::Data * +QDeclarativeCompiler::signal(QDeclarativeParser::Object *object, const QStringRef &name, bool *notInRevision) { if (notInRevision) *notInRevision = false; @@ -3212,17 +3224,50 @@ int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, co else cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject()); - QDeclarativePropertyCache::Data *d = cache->property(name); - // Find the first property - while (d && d->isFunction()) + + QDeclarativePropertyCache::Data *d = cache->property(QHashedStringRef(name.constData(), name.length())); + if (notInRevision) *notInRevision = false; + + while (d && !(d->isFunction())) d = cache->overrideData(d); if (d && !cache->isAllowedInRevision(d)) { if (notInRevision) *notInRevision = true; - return -1; - } else { - return d?d->coreIndex:-1; + return 0; + } else if (d) { + return d; + } + + if (name.endsWith(Changed_string)) { + QStringRef propName(name.string(), name.position(), name.length() - Changed_string.length()); + + d = property(object, propName, notInRevision); + if (d) + return cache->method(d->notifyIndex); } + + return 0; +} + +// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName +int QDeclarativeCompiler::indexOfSignal(QDeclarativeParser::Object *object, const QString &name, + bool *notInRevision) +{ + QDeclarativePropertyCache::Data *d = signal(object, QStringRef(&name), notInRevision); + return d?d->coreIndex:-1; +} + +int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, const QString &name, + bool *notInRevision) +{ + return indexOfProperty(object, QStringRef(&name), notInRevision); +} + +int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, const QStringRef &name, + bool *notInRevision) +{ + QDeclarativePropertyCache::Data *d = property(object, name, notInRevision); + return d?d->coreIndex:-1; } QT_END_NAMESPACE