aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-03-30 09:09:51 +1000
committerQt by Nokia <qt-info@nokia.com>2012-04-16 01:26:12 +0200
commit82a3fef9104ef449ecae56a2b228f4e820d928fa (patch)
tree4c87df2570d47f652589f8e2d787ae67a861772b
parentf189b8934dc405cbd45258abc5aba2713428b1cc (diff)
Add support for variant properties in V4
Support initialization of variant properties in V4. Variants can be set to contain basic types in V4, but we can't extract data from them since they may contain data types that V4 does not comprehend. Task-number: QTBUG-25022 Change-Id: I1935d77b50c5a3481c4c8ddd86b9d3d970571217 Reviewed-by: Michael Brasser <michael.brasser@nokia.com> Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp128
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp21
-rw-r--r--src/qml/qml/v4/qv4instruction.cpp24
-rw-r--r--src/qml/qml/v4/qv4instruction_p.h8
-rw-r--r--src/qml/qml/v4/qv4ir.cpp2
-rw-r--r--src/qml/qml/v4/qv4ir_p.h2
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp12
-rw-r--r--tests/auto/qml/v4/data/variantHandling.qml67
-rw-r--r--tests/auto/qml/v4/tst_v4.cpp9
9 files changed, 269 insertions, 4 deletions
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index e5d98e63fa..db015b07d6 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -456,7 +456,7 @@ static void testBindingResult(const QString &binding, int line, int column,
if (expression.hasError()) {
iserror = true;
qtscriptResult = "exception";
- } else if (value.userType() != resultType) {
+ } else if ((value.userType() != resultType) && (resultType != QMetaType::QVariant)) {
// Override the QMetaType conversions to make them more JS friendly.
if (value.userType() == QMetaType::Double && (resultType == QMetaType::QString ||
resultType == QMetaType::QUrl)) {
@@ -506,6 +506,12 @@ static void testBindingResult(const QString &binding, int line, int column,
case QMetaType::Double:
v4value = result.getnumber();
break;
+ case QMetaType::QColor:
+ v4value = *result.getcolorptr();
+ break;
+ case QMetaType::QVariant:
+ v4value = *result.getvariantptr();
+ break;
default:
if (resultType == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
v4value = QVariant(QQmlMetaType::QQuickAnchorLineMetaTypeId(), result.typeDataPtr());
@@ -882,6 +888,19 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertBoolToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertBoolToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getvariantptr()) QVariant(src.getbool());
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertBoolToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertIntToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -906,13 +925,26 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
Register &output = registers[instr->unaryop.output];
if (src.isUndefined()) {
output.setUndefined();
- } else {
+ } else {
new (output.getstringptr()) QString(QString::number(src.getint()));
STRING_REGISTER(instr->unaryop.output);
}
}
QML_V4_END_INSTR(ConvertIntToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertIntToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getvariantptr()) QVariant(src.getint());
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertIntToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertNumberToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -945,6 +977,19 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertNumberToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertNumberToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ new (output.getvariantptr()) QVariant(src.getnumber());
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertNumberToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertStringToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1048,6 +1093,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertStringToUrl, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertStringToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ const QString tmp(*src.getstringptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupString();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ new (output.getvariantptr()) QVariant(tmp);
+
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertStringToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1085,6 +1149,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertUrlToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertUrlToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ const QUrl tmp(*src.geturlptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupUrl();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ new (output.getvariantptr()) QVariant(tmp);
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertUrlToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertColorToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1119,6 +1202,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertColorToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertColorToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ const QColor tmp(*src.getcolorptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupColor();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ new (output.getvariantptr()) QVariant(tmp);
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertColorToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertObjectToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1131,6 +1233,20 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertObjectToBool, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertObjectToVariant, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined())
+ output.setUndefined();
+ else {
+ new (output.getvariantptr()) QVariant(qVariantFromValue<QObject *>(src.getQObject()));
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertObjectToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertNullToObject, unaryop)
{
Register &output = registers[instr->unaryop.output];
@@ -1138,6 +1254,14 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertNullToObject, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertNullToVariant, unaryop)
+ {
+ Register &output = registers[instr->unaryop.output];
+ new (output.getvariantptr()) QVariant();
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ QML_V4_END_INSTR(ConvertNullToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ResolveUrl, unaryop)
{
const Register &src = registers[instr->unaryop.src];
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 045a14fbb5..e03270cf1d 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -377,6 +377,9 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
case QMetaType::QColor:
regType = QColorType;
break;
+ case QMetaType::QVariant:
+ regType = QVariantType;
+ break;
default:
if (propTy == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
@@ -966,6 +969,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
switch (targetTy) {
case IR::BoolType:
case IR::StringType:
+ case IR::VariantType:
// nothing to do. V4 will generate optimized
// url-to-xxx conversions.
break;
@@ -1068,6 +1072,20 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::NullType: opcode = V4Instr::ConvertNullToObject; break;
default: break;
} // switch
+ } else if (targetTy == IR::VariantType) {
+ if (s->isMoveForReturn) {
+ switch (sourceTy) {
+ case IR::BoolType: opcode = V4Instr::ConvertBoolToVariant; break;
+ case IR::IntType: opcode = V4Instr::ConvertIntToVariant; break;
+ case IR::NumberType: opcode = V4Instr::ConvertNumberToVariant; break;
+ case IR::UrlType: opcode = V4Instr::ConvertUrlToVariant; break;
+ case IR::ColorType: opcode = V4Instr::ConvertColorToVariant; break;
+ case IR::StringType: opcode = V4Instr::ConvertStringToVariant; break;
+ case IR::ObjectType: opcode = V4Instr::ConvertObjectToVariant; break;
+ case IR::NullType: opcode = V4Instr::ConvertNullToVariant; break;
+ default: break;
+ } // switch
+ }
}
if (opcode != V4Instr::Noop) {
V4Instr conv;
@@ -1141,6 +1159,9 @@ void QV4CompilerPrivate::visitRet(IR::Ret *s)
case IR::ObjectType:
test.regType = QMetaType::QObjectStar;
break;
+ case IR::VariantType:
+ test.regType = QMetaType::QVariant;
+ break;
case IR::BoolType:
test.regType = QMetaType::Bool;
break;
diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp
index ecd4f01ef3..c20297975d 100644
--- a/src/qml/qml/v4/qv4instruction.cpp
+++ b/src/qml/qml/v4/qv4instruction.cpp
@@ -144,6 +144,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertBoolToString:
INSTR_DUMP << "\t" << "ConvertBoolToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertBoolToVariant:
+ INSTR_DUMP << "\t" << "ConvertBoolToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertIntToBool:
INSTR_DUMP << "\t" << "ConvertIntToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -153,6 +156,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertIntToString:
INSTR_DUMP << "\t" << "ConvertIntToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertIntToVariant:
+ INSTR_DUMP << "\t" << "ConvertIntToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertNumberToBool:
INSTR_DUMP << "\t" << "ConvertNumberToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -162,6 +168,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertNumberToString:
INSTR_DUMP << "\t" << "ConvertNumberToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertNumberToVariant:
+ INSTR_DUMP << "\t" << "ConvertNumberToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertStringToBool:
INSTR_DUMP << "\t" << "ConvertStringToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -177,24 +186,39 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertStringToColor:
INSTR_DUMP << "\t" << "ConvertStringToColor" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertStringToVariant:
+ INSTR_DUMP << "\t" << "ConvertStringToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertUrlToBool:
INSTR_DUMP << "\t" << "ConvertUrlToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertUrlToString:
INSTR_DUMP << "\t" << "ConvertUrlToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertUrlToVariant:
+ INSTR_DUMP << "\t" << "ConvertUrlToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertColorToBool:
INSTR_DUMP << "\t" << "ConvertColorToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertColorToString:
INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertColorToVariant:
+ INSTR_DUMP << "\t" << "ConvertColorToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertObjectToBool:
INSTR_DUMP << "\t" << "ConvertObjectToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertObjectToVariant:
+ INSTR_DUMP << "\t" << "ConvertObjectToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertNullToObject:
INSTR_DUMP << "\t" << "ConvertNullToObject" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertNullToVariant:
+ INSTR_DUMP << "\t" << "ConvertNullToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ResolveUrl:
INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h
index 310bfbaff5..6eb9efa50f 100644
--- a/src/qml/qml/v4/qv4instruction_p.h
+++ b/src/qml/qml/v4/qv4instruction_p.h
@@ -83,23 +83,31 @@ QT_BEGIN_NAMESPACE
F(ConvertBoolToInt, unaryop) \
F(ConvertBoolToNumber, unaryop) \
F(ConvertBoolToString, unaryop) \
+ F(ConvertBoolToVariant, unaryop) \
F(ConvertIntToBool, unaryop) \
F(ConvertIntToNumber, unaryop) \
F(ConvertIntToString, unaryop) \
+ F(ConvertIntToVariant, unaryop) \
F(ConvertNumberToBool, unaryop) \
F(ConvertNumberToInt, unaryop) \
F(ConvertNumberToString, unaryop) \
+ F(ConvertNumberToVariant, unaryop) \
F(ConvertStringToBool, unaryop) \
F(ConvertStringToInt, unaryop) \
F(ConvertStringToNumber, unaryop) \
F(ConvertStringToUrl, unaryop) \
F(ConvertStringToColor, unaryop) \
+ F(ConvertStringToVariant, unaryop) \
F(ConvertUrlToBool, unaryop) \
F(ConvertUrlToString, unaryop) \
+ F(ConvertUrlToVariant, unaryop) \
F(ConvertColorToBool, unaryop) \
F(ConvertColorToString, unaryop) \
+ F(ConvertColorToVariant, unaryop) \
F(ConvertObjectToBool, unaryop) \
+ F(ConvertObjectToVariant, unaryop) \
F(ConvertNullToObject, unaryop) \
+ F(ConvertNullToVariant, unaryop) \
F(ResolveUrl, unaryop) \
F(MathSinNumber, unaryop) \
F(MathCosNumber, unaryop) \
diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp
index ba0faec80e..45e909f54b 100644
--- a/src/qml/qml/v4/qv4ir.cpp
+++ b/src/qml/qml/v4/qv4ir.cpp
@@ -63,6 +63,8 @@ const char *typeName(Type t)
case SGAnchorLineType: return "SGAnchorLine";
case AttachType: return "AttachType";
case ObjectType: return "object";
+ case VariantType: return "variant";
+ case VarType: return "var";
case BoolType: return "bool";
case IntType: return "int";
case FloatType: return "float";
diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h
index 26bd43c406..254b810403 100644
--- a/src/qml/qml/v4/qv4ir_p.h
+++ b/src/qml/qml/v4/qv4ir_p.h
@@ -146,6 +146,8 @@ enum Type {
SGAnchorLineType,
AttachType,
ObjectType,
+ VariantType,
+ VarType,
FirstNumberType,
BoolType = FirstNumberType,
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 31ed9a5a6a..82da09f485 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -116,8 +116,16 @@ bool QV4IRBuilder::operator()(QQmlJS::IR::Function *function,
//_block->MOVE(_block->TEMP(IR::InvalidType), r.code);
if (r.code) {
- const QMetaObject *m = 0;
- const IR::Type targetType = irTypeFromVariantType(m_expression->property->type, m_engine, m);
+ IR::Type targetType = IR::InvalidType;
+
+ // This is the only operation where variant is supported:
+ QQmlPropertyData *data = &m_expression->property->core;
+ if (data->propType == QMetaType::QVariant) {
+ targetType = (data->isVMEProperty() ? IR::VarType : IR::VariantType);
+ } else {
+ targetType = irTypeFromVariantType(data->propType, m_engine, 0);
+ }
+
if (targetType != r.type()) {
IR::Expr *x = _block->TEMP(targetType);
_block->MOVE(x, r, true);
diff --git a/tests/auto/qml/v4/data/variantHandling.qml b/tests/auto/qml/v4/data/variantHandling.qml
new file mode 100644
index 0000000000..3d48eef57e
--- /dev/null
+++ b/tests/auto/qml/v4/data/variantHandling.qml
@@ -0,0 +1,67 @@
+import QtQuick 2.0
+
+QtObject {
+ property bool pBool: true
+ property int pInt: 666
+ property real pReal: 3.1415927
+ property string pString: 'foo'
+ property url pUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2'
+ property color pColor: Qt.rgba(1, 0, 0, 0.5)
+ property QtObject pObject: QtObject { property string foo: 'bar' }
+
+ // Test assignment to variant
+ property variant pBoolVar: pBool
+ property variant pIntVar: pInt
+ property variant pRealVar: pReal
+ property variant pStringVar: pString
+ property variant pUrlVar: pUrl
+ property variant pColorVar: pColor
+ property variant pObjectVar: pObject
+ property variant pNullVar: null
+ property variant pVarVar: pUrlVar
+
+ // Test equivalence
+ property bool boolConversionSuccess: (pBoolVar == true)
+ property bool intConversionSuccess: (pIntVar == 666)
+ property bool realConversionSuccess: (pRealVar == 3.1415927)
+ property bool stringConversionSuccess: (pStringVar == 'foo')
+
+ property url comparisonUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2'
+ property bool urlConversionSuccess: (pUrlVar == comparisonUrl)
+
+ property color comparisonColor: Qt.rgba(1, 0, 0, 0.5)
+ property bool colorConversionSuccess: (pColorVar == comparisonColor)
+
+ property bool objectConversionSuccess: (pObjectVar == pObject)
+ property bool nullConversionSuccess: (pNullVar == null)
+
+ property bool variantConversionSuccess: (pVarVar == comparisonUrl)
+
+ // Operations are not handled by V4 - they should pass through correctly
+ property variant pVarNot: !pBoolVar
+ property variant pVarComplement: ~pIntVar
+ property variant pVarEqual: (pBoolVar == pBoolVar)
+ property variant pVarLiteralEqual: (pBoolVar == true)
+ property variant pVarUnequal: (pUrlVar == pColorVar)
+ property variant pVarComparison: (pIntVar <= pIntVar)
+ property variant pVarShift: (pIntVar >> 1)
+
+ Component.onCompleted: {
+ if (!boolConversionSuccess) console.warn('QV4: bool conversion failed');
+ if (!intConversionSuccess) console.warn('QV4: int conversion failed');
+ if (!realConversionSuccess) console.warn('QV4: real conversion failed');
+ if (!stringConversionSuccess) console.warn('QV4: string conversion failed');
+ if (!urlConversionSuccess) console.warn('QV4: url conversion failed');
+ if (!colorConversionSuccess) console.warn('QV4: color conversion failed');
+ if (!objectConversionSuccess) console.warn('QV4: object conversion failed');
+ if (!nullConversionSuccess) console.warn('QV4: null conversion failed');
+ if (!variantConversionSuccess) console.warn('QV4: variant conversion failed');
+ if (pVarNot != false) console.warn('QV4: variant negation impeded');
+ if (pVarComplement != ~666) console.warn('QV4: variant complement impeded');
+ if (pVarEqual != true) console.warn('QV4: variant equality impeded');
+ if (pVarLiteralEqual != true) console.warn('QV4: variant/literal equality impeded');
+ if (pVarUnequal != false) console.warn('QV4: variant unequality impeded');
+ if (pVarComparison != true) console.warn('QV4: variant comparison impeded');
+ if (pVarShift != 333) console.warn('QV4: variant shift impeded');
+ }
+}
diff --git a/tests/auto/qml/v4/tst_v4.cpp b/tests/auto/qml/v4/tst_v4.cpp
index dfb7cc48c7..99a4405afa 100644
--- a/tests/auto/qml/v4/tst_v4.cpp
+++ b/tests/auto/qml/v4/tst_v4.cpp
@@ -150,6 +150,7 @@ void tst_v4::qtscript_data()
QTest::newRow("conversion from string") << "conversions.6.qml"; // QTBUG-24706
QTest::newRow("conversion from url") << "conversions.7.qml"; // QTBUG-24706
QTest::newRow("conversion from vec3") << "conversions.8.qml";
+ QTest::newRow("variantHandling") << "variantHandling.qml";
}
void tst_v4::unnecessaryReeval()
@@ -856,23 +857,31 @@ void tst_v4::debuggingDumpInstructions()
expectedPreAddress << "\t\tConvertBoolToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertBoolToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertBoolToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertBoolToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertIntToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertNumberToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToUrl\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToColor\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertStringToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertUrlToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertUrlToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertUrlToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertColorToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertColorToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertColorToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertObjectToBool\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertObjectToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNullToObject\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertNullToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tResolveUrl\t\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tMathSinNumber\t\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tMathCosNumber\t\tInput_Reg(0) -> Output_Reg(0)";