aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp14
-rw-r--r--src/qml/jsruntime/qv4promiseobject_p.h11
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp14
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
-rw-r--r--src/qml/qml/qqmlcomponent.cpp18
-rw-r--r--src/qml/qml/qqmlmetatype.cpp29
8 files changed, 67 insertions, 29 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 883b21ab07..9021fd0284 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1947,11 +1947,7 @@ QQmlPropertyData *JSCodeGen::lookupQmlCompliantProperty(QQmlPropertyCache *cache
{
QQmlPropertyData *pd = cache->property(name, /*object*/nullptr, /*context*/nullptr);
- // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
- if (!pd || pd->isFunction())
- return nullptr;
-
- if (!cache->isAllowedInRevision(pd))
+ if (pd && !cache->isAllowedInRevision(pd))
return nullptr;
return pd;
@@ -2280,6 +2276,10 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n
if (_scopeObject) {
QQmlPropertyData *data = lookupQmlCompliantProperty(_scopeObject, name);
if (data) {
+ // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
+ if (data->isFunction())
+ return Reference::fromName(this, name);
+
Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
Reference::PropertyCapturePolicy capturePolicy;
if (!data->isConstant() && !data->isQmlBinding())
@@ -2293,6 +2293,10 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n
if (_contextObject) {
QQmlPropertyData *data = lookupQmlCompliantProperty(_contextObject, name);
if (data) {
+ // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
+ if (data->isFunction())
+ return Reference::fromName(this, name);
+
Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
Reference::PropertyCapturePolicy capturePolicy;
if (!data->isConstant() && !data->isQmlBinding())
diff --git a/src/qml/jsruntime/qv4promiseobject_p.h b/src/qml/jsruntime/qv4promiseobject_p.h
index 80f7183074..bce59b19a7 100644
--- a/src/qml/jsruntime/qv4promiseobject_p.h
+++ b/src/qml/jsruntime/qv4promiseobject_p.h
@@ -39,6 +39,17 @@
#ifndef QV4PROMISEOBJECT_H
#define QV4PROMISEOBJECT_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 2e4223de7d..8cdec2f6ee 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -764,11 +764,11 @@ struct QObjectWrapperOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
{
int propertyIndex = 0;
~QObjectWrapperOwnPropertyKeyIterator() override = default;
- PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
+ PropertyKey next(const QV4::Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
};
-PropertyKey QObjectWrapperOwnPropertyKeyIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
+PropertyKey QObjectWrapperOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd, PropertyAttributes *attrs)
{
// Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 634fbcbd97..4ef4fa2c9e 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -238,20 +238,20 @@ void Heap::RegExpCtor::clearLastMatch()
lastMatchEnd = 0;
}
-static bool isRegExp(ExecutionEngine *e, const Value *arg)
+static bool isRegExp(ExecutionEngine *e, const QV4::Value *arg)
{
- const Object *o = arg->objectValue();
+ const QV4::Object *o = arg->objectValue();
if (!o)
return false;
- Value isRegExp = Value::fromReturnedValue(o->get(e->symbol_match()));
+ QV4::Value isRegExp = QV4::Value::fromReturnedValue(o->get(e->symbol_match()));
if (!isRegExp.isUndefined())
return isRegExp.toBoolean();
const RegExpObject *re = o->as<RegExpObject>();
return re ? true : false;
}
-uint parseFlags(Scope &scope, const Value *f)
+uint parseFlags(Scope &scope, const QV4::Value *f)
{
uint flags = CompiledData::RegExp::RegExp_NoFlags;
if (!f->isUndefined()) {
@@ -546,13 +546,13 @@ static int advanceStringIndex(int index, const QString &str, bool unicode)
return index;
}
-static void advanceLastIndexOnEmptyMatch(ExecutionEngine *e, bool unicode, Object *rx, const String *matchString, const QString &str)
+static void advanceLastIndexOnEmptyMatch(ExecutionEngine *e, bool unicode, QV4::Object *rx, const String *matchString, const QString &str)
{
Scope scope(e);
if (matchString->d()->length() == 0) {
- ScopedValue v(scope, rx->get(scope.engine->id_lastIndex()));
+ QV4::ScopedValue v(scope, rx->get(scope.engine->id_lastIndex()));
int lastIndex = advanceStringIndex(v->toLength(), str, unicode);
- if (!rx->put(scope.engine->id_lastIndex(), Value::fromInt32(lastIndex)))
+ if (!rx->put(scope.engine->id_lastIndex(), QV4::Value::fromInt32(lastIndex)))
scope.engine->throwTypeError();
}
}
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index f6b9c5ba94..03f351b9e4 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -112,11 +112,11 @@ bool StringObject::virtualDeleteProperty(Managed *m, PropertyKey id)
struct StringObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
{
~StringObjectOwnPropertyKeyIterator() override = default;
- PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
+ PropertyKey next(const QV4::Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
};
-PropertyKey StringObjectOwnPropertyKeyIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
+PropertyKey StringObjectOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd, PropertyAttributes *attrs)
{
const StringObject *s = static_cast<const StringObject *>(o);
uint slen = s->d()->string->toQString().length();
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 29814246db..1cca50f6c1 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -377,7 +377,7 @@ static bool compareEqualInt(QV4::Value &accumulator, QV4::Value lhs, int rhs)
if (lhs.m()->internalClass->vtable->isString)
return RuntimeHelpers::stringToNumber(static_cast<String &>(lhs).toQString()) == rhs;
accumulator = lhs;
- lhs = Value::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(accumulator), PREFERREDTYPE_HINT));
+ lhs = QV4::Value::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(accumulator), PREFERREDTYPE_HINT));
goto redo;
case QV4::Value::QT_Empty:
Q_UNREACHABLE();
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index a67c5c4a2b..5ed3cc5d6a 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1132,22 +1132,23 @@ class QQmlComponentIncubator : public QQmlIncubator
public:
QQmlComponentIncubator(QV4::Heap::QmlIncubatorObject *inc, IncubationMode mode)
: QQmlIncubator(mode)
- , incubatorObject(inc)
- {}
+ {
+ incubatorObject.set(inc->internalClass->engine, inc);
+ }
void statusChanged(Status s) override {
- QV4::Scope scope(incubatorObject->internalClass->engine);
- QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject);
+ QV4::Scope scope(incubatorObject.engine());
+ QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject.as<QV4::QmlIncubatorObject>());
i->statusChanged(s);
}
void setInitialState(QObject *o) override {
- QV4::Scope scope(incubatorObject->internalClass->engine);
- QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject);
+ QV4::Scope scope(incubatorObject.engine());
+ QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject.as<QV4::QmlIncubatorObject>());
i->setInitialState(o);
}
- QV4::Heap::QmlIncubatorObject *incubatorObject;
+ QV4::PersistentValue incubatorObject; // keep a strong internal reference while incubating
};
@@ -1571,6 +1572,9 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s)
QQmlEnginePrivate::warning(QQmlEnginePrivate::get(scope.engine->qmlEngine()), error);
}
}
+
+ if (s != QQmlIncubator::Loading)
+ d()->incubator->incubatorObject.clear();
}
#undef INITIALPROPERTIES_SOURCE
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index ea4a69f05d..ba8d5831ad 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -847,21 +847,40 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
}
}
+ QSet<QString> localEnums;
+ const QMetaObject *localMetaObject = nullptr;
+
// Add any enum values defined by this class, overwriting any inherited values
for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
QMetaEnum e = metaObject->enumerator(ii);
const bool isScoped = e.isScoped();
QStringHash<int> *scoped = isScoped ? new QStringHash<int>() : nullptr;
+ // We allow enums in sub-classes to overwrite enums from base-classes, such as
+ // ListView.Center (from enum PositionMode) overwriting Item.Center (from enum TransformOrigin).
+ // This is acceptable because the _use_ of the enum from the QML side requires qualification
+ // anyway, i.e. ListView.Center vs. Item.Center.
+ // However if a class defines two enums with the same value, then that must produce a warning
+ // because it represents a valid conflict.
+ if (e.enclosingMetaObject() != localMetaObject) {
+ localEnums.clear();
+ localMetaObject = e.enclosingMetaObject();
+ }
+
for (int jj = 0; jj < e.keyCount(); ++jj) {
const QString key = QString::fromUtf8(e.key(jj));
const int value = e.value(jj);
if (!isScoped || (regType == QQmlType::CppType && extraData.cd->registerEnumClassesUnscoped)) {
- if (enums.contains(key)) {
- qWarning("Previously registered enum will be overwritten due to name clash: %s.%s", metaObject->className(), key.toUtf8().constData());
- createEnumConflictReport(metaObject, key);
- }
- enums.insert(key, value);
+ if (localEnums.contains(key)) {
+ auto existingEntry = enums.find(key);
+ if (existingEntry != enums.end() && existingEntry.value() != value) {
+ qWarning("Previously registered enum will be overwritten due to name clash: %s.%s", metaObject->className(), key.toUtf8().constData());
+ createEnumConflictReport(metaObject, key);
+ }
+ } else {
+ localEnums.insert(key);
+ }
+ enums.insert(key, value);
}
if (isScoped)
scoped->insert(key, value);