*/
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';
}
*/
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();
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"));
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;
}
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());
}
}
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;
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;
{
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;
{
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;
{
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:
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));
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();
}
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();
}
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();
}
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();
}
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();
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();
{
bool b = v->value.asBoolean();
instr.setType(QDeclarativeInstruction::StoreBool);
- instr.storeBool.propertyIndex = prop.propertyIndex();
+ instr.storeBool.propertyIndex = prop->index;
instr.storeBool.value = b;
}
break;
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();
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;
}
data->types.clear();
data->primitives.clear();
data->datas.clear();
- data->bytecode.clear();
+ data->bytecode.resize(0);
}
/*!
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)
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;
}
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);
}
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);
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;
{
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.
}
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<QDeclarativeTypeData::TypeReference> &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()));
}
}
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) {
if (script.isEmpty())
COMPILE_EXCEPTION(prop, tr("Empty signal assignment"));
- compileState->signalExpressions.insert(prop->values.first(), ctxt);
+ prop->values.first()->signalExpressionContextStack = ctxt.stack;
}
}
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,
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<QDeclarativeTypeData::TypeReference> &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 &&
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) {
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);
} else if (v->type == Value::Literal) {
- QMetaProperty mp = obj->metaObject()->property(prop->index);
- genLiteralAssignment(mp, v);
+ genLiteralAssignment(prop, v);
}
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;
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)
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) {
}
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()));
}
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)
//optimization for <Type>.<EnumValue> 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 {
value->type = Value::PropertyBinding;
}
} else {
- COMPILE_CHECK(testLiteralAssignment(p, value));
+ COMPILE_CHECK(testLiteralAssignment(prop, value));
value->type = Value::Literal;
}
}
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)) {
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));
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
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;
// 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 <Type>.<EnumValue> 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));
} else {
- COMPILE_CHECK(testLiteralAssignment(obj->metaObject()->property(prop->index), v));
+ COMPILE_CHECK(testLiteralAssignment(prop, v));
v->type = Value::Literal;
}
}
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())
{
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());
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;
{
if (node->kind == QDeclarativeJS::AST::Node::Kind_IdentifierExpression) {
QString name =
- static_cast<QDeclarativeJS::AST::IdentifierExpression *>(node)->name->asString();
+ static_cast<QDeclarativeJS::AST::IdentifierExpression *>(node)->name.toString();
return QStringList() << name;
} else if (node->kind == QDeclarativeJS::AST::Node::Kind_FieldMemberExpression) {
QDeclarativeJS::AST::FieldMemberExpression *expr = static_cast<QDeclarativeJS::AST::FieldMemberExpression *>(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();
if (alias.count() < 1 || alias.count() > 3)
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
- 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;
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"));
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<BindingReference>();
reference->expression = value->value;
return -1;
QDeclarativeIntegerCache *cache = new QDeclarativeIntegerCache();
-
- for (QHash<QString, QDeclarativeParser::Object *>::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;
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;
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;
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