aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@theqtcompany.com>2016-03-01 14:17:44 +0100
committerJ-P Nurmi <jpnurmi@theqtcompany.com>2016-03-01 14:17:52 +0100
commit23712c568072422e49d41f039ad72c92fd117afe (patch)
tree423e84c8802074f9daa5422eb5c8c49b3074516a /src/qml
parentab2c5be35dd8f339ec39f52364625a53fa6d0ded (diff)
parent2b55b531b095a991376a26599d503223a67ae946 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro Change-Id: I3ca8f0422828191b7e19539c25f31f2d048e9f18
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp24
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h1
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp2
-rw-r--r--src/qml/qml.pro9
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp74
-rw-r--r--src/qml/types/qqmlbind.cpp4
6 files changed, 80 insertions, 34 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index a708e90116..33716d57b8 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1163,6 +1163,17 @@ struct StaticQtMetaObject : public QObject
{ return &staticQtMetaObject; }
};
+bool QQmlEnumTypeResolver::assignEnumToBinding(QmlIR::Binding *binding, const QString &enumName, int enumValue, bool isQtObject)
+{
+ if (enumName.length() > 0 && enumName[0].isLower() && !isQtObject) {
+ COMPILE_EXCEPTION(binding, tr("Invalid property assignment: Enum value \"%1\" cannot start with a lowercase letter").arg(enumName));
+ }
+ binding->type = QV4::CompiledData::Binding::Type_Number;
+ binding->value.d = (double)enumValue;
+ binding->flags |= QV4::CompiledData::Binding::IsResolvedEnum;
+ return true;
+}
+
bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, const QQmlPropertyCache *propertyCache, const QQmlPropertyData *prop, QmlIR::Binding *binding)
{
bool isIntProp = (prop->propType == QMetaType::Int) && !prop->isEnum();
@@ -1185,6 +1196,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
return true;
QHashedStringRef typeName(string.constData(), dot);
+ const bool isQtObject = (typeName == QLatin1String("Qt"));
QString enumValue = string.mid(dot+1);
if (isIntProp) {
@@ -1192,16 +1204,15 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
bool ok;
int enumval = evaluateEnum(typeName.toString(), enumValue.toUtf8(), &ok);
if (ok) {
- binding->type = QV4::CompiledData::Binding::Type_Number;
- binding->value.d = (double)enumval;
- binding->flags |= QV4::CompiledData::Binding::IsResolvedEnum;
+ if (!assignEnumToBinding(binding, enumValue, enumval, isQtObject))
+ return false;
}
return true;
}
QQmlType *type = 0;
imports->resolveType(typeName, &type, 0, 0, 0);
- if (!type && typeName != QLatin1String("Qt"))
+ if (!type && !isQtObject)
return true;
int value = 0;
@@ -1234,10 +1245,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
if (!ok)
return true;
- binding->type = QV4::CompiledData::Binding::Type_Number;
- binding->value.d = (double)value;
- binding->flags |= QV4::CompiledData::Binding::IsResolvedEnum;
- return true;
+ return assignEnumToBinding(binding, enumValue, value, isQtObject);
}
int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index 3404350ece..240f591f91 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -196,6 +196,7 @@ public:
bool resolveEnumBindings();
private:
+ bool assignEnumToBinding(QmlIR::Binding *binding, const QString &enumName, int enumValue, bool isQtObject);
bool tryQualifiedEnumAssignment(const QmlIR::Object *obj, const QQmlPropertyCache *propertyCache,
const QQmlPropertyData *prop,
QmlIR::Binding *binding);
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index f264ec028e..8c5e7d8be1 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -51,8 +51,6 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(MathObject);
-static const double qt_PI = 2.0 * ::asin(1.0);
-
Heap::MathObject::MathObject()
{
Scope scope(internalClass->engine);
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index d75262bf0b..e30c39c8b9 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -11,9 +11,6 @@ solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
# Ensure this gcc optimization is switched off for mips platforms to avoid trouble with JIT.
gcc:isEqual(QT_ARCH, "mips"): QMAKE_CXXFLAGS += -fno-reorder-blocks
-MODULE_PLUGIN_TYPES = \
- qmltooling
-
exists("qqml_enable_gcov") {
QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors
LIBS_PRIVATE += -lgcov
@@ -29,8 +26,6 @@ greaterThan(QT_CLANG_MAJOR_VERSION, 3)|greaterThan(QT_CLANG_MINOR_VERSION, 3)| \
if(equals(QT_APPLE_CLANG_MAJOR_VERSION, 5):greaterThan(QT_APPLE_CLANG_MINOR_VERSION, 0)): \
WERROR += -Wno-error=unused-const-variable
-load(qt_module)
-
HEADERS += qtqmlglobal.h \
qtqmlglobal_p.h
@@ -46,3 +41,7 @@ include(qml/qml.pri)
include(debugger/debugger.pri)
include(animations/animations.pri)
include(types/types.pri)
+
+MODULE_PLUGIN_TYPES = \
+ qmltooling
+load(qt_module)
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 2f2c6cf7dc..33fe655368 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -125,6 +125,28 @@ ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, Q
return w.asReturnedValue();
}
+static int enumForSingleton(String *name, QObject *qobjectSingleton)
+{
+ // ### Optimize
+ QByteArray enumName = name->toQString().toUtf8();
+ const QMetaObject *metaObject = qobjectSingleton->metaObject();
+ for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
+ QMetaEnum e = metaObject->enumerator(ii);
+ bool ok;
+ int value = e.keyToValue(enumName.constData(), &ok);
+ if (ok)
+ return value;
+ }
+ return -1;
+}
+
+static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *name, QQmlType *type)
+{
+ const QString message =
+ QStringLiteral("Cannot access enum value '%1' of '%2', enum values need to start with an uppercase letter.")
+ .arg(name->toQString()).arg(QLatin1String(type->typeName()));
+ return v4->throwTypeError(message);
+}
ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
@@ -141,9 +163,9 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
QQmlContextData *context = v4->callingQmlContext();
QObject *object = w->d()->object;
+ QQmlType *type = w->d()->type;
- if (w->d()->type) {
- QQmlType *type = w->d()->type;
+ if (type) {
// singleton types are handled differently to other types.
if (type->isSingleton()) {
@@ -153,24 +175,29 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
QObject *qobjectSingleton = siinfo->qobjectApi(e);
if (qobjectSingleton) {
+
// check for enum value
- if (name->startsWithUpper()) {
- if (w->d()->mode == Heap::QmlTypeWrapper::IncludeEnums) {
- // ### Optimize
- QByteArray enumName = name->toQString().toUtf8();
- const QMetaObject *metaObject = qobjectSingleton->metaObject();
- for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
- QMetaEnum e = metaObject->enumerator(ii);
- bool ok;
- int value = e.keyToValue(enumName.constData(), &ok);
- if (ok)
- return QV4::Primitive::fromInt32(value).asReturnedValue();
- }
- }
+ const bool includeEnums = w->d()->mode == Heap::QmlTypeWrapper::IncludeEnums;
+ if (includeEnums && name->startsWithUpper()) {
+ const int value = enumForSingleton(name, qobjectSingleton);
+ if (value != -1)
+ return QV4::Primitive::fromInt32(value).asReturnedValue();
}
// check for property.
- return QV4::QObjectWrapper::getQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty);
+ bool ok;
+ const ReturnedValue result = QV4::QObjectWrapper::getQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, &ok);
+ if (hasProperty)
+ *hasProperty = ok;
+
+ // Warn when attempting to access a lowercased enum value, singleton case
+ if (!ok && includeEnums && !name->startsWithUpper()) {
+ const int value = enumForSingleton(name, qobjectSingleton);
+ if (value != -1)
+ return throwLowercaseEnumError(v4, name, type);
+ }
+
+ return result;
} else if (!siinfo->scriptApi(e).isUndefined()) {
// NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
QV4::ScopedObject o(scope, QJSValuePrivate::convertedToValue(v4, siinfo->scriptApi(e)));
@@ -227,9 +254,20 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
Q_ASSERT(!"Unreachable");
}
+ bool ok = false;
+ const ReturnedValue result = Object::get(m, name, &ok);
if (hasProperty)
- *hasProperty = false;
- return Object::get(m, name, hasProperty);
+ *hasProperty = ok;
+
+ // Warn when attempting to access a lowercased enum value, non-singleton case
+ if (!ok && type && !type->isSingleton() && !name->startsWithUpper()) {
+ bool enumOk = false;
+ type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &enumOk);
+ if (enumOk)
+ return throwLowercaseEnumError(v4, name, type);
+ }
+
+ return result;
}
diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp
index e2063dee7d..ed9a8533c0 100644
--- a/src/qml/types/qqmlbind.cpp
+++ b/src/qml/types/qqmlbind.cpp
@@ -75,7 +75,7 @@ public:
void QQmlBindPrivate::validate(QObject *binding) const
{
- if (!obj)
+ if (!obj || (when.isValid() && !when))
return;
if (!prop.isValid()) {
@@ -185,6 +185,8 @@ void QQmlBind::setWhen(bool v)
return;
d->when = v;
+ if (v && d->componentComplete)
+ d->validate(this);
eval();
}