#include <private/qdeclarativeprofilerservice_p.h>
#include <private/qdeclarativemetatype_p.h>
#include <private/qdeclarativetrace_p.h>
+#include <private/qdeclarativestringconverters_p.h>
#include <QtDeclarative/qdeclarativeinfo.h>
#include <QtCore/qnumeric.h>
QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
QString *getstringptr() { return (QString *)typeDataPtr(); }
QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
+ QColor *getcolorptr() { return (QColor *)typeDataPtr(); }
const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
const QString *getstringptr() const { return (QString *)typeDataPtr(); }
const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
+ const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); }
void *typeDataPtr() { return (void *)&data; }
void *typeMemory() { return (void *)data; }
inline void cleanup();
inline void cleanupString();
inline void cleanupUrl();
+ inline void cleanupColor();
inline void cleanupVariant();
inline void copy(const Register &other);
getstringptr()->~QString();
} else if (dataType == QUrlType) {
geturlptr()->~QUrl();
+ } else if (dataType == QColorType) {
+ getcolorptr()->~QColor();
} else if (dataType == QVariantType) {
getvariantptr()->~QVariant();
}
setUndefined();
}
+void Register::cleanupColor()
+{
+ getcolorptr()->~QColor();
+ setUndefined();
+}
+
void Register::cleanupVariant()
{
getvariantptr()->~QVariant();
new (getstringptr()) QString(*other.getstringptr());
else if (other.dataType == QUrlType)
new (geturlptr()) QUrl(*other.geturlptr());
+ else if (other.dataType == QColorType)
+ new (getcolorptr()) QColor(*other.getcolorptr());
else if (other.dataType == QVariantType)
new (getvariantptr()) QVariant(*other.getvariantptr());
}
new (getstringptr()) QString();
else if (dataType == QUrlType)
new (geturlptr()) QUrl();
+ else if (dataType == QColorType)
+ new (getcolorptr()) QColor();
else if (dataType == QVariantType)
new (getvariantptr()) QVariant();
}
MARK_REGISTER(reg); \
}
+#define COLOR_REGISTER(reg) { \
+ registers[(reg)].settype(QColorType); \
+ MARK_REGISTER(reg); \
+}
+
#define VARIANT_REGISTER(reg) { \
registers[(reg)].settype(QVariantType); \
MARK_REGISTER(reg); \
}
QML_V4_END_INSTR(ConvertStringToUrl, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertStringToColor, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ 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);
+ }
+ QColor *colorPtr = output.getcolorptr();
+ new (colorPtr) QColor(QDeclarativeStringConverters::colorFromString(tmp));
+
+ COLOR_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertStringToUrl, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
}
QML_V4_END_INSTR(ConvertUrlToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertColorToBool, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined()) {
+ output.setUndefined();
+ } else {
+ // for compatibility with color behavior in v8, always true
+ output.setbool(true);
+ }
+ }
+ QML_V4_END_INSTR(ConvertColorToBool, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertColorToString, 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);
+ }
+ // to maintain behaviour with QtQuick 1.0, we just output normal toString() value.
+ new (output.getstringptr()) QString(QVariant(tmp).toString());
+ STRING_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertColorToString, unaryop)
+
QML_V4_BEGIN_INSTR(ResolveUrl, unaryop)
{
const Register &src = registers[instr->unaryop.src];
case QMetaType::QUrl:
regType = QUrlType;
break;
+ case QMetaType::QColor:
+ regType = QColorType;
+ break;
default:
if (propTy == QDeclarativeMetaType::QQuickAnchorLineMetaTypeId()) {
gen(i);
} return;
+ case IR::ColorType: {
+ Instr::ConvertColorToBool i;
+ i.output = i.src = reg;
+ gen(i);
+ } return;
+
default:
discard();
break;
case IR::RealType: opcode = V4Instr::ConvertRealToBool; break;
case IR::StringType: opcode = V4Instr::ConvertStringToBool; break;
case IR::UrlType: opcode = V4Instr::ConvertUrlToBool; break;
+ case IR::ColorType: opcode = V4Instr::ConvertColorToBool; break;
default: break;
} // switch
} else if (targetTy == IR::IntType) {
case IR::IntType: opcode = V4Instr::ConvertIntToString; break;
case IR::RealType: opcode = V4Instr::ConvertRealToString; break;
case IR::UrlType: opcode = V4Instr::ConvertUrlToString; break;
+ case IR::ColorType: opcode = V4Instr::ConvertColorToString; break;
default: break;
} // switch
} else if (targetTy == IR::UrlType) {
case IR::BoolType: gen(V4Instr::ConvertBoolToString, convToString); sourceTy = IR::StringType; break;
case IR::IntType: gen(V4Instr::ConvertIntToString, convToString); sourceTy = IR::StringType; break;
case IR::RealType: gen(V4Instr::ConvertRealToString, convToString); sourceTy = IR::StringType; break;
+ case IR::ColorType: gen(V4Instr::ConvertColorToString, convToString); sourceTy = IR::StringType; break;
default: break;
} // switch
if (sourceTy == IR::StringType)
opcode = V4Instr::ConvertStringToUrl;
+ } else if (targetTy == IR::ColorType) {
+ switch (sourceTy) {
+ case IR::StringType: opcode = V4Instr::ConvertStringToColor; break;
+ default: break;
+ } // switch
}
if (opcode != V4Instr::Noop) {
V4Instr conv;
case IR::UrlType:
test.regType = QMetaType::QUrl;
break;
+ case IR::ColorType:
+ test.regType = QMetaType::QColor;
+ break;
case IR::SGAnchorLineType:
test.regType = QDeclarativeMetaType::QQuickAnchorLineMetaTypeId();
break;
case V4Instr::ConvertStringToUrl:
INSTR_DUMP << "\t" << "ConvertStringToUrl" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertStringToColor:
+ INSTR_DUMP << "\t" << "ConvertStringToColor" << "\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::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::ResolveUrl:
INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
F(ConvertStringToInt, unaryop) \
F(ConvertStringToReal, unaryop) \
F(ConvertStringToUrl, unaryop) \
+ F(ConvertStringToColor, unaryop) \
F(ConvertUrlToBool, unaryop) \
F(ConvertUrlToString, unaryop) \
+ F(ConvertColorToBool, unaryop) \
+ F(ConvertColorToString, unaryop) \
F(ResolveUrl, unaryop) \
F(MathSinReal, unaryop) \
F(MathCosReal, unaryop) \
case VoidType: return "void";
case StringType: return "string";
case UrlType: return "url";
+ case ColorType: return "color";
case SGAnchorLineType: return "SGAnchorLine";
case AttachType: return "AttachType";
case ObjectType: return "object";
inline bool isStringType(IR::Type ty)
{
- return ty == IR::StringType || ty == IR::UrlType;
+ return ty == IR::StringType || ty == IR::UrlType || ty == IR::ColorType;
}
IR::Type maxType(IR::Type left, IR::Type right)
VoidType,
StringType,
UrlType,
+ ColorType,
SGAnchorLineType,
AttachType,
ObjectType,
case QMetaType::QUrl:
return IR::UrlType;
+ case QMetaType::QColor:
+ return IR::ColorType;
+
default:
if (t == QDeclarativeMetaType::QQuickAnchorLineMetaTypeId()) {
return IR::SGAnchorLineType;
QStringType = FirstCleanupType,
QUrlType,
QVariantType,
+ QColorType
};
const char *QV4Program::data() const
--- /dev/null
+import QtQuick 2.0
+
+QtObject {
+ property bool useMyColor: true
+ property color myColor: "red"
+ property color myOtherColor: "green"
+
+ property color test1: useMyColor ? myColor : myOtherColor
+ property color test2: useMyColor ? "red" : "green"
+ property color test3: useMyColor ? myColor : "green"
+
+ property bool test4: !myColor ? false : true
+
+ property bool test5: myColor != "red"
+ property bool test6: myColor == "#ff0000"
+ property bool test7: myColor != "#00ff00"
+}
+
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdebug.h>
+#include <QtGui/qcolor.h>
#include <private/qv4compiler_p.h>
void stringComparison();
void unaryMinus();
void unaryPlus();
+ void colorType();
private:
QDeclarativeEngine engine;
delete o;
}
+void tst_v4::colorType()
+{
+ QDeclarativeComponent component(&engine, testFileUrl("colorType.qml"));
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+ QCOMPARE(o->property("test1").value<QColor>(), QColor("red"));
+ QCOMPARE(o->property("test2").value<QColor>(), QColor("red"));
+ QCOMPARE(o->property("test3").value<QColor>(), QColor("red"));
+ QCOMPARE(o->property("test4").toBool(), true);
+ QCOMPARE(o->property("test5").toBool(), true);
+ QCOMPARE(o->property("test6").toBool(), true);
+ QCOMPARE(o->property("test7").toBool(), true);
+ delete o;
+}
+
QTEST_MAIN(tst_v4)
#include "tst_v4.moc"