summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/qmlcompiler.cpp182
-rw-r--r--src/declarative/qml/qmlcompiler_p.h13
2 files changed, 87 insertions, 108 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 89a1774..c5ffeda 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -194,45 +194,76 @@ bool QmlCompiler::isAttachedProperty(const QByteArray &name)
return !name.isEmpty() && name.at(0) >= 'A' && name.at(0) <= 'Z';
}
-QmlCompiler::StoreInstructionResult
-QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
- QmlInstruction &instr,
- const QMetaProperty &prop,
- int coreIdx, int primitive,
- const QString *string)
+#define COMPILE_EXCEPTION2(token, desc) \
+ { \
+ QString exceptionDescription; \
+ QmlError error; \
+ error.setUrl(output->url); \
+ error.setLine(token->location.start.line); \
+ error.setColumn(token->location.start.column); \
+ QDebug d(&exceptionDescription); \
+ d << desc; \
+ error.setDescription(exceptionDescription.trimmed()); \
+ exceptions << error; \
+ return false; \
+ }
+
+#define COMPILE_EXCEPTION(desc) \
+ { \
+ QString exceptionDescription; \
+ QmlError error; \
+ error.setUrl(output->url); \
+ error.setLine(obj->location.start.line); \
+ error.setColumn(obj->location.start.column); \
+ QDebug d(&exceptionDescription); \
+ d << desc; \
+ error.setDescription(exceptionDescription.trimmed()); \
+ exceptions << error; \
+ return false; \
+ }
+
+#define COMPILE_CHECK(a) \
+ { \
+ if (!a) return false; \
+ }
+
+bool QmlCompiler::generateStoreInstruction(QmlInstruction &instr,
+ const QMetaProperty &prop,
+ int coreIdx,
+ QmlParser::Value *v)
{
+ QString string = v->value.asScript();
+
if (!prop.isWritable())
- return ReadOnly;
+ COMPILE_EXCEPTION2(v, "Cannot assign literal value to read-only property" << prop.name());
+
if (prop.isEnumType()) {
int value;
if (prop.isFlagType()) {
- value = prop.enumerator().keysToValue(string->toLatin1().constData());
+ value = prop.enumerator().keysToValue(string.toLatin1().constData());
} else
- value = prop.enumerator().keyToValue(string->toLatin1().constData());
+ value = prop.enumerator().keyToValue(string.toLatin1().constData());
if (value == -1)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot assign unknown enumeration to property" << prop.name());
instr.type = QmlInstruction::StoreInteger;
instr.storeInteger.propertyIndex = coreIdx;
instr.storeInteger.value = value;
- return Ok;
+ return true;
}
int type = prop.type();
switch(type) {
case -1:
+ {
instr.type = QmlInstruction::StoreVariant;
instr.storeString.propertyIndex = coreIdx;
- if (primitive == -1)
- primitive = cdata.indexForString(*string);
- instr.storeString.value = primitive;
- break;
+ instr.storeString.value = output->indexForString(string);
+ }
break;
case QVariant::String:
{
instr.type = QmlInstruction::StoreString;
instr.storeString.propertyIndex = coreIdx;
- if (primitive == -1)
- primitive = cdata.indexForString(*string);
- instr.storeString.value = primitive;
+ instr.storeString.value = output->indexForString(string);
}
break;
case QVariant::UInt:
@@ -240,9 +271,9 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
instr.type = QmlInstruction::StoreInteger;
instr.storeInteger.propertyIndex = coreIdx;
bool ok;
- int value = string->toUInt(&ok);
+ int value = string.toUInt(&ok);
if (!ok)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to unsigned integer");
instr.storeInteger.value = value;
}
break;
@@ -251,9 +282,9 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
instr.type = QmlInstruction::StoreInteger;
instr.storeInteger.propertyIndex = coreIdx;
bool ok;
- int value = string->toInt(&ok);
+ int value = string.toInt(&ok);
if (!ok)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to integer");
instr.storeInteger.value = value;
}
break;
@@ -263,17 +294,17 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
instr.type = QmlInstruction::StoreReal;
instr.storeReal.propertyIndex = coreIdx;
bool ok;
- float value = string->toFloat(&ok);
+ float value = string.toFloat(&ok);
if (!ok)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to real number");
instr.storeReal.value = value;
}
break;
case QVariant::Color:
{
- QColor c = QmlStringConverters::colorFromString(*string);
+ QColor c = QmlStringConverters::colorFromString(string);
if (!c.isValid())
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to color");
instr.type = QmlInstruction::StoreColor;
instr.storeColor.propertyIndex = coreIdx;
instr.storeColor.value = c.rgba();
@@ -281,9 +312,9 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
break;
case QVariant::Date:
{
- QDate d = QDate::fromString(*string, Qt::ISODate);
+ QDate d = QDate::fromString(string, Qt::ISODate);
if (!d.isValid())
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to date");
instr.type = QmlInstruction::StoreDate;
instr.storeDate.propertyIndex = coreIdx;
instr.storeDate.value = d.toJulianDay();
@@ -291,11 +322,11 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
break;
case QVariant::Time:
{
- QTime time = QTime::fromString(*string, Qt::ISODate);
+ QTime time = QTime::fromString(string, Qt::ISODate);
if (!time.isValid())
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to time");
int data[] = { time.hour(), time.minute(), time.second(), time.msec() };
- int index = cdata.indexForInt(data, 4);
+ int index = output->indexForInt(data, 4);
instr.type = QmlInstruction::StoreTime;
instr.storeTime.propertyIndex = coreIdx;
instr.storeTime.valueIndex = index;
@@ -303,15 +334,15 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
break;
case QVariant::DateTime:
{
- QDateTime dateTime = QDateTime::fromString(*string, Qt::ISODate);
+ QDateTime dateTime = QDateTime::fromString(string, Qt::ISODate);
if (!dateTime.isValid())
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to date and time");
int data[] = { dateTime.date().toJulianDay(),
dateTime.time().hour(),
dateTime.time().minute(),
dateTime.time().second(),
dateTime.time().msec() };
- int index = cdata.indexForInt(data, 5);
+ int index = output->indexForInt(data, 5);
instr.type = QmlInstruction::StoreDateTime;
instr.storeDateTime.propertyIndex = coreIdx;
instr.storeDateTime.valueIndex = index;
@@ -321,11 +352,11 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
case QVariant::PointF:
{
bool ok;
- QPointF point = QmlStringConverters::pointFFromString(*string, &ok);
+ QPointF point = QmlStringConverters::pointFFromString(string, &ok);
if (!ok)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to point");
float data[] = { point.x(), point.y() };
- int index = cdata.indexForFloat(data, 2);
+ int index = output->indexForFloat(data, 2);
if (type == QVariant::PointF)
instr.type = QmlInstruction::StorePointF;
else
@@ -338,11 +369,11 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
case QVariant::SizeF:
{
bool ok;
- QSizeF size = QmlStringConverters::sizeFFromString(*string, &ok);
+ QSizeF size = QmlStringConverters::sizeFFromString(string, &ok);
if (!ok)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to size");
float data[] = { size.width(), size.height() };
- int index = cdata.indexForFloat(data, 2);
+ int index = output->indexForFloat(data, 2);
if (type == QVariant::SizeF)
instr.type = QmlInstruction::StoreSizeF;
else
@@ -355,12 +386,12 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
case QVariant::RectF:
{
bool ok;
- QRectF rect = QmlStringConverters::rectFFromString(*string, &ok);
+ QRectF rect = QmlStringConverters::rectFFromString(string, &ok);
if (!ok)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to rect");
float data[] = { rect.x(), rect.y(),
rect.width(), rect.height() };
- int index = cdata.indexForFloat(data, 4);
+ int index = output->indexForFloat(data, 4);
if (type == QVariant::RectF)
instr.type = QmlInstruction::StoreRectF;
else
@@ -372,9 +403,9 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
case QVariant::Bool:
{
bool ok;
- bool b = QmlStringConverters::boolFromString(*string, &ok);
+ bool b = QmlStringConverters::boolFromString(string, &ok);
if (!ok)
- return InvalidData;
+ COMPILE_EXCEPTION2(v, "Cannot convert value" << string << "to boolean");
instr.type = QmlInstruction::StoreBool;
instr.storeBool.propertyIndex = coreIdx;
instr.storeBool.value = b;
@@ -388,24 +419,22 @@ QmlCompiler::generateStoreInstruction(QmlCompiledData &cdata,
QmlMetaType::StringConverter converter =
QmlMetaType::customStringConverter(t);
if (converter) {
- int index = cdata.customTypeData.count();
+ int index = output->customTypeData.count();
instr.type = QmlInstruction::AssignCustomType;
instr.assignCustomType.propertyIndex = coreIdx;
instr.assignCustomType.valueIndex = index;
QmlCompiledData::CustomTypeData data;
- if (primitive == -1)
- primitive = cdata.indexForString(*string);
- data.index = primitive;
+ data.index = output->indexForString(string);
data.type = t;
- cdata.customTypeData << data;
+ output->customTypeData << data;
break;
}
}
- return UnknownType;
+ COMPILE_EXCEPTION2(v, "Cannot assign to property" << prop.name() << "of unknown type" << prop.type());
break;
}
- return Ok;
+ return true;
}
void QmlCompiler::reset(QmlCompiledComponent *cc, bool deleteMemory)
@@ -424,39 +453,6 @@ void QmlCompiler::reset(QmlCompiledComponent *cc, bool deleteMemory)
cc->bytecode.clear();
}
-#define COMPILE_EXCEPTION2(token, desc) \
- { \
- QString exceptionDescription; \
- QmlError error; \
- error.setUrl(output->url); \
- error.setLine(token->location.start.line); \
- error.setColumn(token->location.start.column); \
- QDebug d(&exceptionDescription); \
- d << desc; \
- error.setDescription(exceptionDescription.trimmed()); \
- exceptions << error; \
- return false; \
- }
-
-#define COMPILE_EXCEPTION(desc) \
- { \
- QString exceptionDescription; \
- QmlError error; \
- error.setUrl(output->url); \
- error.setLine(obj->location.start.line); \
- error.setColumn(obj->location.start.column); \
- QDebug d(&exceptionDescription); \
- d << desc; \
- error.setDescription(exceptionDescription.trimmed()); \
- exceptions << error; \
- return false; \
- }
-
-#define COMPILE_CHECK(a) \
- { \
- if (!a) return false; \
- }
-
bool QmlCompiler::compile(QmlEngine *engine,
QmlCompositeTypeData *unit,
QmlCompiledComponent *out)
@@ -1226,21 +1222,7 @@ bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
assign.line = v->location.start.line;
if (prop->index != -1) {
- QString value = v->primitive();
- StoreInstructionResult r =
- generateStoreInstruction(*output, assign, obj->metaObject()->property(prop->index), prop->index, -1, &value);
-
- if (r == Ok) {
- } else if (r == InvalidData) {
- //### we are restricted to a rather generic message here. If we can find a way to move
- // the exception into generateStoreInstruction we could potentially have better messages.
- // (the problem is that both compile and run exceptions can be generated, though)
- COMPILE_EXCEPTION2(v, "Cannot assign value" << v->primitive() << "to property" << obj->metaObject()->property(prop->index).name());
- } else if (r == ReadOnly) {
- COMPILE_EXCEPTION2(v, "Cannot assign value" << v->primitive() << "to the read-only property" << obj->metaObject()->property(prop->index).name());
- } else {
- COMPILE_EXCEPTION2(prop, "Cannot assign value to property" << obj->metaObject()->property(prop->index).name() << "of unknown type");
- }
+ COMPILE_CHECK(generateStoreInstruction(assign, obj->metaObject()->property(prop->index), prop->index, v));
} else {
COMPILE_EXCEPTION2(prop, "Cannot assign value to non-existant property" << prop->name);
}
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 3280866..27c4dd2 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -121,14 +121,6 @@ public:
static bool isValidId(const QString &);
static bool isAttachedProperty(const QByteArray &);
- enum StoreInstructionResult { Ok, UnknownType, InvalidData, ReadOnly };
- static StoreInstructionResult
- generateStoreInstruction(QmlCompiledData &data,
- QmlInstruction &instr,
- const QMetaProperty &prop,
- int index,
- int primitive,
- const QString *string);
private:
void reset(QmlCompiledComponent *, bool);
@@ -163,6 +155,11 @@ private:
QmlParser::Value *value,
int ctxt);
+ bool generateStoreInstruction(QmlInstruction &instr,
+ const QMetaProperty &prop,
+ int index,
+ QmlParser::Value *value);
+
bool compileDynamicMeta(QmlParser::Object *obj);
bool compileBinding(const QString &, QmlParser::Property *prop,
int ctxt, const QMetaObject *, qint64);