diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4promiseobject_p.h | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 14 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 18 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 29 |
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); |