aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/ftw/qqmlrefcount_p.h8
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp14
-rw-r--r--src/qml/qml/qml.pri4
-rw-r--r--src/qml/qml/qqml.cpp22
-rw-r--r--src/qml/qml/qqml.h34
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp24
-rw-r--r--src/qml/qml/qqmlapplicationengine_p.h5
-rw-r--r--src/qml/qml/qqmlcomponent.cpp4
-rw-r--r--src/qml/qml/qqmlcontext.cpp17
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp7
-rw-r--r--src/qml/qml/qqmlcustomparser_p.h4
-rw-r--r--src/qml/qml/qqmlengine.cpp31
-rw-r--r--src/qml/qml/qqmlengine.h2
-rw-r--r--src/qml/qml/qqmlengine_p.h2
-rw-r--r--src/qml/qml/qqmlerror.cpp348
-rw-r--r--src/qml/qml/qqmlerror.h89
-rw-r--r--src/qml/qml/qqmlexpression.cpp8
-rw-r--r--src/qml/qml/qqmlimport.cpp29
-rw-r--r--src/qml/qml/qqmlimport_p.h3
-rw-r--r--src/qml/qml/qqmlincubator.cpp3
-rw-r--r--src/qml/qml/qqmlirloader_p.h1
-rw-r--r--src/qml/qml/qqmlmetatype.cpp24
-rw-r--r--src/qml/qml/qqmlmetatype_p.h4
-rw-r--r--src/qml/qml/qqmlnotifier.cpp4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp5
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h6
-rw-r--r--src/qml/qml/qqmlprivate.h4
-rw-r--r--src/qml/qml/qqmlpropertycachecreator.cpp29
-rw-r--r--src/qml/qml/qqmlpropertycachecreator_p.h157
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp55
-rw-r--r--src/qml/qml/qqmlpropertyvalidator_p.h20
-rw-r--r--src/qml/qml/qqmlsourcecoordinate_p.h95
-rw-r--r--src/qml/qml/qqmltype_p.h4
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp57
-rw-r--r--src/qml/qml/qqmltypecompiler_p.h7
-rw-r--r--src/qml/qml/qqmltypeloader.cpp78
-rw-r--r--src/qml/qml/qqmltypeloader_p.h7
-rw-r--r--src/qml/qml/qqmltypemodule.cpp16
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp43
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h2
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp320
42 files changed, 1130 insertions, 468 deletions
diff --git a/src/qml/qml/ftw/qqmlrefcount_p.h b/src/qml/qml/ftw/qqmlrefcount_p.h
index 140f129b21..b4f8acad49 100644
--- a/src/qml/qml/ftw/qqmlrefcount_p.h
+++ b/src/qml/qml/ftw/qqmlrefcount_p.h
@@ -113,25 +113,25 @@ QQmlRefCount::QQmlRefCount()
QQmlRefCount::~QQmlRefCount()
{
- Q_ASSERT(refCount.load() == 0);
+ Q_ASSERT(refCount.loadRelaxed() == 0);
}
void QQmlRefCount::addref() const
{
- Q_ASSERT(refCount.load() > 0);
+ Q_ASSERT(refCount.loadRelaxed() > 0);
refCount.ref();
}
void QQmlRefCount::release() const
{
- Q_ASSERT(refCount.load() > 0);
+ Q_ASSERT(refCount.loadRelaxed() > 0);
if (!refCount.deref())
delete this;
}
int QQmlRefCount::count() const
{
- return refCount.load();
+ return refCount.loadRelaxed();
}
template<class T>
diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp
index 2ef1dc7e93..e961ed3d0d 100644
--- a/src/qml/qml/ftw/qqmlthread.cpp
+++ b/src/qml/qml/ftw/qqmlthread.cpp
@@ -104,14 +104,18 @@ QQmlThreadPrivate::MainObject::MainObject(QQmlThreadPrivate *p)
// Trigger mainEvent in main thread. Must be called from thread.
void QQmlThreadPrivate::triggerMainEvent()
{
+#if QT_CONFIG(thread)
Q_ASSERT(q->isThisThread());
+#endif
QCoreApplication::postEvent(&m_mainObject, new QEvent(QEvent::User));
}
// Trigger even in thread. Must be called from main thread.
void QQmlThreadPrivate::triggerThreadEvent()
{
+#if QT_CONFIG(thread)
Q_ASSERT(!q->isThisThread());
+#endif
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
}
@@ -353,6 +357,12 @@ void QQmlThread::internalCallMethodInThread(Message *message)
void QQmlThread::internalCallMethodInMain(Message *message)
{
+#if !QT_CONFIG(thread)
+ message->call(this);
+ delete message;
+ return;
+#endif
+
Q_ASSERT(isThisThread());
d->lock();
@@ -397,7 +407,9 @@ void QQmlThread::internalPostMethodToThread(Message *message)
void QQmlThread::internalPostMethodToMain(Message *message)
{
+#if QT_CONFIG(thread)
Q_ASSERT(isThisThread());
+#endif
d->lock();
bool wasEmpty = d->mainList.isEmpty();
d->mainList.append(message);
@@ -408,7 +420,9 @@ void QQmlThread::internalPostMethodToMain(Message *message)
void QQmlThread::waitForNextMessage()
{
+#if QT_CONFIG(thread)
Q_ASSERT(!isThisThread());
+#endif
d->lock();
Q_ASSERT(d->m_mainThreadWaiting == false);
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index c625743f61..15ea12cbe7 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -1,5 +1,6 @@
SOURCES += \
$$PWD/qqml.cpp \
+ $$PWD/qqmlerror.cpp \
$$PWD/qqmlopenmetaobject.cpp \
$$PWD/qqmlvmemetaobject.cpp \
$$PWD/qqmlengine.cpp \
@@ -142,7 +143,8 @@ HEADERS += \
$$PWD/qqmlpropertyresolver_p.h \
$$PWD/qqmltypecompiler_p.h \
$$PWD/qqmlpropertycachecreator_p.h \
- $$PWD/qqmlpropertyvalidator_p.h
+ $$PWD/qqmlpropertyvalidator_p.h \
+ $$PWD/qqmlsourcecoordinate_p.h
qtConfig(qml-xml-http-request) {
HEADERS += \
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp
index c1a8ed2a3d..613816e3f7 100644
--- a/src/qml/qml/qqml.cpp
+++ b/src/qml/qml/qqml.cpp
@@ -55,9 +55,7 @@ void qmlClearTypeRegistrations() // Declared in qqml.h
{
QQmlMetaType::clearTypeRegistrations();
QQmlEnginePrivate::baseModulesUninitialized = true; //So the engine re-registers its types
-#if QT_CONFIG(library)
qmlClearEnginePlugins();
-#endif
}
//From qqml.h
@@ -113,4 +111,24 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return dtype.index();
}
+void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data)
+{
+ switch (type) {
+ case AutoParentRegistration:
+ QQmlMetaType::unregisterAutoParentFunction(reinterpret_cast<AutoParentFunction>(data));
+ break;
+ case QmlUnitCacheHookRegistration:
+ QQmlMetaType::removeCachedUnitLookupFunction(
+ reinterpret_cast<QmlUnitCacheLookupFunction>(data));
+ break;
+ case TypeRegistration:
+ case InterfaceRegistration:
+ case SingletonRegistration:
+ case CompositeRegistration:
+ case CompositeSingletonRegistration:
+ QQmlMetaType::unregisterType(data);
+ break;
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 7b3f89e943..4f3bfb76b0 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -608,9 +608,12 @@ Q_QML_EXPORT void qmlRegisterModule(const char *uri, int versionMajor, int versi
template<typename T>
QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
{
- QObject *mutableObj = const_cast<QObject *>(obj);
- return qmlAttachedPropertiesObject(
- mutableObj, qmlAttachedPropertiesFunction(mutableObj, &T::staticMetaObject), create);
+ // We don't need a concrete object to resolve the function. As T is a C++ type, it and all its
+ // super types should be registered as CppType (or not at all). We only need the object and its
+ // QML engine to resolve composite types. Therefore, the function is actually a static property
+ // of the C++ type system and we can cache it here for improved performance on further lookups.
+ static const auto func = qmlAttachedPropertiesFunction(nullptr, &T::staticMetaObject);
+ return qmlAttachedPropertiesObject(const_cast<QObject *>(obj), func, create);
}
inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
@@ -621,13 +624,13 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
uri, versionMajor, versionMinor, typeName,
- callback, nullptr, nullptr, 0, 0
+ callback, nullptr, nullptr, 0, 0, {}
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
}
-enum { QmlCurrentSingletonTypeRegistrationVersion = 2 };
+enum { QmlCurrentSingletonTypeRegistrationVersion = 3 };
template <typename T>
inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
QObject *(*callback)(QQmlEngine *, QJSEngine *))
@@ -639,7 +642,26 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
uri, versionMajor, versionMinor, typeName,
- nullptr, callback, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0
+ nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback
+ };
+
+ return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
+}
+
+template <typename T, typename F, typename std::enable_if<std::is_convertible<F, std::function<QObject *(QQmlEngine *, QJSEngine *)>>::value
+ && !std::is_convertible<F, QObject *(*)(QQmlEngine *, QJSEngine *)>::value, void>::type* = nullptr>
+inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
+ F&& callback)
+{
+
+ QML_GETTYPENAMES
+
+ QQmlPrivate::RegisterSingletonType api = {
+ QmlCurrentSingletonTypeRegistrationVersion,
+
+ uri, versionMajor, versionMinor, typeName,
+
+ nullptr, nullptr, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0, callback
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 1b7a433a84..7149f8c134 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -62,9 +62,6 @@ void QQmlApplicationEnginePrivate::cleanUp()
obj->disconnect(q);
qDeleteAll(objects);
-#if QT_CONFIG(translation)
- qDeleteAll(translators);
-#endif
}
void QQmlApplicationEnginePrivate::init()
@@ -75,10 +72,11 @@ void QQmlApplicationEnginePrivate::init()
q->connect(q, &QQmlApplicationEngine::exit, QCoreApplication::instance(),
&QCoreApplication::exit, Qt::QueuedConnection);
#if QT_CONFIG(translation)
- QTranslator* qtTranslator = new QTranslator;
- if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
+ QTranslator* qtTranslator = new QTranslator(q);
+ if (qtTranslator->load(QLocale(), QLatin1String("qt"), QLatin1String("_"), QLibraryInfo::location(QLibraryInfo::TranslationsPath), QLatin1String(".qm")))
QCoreApplication::installTranslator(qtTranslator);
- translators << qtTranslator;
+ else
+ delete qtTranslator;
#endif
new QQmlFileSelector(q,q);
QCoreApplication::instance()->setProperty("__qml_using_qqmlapplicationengine", QVariant(true));
@@ -90,15 +88,14 @@ void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile)
if (rootFile.scheme() != QLatin1String("file") && rootFile.scheme() != QLatin1String("qrc"))
return;
- QFileInfo fi(rootFile.toLocalFile());
+ QFileInfo fi(QQmlFile::urlToLocalFileOrQrc(rootFile));
- QTranslator *translator = new QTranslator;
- if (translator->load(QLocale(), QLatin1String("qml"), QLatin1String("_"), fi.path() + QLatin1String("/i18n"))) {
+ Q_Q(QQmlApplicationEngine);
+ QTranslator *translator = new QTranslator(q);
+ if (translator->load(QLocale(), QLatin1String("qml"), QLatin1String("_"), fi.path() + QLatin1String("/i18n"), QLatin1String(".qm")))
QCoreApplication::installTranslator(translator);
- translators << translator;
- } else {
+ else
delete translator;
- }
#else
Q_UNUSED(rootFile)
#endif
@@ -180,6 +177,9 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
\list
\li Connecting Qt.quit() to QCoreApplication::quit()
\li Automatically loads translation files from an i18n directory adjacent to the main QML file.
+ \list
+ \li Translation files must have "qml_" prefix e.g. qml_ja_JP.qm.
+ \endlist
\li Automatically sets an incubation controller if the scene contains a QQuickWindow.
\li Automatically sets a \c QQmlFileSelector as the url interceptor, applying file selectors to all
QML files and assets.
diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h
index 6cf6828832..7a341847bd 100644
--- a/src/qml/qml/qqmlapplicationengine_p.h
+++ b/src/qml/qml/qqmlapplicationengine_p.h
@@ -59,7 +59,6 @@
QT_BEGIN_NAMESPACE
-class QTranslator;
class QFileSelector;
class Q_QML_PRIVATE_EXPORT QQmlApplicationEnginePrivate : public QQmlEnginePrivate
{
@@ -74,10 +73,6 @@ public:
void loadTranslations(const QUrl &rootFile);
void finishLoad(QQmlComponent *component);
QList<QObject *> objects;
-
-#if QT_CONFIG(translation)
- QList<QTranslator *> translators;
-#endif
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 04debc0615..59b5cc2691 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -64,7 +64,6 @@
#include <QThreadStorage>
#include <QtCore/qdebug.h>
#include <qqmlinfo.h>
-#include "qqmlmemoryprofiler_p.h"
namespace {
QThreadStorage<int> creationDepth;
@@ -774,7 +773,6 @@ QQmlComponent::QQmlComponent(QQmlComponentPrivate &dd, QObject *parent)
QObject *QQmlComponent::create(QQmlContext *context)
{
Q_D(QQmlComponent);
- QML_MEMORY_SCOPE_URL(url());
if (!context)
context = d->engine->rootContext();
@@ -1206,7 +1204,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent)
\js
var component = Qt.createComponent("Button.qml");
if (component.status == Component.Ready)
- component.createObject(parent, {"x": 100, "y": 100});
+ component.createObject(parent, {x: 100, y: 100});
\endjs
Dynamically created instances can be deleted with the \c destroy() method.
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index bd59409475..14892bd6ad 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -317,6 +317,12 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
d->propertyValues[idx] = value;
QMetaObject::activate(this, d->notifyIndex, idx, nullptr);
}
+
+ if (auto *obj = qvariant_cast<QObject *>(value)) {
+ connect(obj, &QObject::destroyed, this, [d, name](QObject *destroyed) {
+ d->dropDestroyedQObject(name, destroyed);
+ });
+ }
}
/*!
@@ -524,6 +530,17 @@ QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, int ind
}
}
+void QQmlContextPrivate::dropDestroyedQObject(const QString &name, QObject *destroyed)
+{
+ const int idx = data->propertyNames().value(name);
+ Q_ASSERT(idx >= 0);
+ if (qvariant_cast<QObject *>(propertyValues[idx]) != destroyed)
+ return;
+
+ propertyValues[idx] = QVariant::fromValue<QObject *>(nullptr);
+ QMetaObject::activate(q_func(), notifyIndex, idx, nullptr);
+}
+
QQmlContextData::QQmlContextData()
: QQmlContextData(nullptr)
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 1ddd04c9ff..5f7316b00c 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -104,6 +104,8 @@ public:
static int context_count(QQmlListProperty<QObject> *);
static QObject *context_at(QQmlListProperty<QObject> *, int);
+
+ void dropDestroyedQObject(const QString &name, QObject *destroyed);
};
class QQmlComponentAttached;
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index 5cf87f5264..c477415ef7 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -100,7 +100,12 @@ void QQmlCustomParser::clearErrors()
*/
void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const QString &description)
{
- exceptions << QQmlCompileError(location, description);
+ QQmlJS::DiagnosticMessage error;
+ error.line = location.line;
+ error.column = location.column;
+ error.message = description;
+
+ exceptions << error;
}
struct StaticQtMetaObject : public QObject
diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h
index c8e1300a1b..94671a4f35 100644
--- a/src/qml/qml/qqmlcustomparser_p.h
+++ b/src/qml/qml/qqmlcustomparser_p.h
@@ -83,7 +83,7 @@ public:
virtual void verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, const QList<const QV4::CompiledData::Binding *> &) = 0;
virtual void applyBindings(QObject *, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, const QList<const QV4::CompiledData::Binding *> &) = 0;
- QVector<QQmlCompileError> errors() const { return exceptions; }
+ QVector<QQmlJS::DiagnosticMessage> errors() const { return exceptions; }
protected:
void error(const QV4::CompiledData::Binding *binding, const QString& description)
@@ -97,7 +97,7 @@ protected:
const QMetaObject *resolveType(const QString&) const;
private:
- QVector<QQmlCompileError> exceptions;
+ QVector<QQmlJS::DiagnosticMessage> exceptions;
QQmlEnginePrivate *engine;
const QQmlPropertyValidator *validator;
Flags m_flags;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 691eb987f6..4460312e2c 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -811,9 +811,9 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
// marshalled back onto the QObject's thread and handled by QML from there. This is tested
// by the qqmlecmascript::threadSignal() autotest.
if (ddata->notifyList &&
- QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId.load()) {
+ QThread::currentThreadId() != QObjectPrivate::get(object)->threadData->threadId.loadRelaxed()) {
- if (!QObjectPrivate::get(object)->threadData->thread)
+ if (!QObjectPrivate::get(object)->threadData->thread.loadAcquire())
return;
QMetaMethod m = QMetaObjectPrivate::signal(object->metaObject(), index);
@@ -849,7 +849,7 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
mpo->target = object;
- mpo->moveToThread(QObjectPrivate::get(object)->threadData->thread);
+ mpo->moveToThread(QObjectPrivate::get(object)->threadData->thread.loadAcquire());
QCoreApplication::postEvent(mpo, ev);
} else {
@@ -1169,6 +1169,13 @@ void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
}
}
+QSharedPointer<QQmlImageProviderBase> QQmlEnginePrivate::imageProvider(const QString &providerId) const
+{
+ const QString providerIdLower = providerId.toLower();
+ QMutexLocker locker(&mutex);
+ return imageProviders.value(providerIdLower);
+}
+
#if QT_CONFIG(qml_network)
/*!
Sets the \a factory to use for creating QNetworkAccessManager(s).
@@ -1258,8 +1265,10 @@ QNetworkAccessManager *QQmlEngine::networkAccessManager() const
void QQmlEngine::addImageProvider(const QString &providerId, QQmlImageProviderBase *provider)
{
Q_D(QQmlEngine);
+ QString providerIdLower = providerId.toLower();
+ QSharedPointer<QQmlImageProviderBase> sp(provider);
QMutexLocker locker(&d->mutex);
- d->imageProviders.insert(providerId.toLower(), QSharedPointer<QQmlImageProviderBase>(provider));
+ d->imageProviders.insert(std::move(providerIdLower), std::move(sp));
}
/*!
@@ -1270,8 +1279,9 @@ void QQmlEngine::addImageProvider(const QString &providerId, QQmlImageProviderBa
QQmlImageProviderBase *QQmlEngine::imageProvider(const QString &providerId) const
{
Q_D(const QQmlEngine);
+ const QString providerIdLower = providerId.toLower();
QMutexLocker locker(&d->mutex);
- return d->imageProviders.value(providerId.toLower()).data();
+ return d->imageProviders.value(providerIdLower).data();
}
/*!
@@ -1282,8 +1292,9 @@ QQmlImageProviderBase *QQmlEngine::imageProvider(const QString &providerId) cons
void QQmlEngine::removeImageProvider(const QString &providerId)
{
Q_D(QQmlEngine);
+ const QString providerIdLower = providerId.toLower();
QMutexLocker locker(&d->mutex);
- d->imageProviders.take(providerId.toLower());
+ d->imageProviders.take(providerIdLower);
}
/*!
@@ -2109,15 +2120,15 @@ QList<QQmlError> QQmlEnginePrivate::qmlErrorFromDiagnostics(const QString &fileN
QList<QQmlError> errors;
for (const DiagnosticMessage &m : diagnosticMessages) {
if (m.isWarning()) {
- qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message));
+ qWarning("%s:%d : %s", qPrintable(fileName), m.line, qPrintable(m.message));
continue;
}
QQmlError error;
error.setUrl(QUrl(fileName));
error.setDescription(m.message);
- error.setLine(m.loc.startLine);
- error.setColumn(m.loc.startColumn);
+ error.setLine(m.line);
+ error.setColumn(m.column);
errors << error;
}
return errors;
@@ -2245,6 +2256,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths)
d->importDatabase.setPluginPathList(paths);
}
+#if QT_CONFIG(library)
/*!
Imports the plugin named \a filePath with the \a uri provided.
Returns true if the plugin was successfully imported; otherwise returns false.
@@ -2258,6 +2270,7 @@ bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList
Q_D(QQmlEngine);
return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), -1, errors);
}
+#endif
/*!
\property QQmlEngine::offlineStoragePath
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index da91c8fa15..31fe3a1849 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -114,7 +114,9 @@ public:
bool addNamedBundle(const QString &name, const QString &fileName);
+#if QT_CONFIG(library)
bool importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors);
+#endif
#if QT_CONFIG(qml_network)
void setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *);
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index 3b716683fd..e58ff554a7 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -167,6 +167,8 @@ public:
mutable QQmlNetworkAccessManagerFactory *networkAccessManagerFactory;
#endif
QHash<QString,QSharedPointer<QQmlImageProviderBase> > imageProviders;
+ QSharedPointer<QQmlImageProviderBase> imageProvider(const QString &providerId) const;
+
QQmlAbstractUrlInterceptor* urlInterceptor;
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
new file mode 100644
index 0000000000..739d5ce4cd
--- /dev/null
+++ b/src/qml/qml/qqmlerror.cpp
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlerror.h"
+#include "qqmlsourcecoordinate_p.h"
+#include <private/qqmljsdiagnosticmessage_p.h>
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qvector.h>
+
+#include <QtCore/qobject.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQmlError
+ \since 5.0
+ \inmodule QtQml
+ \brief The QQmlError class encapsulates a QML error.
+
+ QQmlError includes a textual description of the error, as well
+ as location information (the file, line, and column). The toString()
+ method creates a single-line, human-readable string containing all of
+ this information, for example:
+ \code
+ file:///home/user/test.qml:7:8: Invalid property assignment: double expected
+ \endcode
+
+ You can use qDebug(), qInfo(), or qWarning() to output errors to the console.
+ This method will attempt to open the file indicated by the error
+ and include additional contextual information.
+ \code
+ file:///home/user/test.qml:7:8: Invalid property assignment: double expected
+ y: "hello"
+ ^
+ \endcode
+
+ \sa QQuickView::errors(), QQmlComponent::errors()
+*/
+class QQmlErrorPrivate : public QQmlJS::DiagnosticMessage
+{
+public:
+ QQmlErrorPrivate() { type = QtWarningMsg; }
+ QUrl url;
+ QPointer<QObject> object;
+};
+
+/*!
+ Creates an empty error object.
+*/
+QQmlError::QQmlError()
+: d(nullptr)
+{
+}
+
+/*!
+ Creates a copy of \a other.
+*/
+QQmlError::QQmlError(const QQmlError &other)
+: d(nullptr)
+{
+ *this = other;
+}
+
+/*!
+ Assigns \a other to this error object.
+*/
+QQmlError &QQmlError::operator=(const QQmlError &other)
+{
+ if (!other.d) {
+ delete d;
+ d = nullptr;
+ } else {
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->url = other.d->url;
+ d->message = other.d->message;
+ d->line = other.d->line;
+ d->column = other.d->column;
+ d->object = other.d->object;
+ d->type = other.d->type;
+ }
+ return *this;
+}
+
+/*!
+ \internal
+*/
+QQmlError::~QQmlError()
+{
+ delete d; d = nullptr;
+}
+
+/*!
+ Returns true if this error is valid, otherwise false.
+*/
+bool QQmlError::isValid() const
+{
+ return d != nullptr;
+}
+
+/*!
+ Returns the url for the file that caused this error.
+*/
+QUrl QQmlError::url() const
+{
+ if (d)
+ return d->url;
+ return QUrl();
+}
+
+/*!
+ Sets the \a url for the file that caused this error.
+*/
+void QQmlError::setUrl(const QUrl &url)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->url = url;
+}
+
+/*!
+ Returns the error description.
+*/
+QString QQmlError::description() const
+{
+ if (d)
+ return d->message;
+ return QString();
+}
+
+/*!
+ Sets the error \a description.
+*/
+void QQmlError::setDescription(const QString &description)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->message = description;
+}
+
+/*!
+ Returns the error line number.
+*/
+int QQmlError::line() const
+{
+ if (d)
+ return qmlConvertSourceCoordinate<quint32, int>(d->line);
+ return -1;
+}
+
+/*!
+ Sets the error \a line number.
+*/
+void QQmlError::setLine(int line)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->line = qmlConvertSourceCoordinate<int, quint32>(line);
+}
+
+/*!
+ Returns the error column number.
+*/
+int QQmlError::column() const
+{
+ if (d)
+ return qmlConvertSourceCoordinate<quint32, int>(d->column);
+ return -1;
+}
+
+/*!
+ Sets the error \a column number.
+*/
+void QQmlError::setColumn(int column)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->column = qmlConvertSourceCoordinate<int, quint32>(column);
+}
+
+/*!
+ Returns the nearest object where this error occurred.
+ Exceptions in bound property expressions set this to the object
+ to which the property belongs. It will be 0 for all
+ other exceptions.
+ */
+QObject *QQmlError::object() const
+{
+ if (d)
+ return d->object;
+ return nullptr;
+}
+
+/*!
+ Sets the nearest \a object where this error occurred.
+ */
+void QQmlError::setObject(QObject *object)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->object = object;
+}
+
+/*!
+ \since 5.9
+
+ Returns the message type.
+ */
+QtMsgType QQmlError::messageType() const
+{
+ if (d)
+ return d->type;
+ return QtMsgType::QtWarningMsg;
+}
+
+/*!
+ \since 5.9
+
+ Sets the \a messageType for this message. The message type determines which
+ QDebug handlers are responsible for receiving the message.
+ */
+void QQmlError::setMessageType(QtMsgType messageType)
+{
+ if (!d)
+ d = new QQmlErrorPrivate;
+ d->type = messageType;
+}
+
+/*!
+ Returns the error as a human readable string.
+*/
+QString QQmlError::toString() const
+{
+ QString rv;
+
+ QUrl u(url());
+ int l(line());
+
+ if (u.isEmpty() || (u.isLocalFile() && u.path().isEmpty()))
+ rv += QLatin1String("<Unknown File>");
+ else
+ rv += u.toString();
+
+ if (l != -1) {
+ rv += QLatin1Char(':') + QString::number(l);
+
+ int c(column());
+ if (c != -1)
+ rv += QLatin1Char(':') + QString::number(c);
+ }
+
+ rv += QLatin1String(": ") + description();
+
+ return rv;
+}
+
+/*!
+ \relates QQmlError
+ \fn QDebug operator<<(QDebug debug, const QQmlError &error)
+
+ Outputs a human readable version of \a error to \a debug.
+*/
+
+QDebug operator<<(QDebug debug, const QQmlError &error)
+{
+ debug << qPrintable(error.toString());
+
+ QUrl url = error.url();
+
+ if (error.line() > 0 && url.scheme() == QLatin1String("file")) {
+ QString file = url.toLocalFile();
+ QFile f(file);
+ if (f.open(QIODevice::ReadOnly)) {
+ QByteArray data = f.readAll();
+ QTextStream stream(data, QIODevice::ReadOnly);
+#if QT_CONFIG(textcodec)
+ stream.setCodec("UTF-8");
+#endif
+ const QString code = stream.readAll();
+ const auto lines = code.splitRef(QLatin1Char('\n'));
+
+ if (lines.count() >= error.line()) {
+ const QStringRef &line = lines.at(error.line() - 1);
+ debug << "\n " << line.toLocal8Bit().constData();
+
+ if(error.column() > 0) {
+ int column = qMax(0, error.column() - 1);
+ column = qMin(column, line.length());
+
+ QByteArray ind;
+ ind.reserve(column);
+ for (int i = 0; i < column; ++i) {
+ const QChar ch = line.at(i);
+ if (ch.isSpace())
+ ind.append(ch.unicode());
+ else
+ ind.append(' ');
+ }
+ ind.append('^');
+ debug << "\n " << ind.constData();
+ }
+ }
+ }
+ }
+ return debug;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h
new file mode 100644
index 0000000000..8ea493c11d
--- /dev/null
+++ b/src/qml/qml/qqmlerror.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLERROR_H
+#define QQMLERROR_H
+
+#include <QtQml/qtqmlglobal.h>
+
+#include <QtCore/qurl.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+// ### Qt 6: should this be called QQmlMessage, since it can have a message type?
+class QDebug;
+class QQmlErrorPrivate;
+class Q_QML_EXPORT QQmlError
+{
+public:
+ QQmlError();
+ QQmlError(const QQmlError &);
+ QQmlError &operator=(const QQmlError &);
+ ~QQmlError();
+
+ bool isValid() const;
+
+ QUrl url() const;
+ void setUrl(const QUrl &);
+ QString description() const;
+ void setDescription(const QString &);
+ int line() const;
+ void setLine(int);
+ int column() const;
+ void setColumn(int);
+
+ QObject *object() const;
+ void setObject(QObject *);
+
+ QtMsgType messageType() const;
+ void setMessageType(QtMsgType messageType);
+
+ QString toString() const;
+private:
+ QQmlErrorPrivate *d;
+};
+
+QDebug Q_QML_EXPORT operator<<(QDebug debug, const QQmlError &error);
+
+Q_DECLARE_TYPEINFO(QQmlError, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+#endif // QQMLERROR_H
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 6a11583f18..be0adc54a7 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -351,7 +351,7 @@ QString QQmlExpression::sourceFile() const
int QQmlExpression::lineNumber() const
{
Q_D(const QQmlExpression);
- return qmlSourceCoordinate(d->line);
+ return qmlConvertSourceCoordinate<quint16, int>(d->line);
}
/*!
@@ -361,7 +361,7 @@ int QQmlExpression::lineNumber() const
int QQmlExpression::columnNumber() const
{
Q_D(const QQmlExpression);
- return qmlSourceCoordinate(d->column);
+ return qmlConvertSourceCoordinate<quint16, int>(d->column);
}
/*!
@@ -372,8 +372,8 @@ void QQmlExpression::setSourceLocation(const QString &url, int line, int column)
{
Q_D(QQmlExpression);
d->url = url;
- d->line = qmlSourceCoordinate(line);
- d->column = qmlSourceCoordinate(column);
+ d->line = qmlConvertSourceCoordinate<int, quint16>(line);
+ d->column = qmlConvertSourceCoordinate<int, quint16>(column);
}
/*!
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 9d5801bbc6..95ab79070d 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1020,13 +1020,6 @@ bool QQmlImportsPrivate::populatePluginPairVector(QVector<StaticPluginPair> &res
return true;
}
-#if defined(QT_SHARED) || !QT_CONFIG(library)
-static inline QString msgCannotLoadPlugin(const QString &uri, const QString &why)
-{
- return QQmlImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri, why);
-}
-#endif
-
/*
Import an extension defined by a qmldir file.
@@ -1075,7 +1068,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
int dynamicPluginsFound = 0;
int staticPluginsFound = 0;
-#if defined(QT_SHARED)
+#if QT_CONFIG(library)
const auto qmldirPlugins = qmldir.plugins();
for (const QQmlDirParser::Plugin &plugin : qmldirPlugins) {
QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, plugin.path, plugin.name);
@@ -1086,9 +1079,11 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
// XXX TODO: should we leave the import plugin error alone?
// Here, we pop it off the top and coalesce it into this error's message.
// The reason is that the lower level may add url and line/column numbering information.
- QQmlError poppedError = errors->takeFirst();
QQmlError error;
- error.setDescription(msgCannotLoadPlugin(uri, poppedError.description()));
+ error.setDescription(
+ QQmlImportDatabase::tr(
+ "plugin cannot be loaded for module \"%1\": %2")
+ .arg(uri, errors->takeFirst().description()));
error.setUrl(QUrl::fromLocalFile(qmldirFilePath));
errors->prepend(error);
}
@@ -1096,7 +1091,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
}
}
}
-#endif // QT_SHARED
+#endif // QT_CONFIG(library)
if (dynamicPluginsFound < qmldirPluginCount) {
// Check if the missing plugins can be resolved statically. We do this by looking at
@@ -2020,13 +2015,13 @@ bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &ba
return true;
}
+#if QT_CONFIG(library)
/*!
\internal
*/
bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QString &uri,
const QString &typeNamespace, int vmaj, QList<QQmlError> *errors)
{
-#if QT_CONFIG(library)
QFileInfo fileInfo(filePath);
const QString absoluteFilePath = fileInfo.absoluteFilePath();
@@ -2104,16 +2099,10 @@ bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QStr
}
return true;
-#else
- Q_UNUSED(filePath);
- Q_UNUSED(uri);
- Q_UNUSED(typeNamespace);
- Q_UNUSED(vmaj);
- Q_UNUSED(errors);
- return false;
-#endif
}
+#endif // QT_CONFIG(library)
+
void QQmlImportDatabase::clearDirCache()
{
QStringHash<QmldirCache *>::ConstIterator itr = qmldirCache.constBegin();
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index d3055b552c..ea9c2eafb5 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -44,6 +44,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qset.h>
#include <QtCore/qstringlist.h>
+#include <QtQml/qqmlerror.h>
#include <private/qqmldirparser_p.h>
#include <private/qqmltype_p.h>
#include <private/qstringhash_p.h>
@@ -211,7 +212,9 @@ public:
QQmlImportDatabase(QQmlEngine *);
~QQmlImportDatabase();
+#if QT_CONFIG(library)
bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, int vmaj, QList<QQmlError> *errors);
+#endif
QStringList importPathList(PathType type = LocalOrRemote) const;
void setImportPathList(const QStringList &paths);
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 39da550d63..bc06226cbf 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -42,7 +42,6 @@
#include "qqmlincubator_p.h"
#include "qqmlexpression_p.h"
-#include "qqmlmemoryprofiler_p.h"
#include "qqmlobjectcreator_p.h"
void QQmlEnginePrivate::incubate(QQmlIncubator &i, QQmlContextData *forContext)
@@ -272,8 +271,6 @@ void QQmlIncubatorPrivate::incubate(QQmlInstantiationInterrupt &i)
if (!compilationUnit)
return;
- QML_MEMORY_SCOPE_URL(compilationUnit->finalUrl());
-
QExplicitlySharedDataPointer<QQmlIncubatorPrivate> protectThis(this);
QRecursionWatcher<QQmlIncubatorPrivate, &QQmlIncubatorPrivate::recursion> watcher(this);
diff --git a/src/qml/qml/qqmlirloader_p.h b/src/qml/qml/qqmlirloader_p.h
index aa303c923f..4812946ef0 100644
--- a/src/qml/qml/qqmlirloader_p.h
+++ b/src/qml/qml/qqmlirloader_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <private/qtqmlglobal_p.h>
#include <private/qv4compileddata_p.h>
#include <private/qqmljsmemorypool_p.h>
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index a5b92d14f7..67fdf8847b 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -107,7 +107,7 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
d->version_maj = type.versionMajor;
d->version_min = type.versionMinor;
- if (type.qobjectApi) {
+ if (type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi)) {
if (type.version >= 1) // static metaobject added in version 1
d->baseMetaObject = type.instanceMetaObject;
if (type.version >= 2) // typeId added in version 2
@@ -118,10 +118,14 @@ static QQmlTypePrivate *createQQmlType(QQmlMetaTypeData *data, const QString &el
d->extraData.sd->singletonInstanceInfo = new QQmlType::SingletonInstanceInfo;
d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi;
- d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
+ if (type.version >= 3) {
+ d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.generalizedQobjectApi;
+ } else {
+ d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi;
+ }
d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
d->extraData.sd->singletonInstanceInfo->instanceMetaObject
- = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : nullptr;
+ = ((type.qobjectApi || (type.version >= 3 && type.generalizedQobjectApi) ) && type.version >= 1) ? type.instanceMetaObject : nullptr;
return d;
}
@@ -281,7 +285,7 @@ void QQmlMetaType::clearTypeRegistrations()
data->undeletableTypes.clear();
}
-int QQmlMetaType::registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
+int QQmlMetaType::registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &autoparent)
{
QQmlMetaTypeDataPtr data;
@@ -290,6 +294,12 @@ int QQmlMetaType::registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &au
return data->parentFunctions.count() - 1;
}
+void QQmlMetaType::unregisterAutoParentFunction(const QQmlPrivate::AutoParentFunction &function)
+{
+ QQmlMetaTypeDataPtr data;
+ data->parentFunctions.removeOne(function);
+}
+
QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &type)
{
if (type.version > 0)
@@ -1193,7 +1203,8 @@ QQmlPropertyCache *QQmlMetaType::propertyCache(const QQmlType &type, int minorVe
void QQmlMetaType::unregisterType(int typeIndex)
{
QQmlMetaTypeDataPtr data;
- if (const QQmlTypePrivate *d = data->types.value(typeIndex).priv()) {
+ const QQmlType type = data->types.value(typeIndex);
+ if (const QQmlTypePrivate *d = type.priv()) {
removeQQmlTypePrivate(data->idToType, d);
removeQQmlTypePrivate(data->nameToType, d);
removeQQmlTypePrivate(data->urlToType, d);
@@ -1203,6 +1214,7 @@ void QQmlMetaType::unregisterType(int typeIndex)
module->remove(d);
data->clearPropertyCachesForMinorVersion(typeIndex);
data->types[typeIndex] = QQmlType();
+ data->undeletableTypes.remove(type);
}
}
@@ -1324,7 +1336,7 @@ const QV4::CompiledData::Unit *QQmlMetaType::findCachedCompilationUnit(const QUr
for (const auto lookup : qAsConst(data->lookupCachedQmlUnit)) {
if (const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) {
QString error;
- if (!unit->qmlData->verifyHeader(QDateTime(), &error)) {
+ if (!QV4::ExecutableCompilationUnit::verifyHeader(unit->qmlData, QDateTime(), &error)) {
qCDebug(DBG_DISK_CACHE) << "Error loading pre-compiled file " << uri << ":" << error;
if (status)
*status = CachedUnitLookupError::VersionMismatch;
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 911e519cf2..c2535a7fd5 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -176,7 +176,9 @@ public:
}
}
- static int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent);
+ static int registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &autoparent);
+ static void unregisterAutoParentFunction(const QQmlPrivate::AutoParentFunction &function);
+
static int registerUnitCacheHook(const QQmlPrivate::RegisterQmlUnitCacheHook &hookRegistration);
static void clearTypeRegistrations();
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index 0706b8c0cf..1359586b31 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -118,8 +118,8 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine
disconnect();
Q_ASSERT(engine);
- if (QObjectPrivate::get(source)->threadData->threadId.load() !=
- QObjectPrivate::get(engine)->threadData->threadId.load()) {
+ if (QObjectPrivate::get(source)->threadData->threadId.loadRelaxed() !=
+ QObjectPrivate::get(engine)->threadData->threadId.loadRelaxed()) {
QString sourceName;
QDebug(&sourceName) << source;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index e5f376fd34..be40eeb58a 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -939,7 +939,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
auto bindingTarget = _bindingTarget;
auto valueTypeProperty = _valueTypeProperty;
- auto assignBinding = [qmlBinding, bindingTarget, targetProperty, subprop, bindingProperty, valueTypeProperty](QQmlObjectCreatorSharedState *sharedState) -> bool {
+ auto assignBinding = [qmlBinding, bindingTarget, targetProperty, subprop, bindingProperty, valueTypeProperty](QQmlObjectCreatorSharedState *sharedState) mutable -> bool {
if (!qmlBinding->setTarget(bindingTarget, *targetProperty, subprop) && targetProperty->isAlias())
return false;
@@ -1384,7 +1384,8 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
QQmlPropertyData::DontRemoveBinding);
if (!b->isValueTypeProxy()) {
QQmlBinding *binding = static_cast<QQmlBinding*>(b.data());
- if (!binding->hasError() && !binding->hasDependencies())
+ if (!binding->hasError() && !binding->hasDependencies()
+ && binding->context() && !binding->context()->unresolvedNames)
b->removeFromObject();
}
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 0766e2082e..1cbad87920 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -94,14 +94,14 @@ public:
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
void clear();
- QQmlComponentAttached **componentAttachment() const { return &sharedState->componentAttached; }
+ QQmlComponentAttached **componentAttachment() { return &sharedState->componentAttached; }
- QList<QQmlEnginePrivate::FinalizeCallback> *finalizeCallbacks() const { return &sharedState->finalizeCallbacks; }
+ QList<QQmlEnginePrivate::FinalizeCallback> *finalizeCallbacks() { return &sharedState->finalizeCallbacks; }
QList<QQmlError> errors;
QQmlContextData *parentContextData() const { return parentContext.contextData(); }
- QFiniteStack<QPointer<QObject> > &allCreatedObjects() const { return sharedState->allCreatedObjects; }
+ QFiniteStack<QPointer<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; }
private:
QQmlObjectCreator(QQmlContextData *contextData, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState);
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index ae84803648..eff78195d9 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -51,6 +51,8 @@
// We mean it.
//
+#include <functional>
+
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qglobal.h>
@@ -276,6 +278,7 @@ namespace QQmlPrivate
const QMetaObject *instanceMetaObject; // new in version 1
int typeId; // new in version 2
int revision; // new in version 2
+ std::function<QObject*(QQmlEngine *, QJSEngine *)> generalizedQobjectApi; // new in version 3
// If this is extended ensure "version" is bumped!!!
};
@@ -318,6 +321,7 @@ namespace QQmlPrivate
};
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
+ void Q_QML_EXPORT qmlunregister(RegistrationType, quintptr);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlpropertycachecreator.cpp b/src/qml/qml/qqmlpropertycachecreator.cpp
index bd4f2a0612..034ebfc743 100644
--- a/src/qml/qml/qqmlpropertycachecreator.cpp
+++ b/src/qml/qml/qqmlpropertycachecreator.cpp
@@ -45,6 +45,35 @@ QT_BEGIN_NAMESPACE
QAtomicInt QQmlPropertyCacheCreatorBase::classIndexCounter(0);
+
+int QQmlPropertyCacheCreatorBase::metaTypeForPropertyType(QV4::CompiledData::BuiltinType type)
+{
+ switch (type) {
+ case QV4::CompiledData::BuiltinType::Var: return QMetaType::QVariant;
+ case QV4::CompiledData::BuiltinType::Variant: return QMetaType::QVariant;
+ case QV4::CompiledData::BuiltinType::Int: return QMetaType::Int;
+ case QV4::CompiledData::BuiltinType::Bool: return QMetaType::Bool;
+ case QV4::CompiledData::BuiltinType::Real: return QMetaType::Double;
+ case QV4::CompiledData::BuiltinType::String: return QMetaType::QString;
+ case QV4::CompiledData::BuiltinType::Url: return QMetaType::QUrl;
+ case QV4::CompiledData::BuiltinType::Color: return QMetaType::QColor;
+ case QV4::CompiledData::BuiltinType::Font: return QMetaType::QFont;
+ case QV4::CompiledData::BuiltinType::Time: return QMetaType::QTime;
+ case QV4::CompiledData::BuiltinType::Date: return QMetaType::QDate;
+ case QV4::CompiledData::BuiltinType::DateTime: return QMetaType::QDateTime;
+ case QV4::CompiledData::BuiltinType::Rect: return QMetaType::QRectF;
+ case QV4::CompiledData::BuiltinType::Point: return QMetaType::QPointF;
+ case QV4::CompiledData::BuiltinType::Size: return QMetaType::QSizeF;
+ case QV4::CompiledData::BuiltinType::Vector2D: return QMetaType::QVector2D;
+ case QV4::CompiledData::BuiltinType::Vector3D: return QMetaType::QVector3D;
+ case QV4::CompiledData::BuiltinType::Vector4D: return QMetaType::QVector4D;
+ case QV4::CompiledData::BuiltinType::Matrix4x4: return QMetaType::QMatrix4x4;
+ case QV4::CompiledData::BuiltinType::Quaternion: return QMetaType::QQuaternion;
+ case QV4::CompiledData::BuiltinType::InvalidBuiltin: break;
+ };
+ return QMetaType::UnknownType;
+}
+
QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
const QString &instantiatingPropertyName, QQmlPropertyCache *referencingObjectPropertyCache)
: referencingObjectIndex(referencingObjectIndex)
diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h
index 28eea27675..14f734277d 100644
--- a/src/qml/qml/qqmlpropertycachecreator_p.h
+++ b/src/qml/qml/qqmlpropertycachecreator_p.h
@@ -84,6 +84,8 @@ struct QQmlPropertyCacheCreatorBase
Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreatorBase)
public:
static QAtomicInt classIndexCounter;
+
+ static int metaTypeForPropertyType(QV4::CompiledData::BuiltinType type);
};
template <typename ObjectContainer>
@@ -97,12 +99,12 @@ public:
QQmlEnginePrivate *enginePrivate,
const ObjectContainer *objectContainer, const QQmlImports *imports);
- QQmlCompileError buildMetaObjects();
+ QQmlJS::DiagnosticMessage buildMetaObjects();
protected:
- QQmlCompileError buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context);
- QQmlRefPointer<QQmlPropertyCache> propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlCompileError *error) const;
- QQmlCompileError createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache);
+ QQmlJS::DiagnosticMessage buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context);
+ QQmlRefPointer<QQmlPropertyCache> propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlJS::DiagnosticMessage *error) const;
+ QQmlJS::DiagnosticMessage createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache);
QString stringAt(int index) const { return objectContainer->stringAt(index); }
@@ -128,14 +130,14 @@ inline QQmlPropertyCacheCreator<ObjectContainer>::QQmlPropertyCacheCreator(QQmlP
}
template <typename ObjectContainer>
-inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects()
+inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjects()
{
QQmlBindingInstantiationContext context;
return buildMetaObjectRecursively(/*root object*/0, context);
}
template <typename ObjectContainer>
-inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context)
+inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObjectRecursively(int objectIndex, const QQmlBindingInstantiationContext &context)
{
const CompiledObject *obj = objectContainer->objectAt(objectIndex);
@@ -155,8 +157,8 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObje
auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
QQmlRefPointer<QQmlPropertyCache> baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
- QQmlCompileError error = createMetaObject(context.referencingObjectIndex, obj, baseTypeCache);
- if (error.isSet())
+ QQmlJS::DiagnosticMessage error = createMetaObject(context.referencingObjectIndex, obj, baseTypeCache);
+ if (error.isValid())
return error;
}
} else {
@@ -170,16 +172,16 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObje
QQmlRefPointer<QQmlPropertyCache> baseTypeCache;
{
- QQmlCompileError error;
+ QQmlJS::DiagnosticMessage error;
baseTypeCache = propertyCacheForObject(obj, context, &error);
- if (error.isSet())
+ if (error.isValid())
return error;
}
if (baseTypeCache) {
if (needVMEMetaObject) {
- QQmlCompileError error = createMetaObject(objectIndex, obj, baseTypeCache);
- if (error.isSet())
+ QQmlJS::DiagnosticMessage error = createMetaObject(objectIndex, obj, baseTypeCache);
+ if (error.isValid())
return error;
} else {
propertyCaches->set(objectIndex, baseTypeCache);
@@ -200,18 +202,18 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObje
if (!context.resolveInstantiatingProperty())
pendingGroupPropertyBindings->append(context);
- QQmlCompileError error = buildMetaObjectRecursively(binding->value.objectIndex, context);
- if (error.isSet())
+ QQmlJS::DiagnosticMessage error = buildMetaObjectRecursively(binding->value.objectIndex, context);
+ if (error.isValid())
return error;
}
}
- QQmlCompileError noError;
+ QQmlJS::DiagnosticMessage noError;
return noError;
}
template <typename ObjectContainer>
-inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlCompileError *error) const
+inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContainer>::propertyCacheForObject(const CompiledObject *obj, const QQmlBindingInstantiationContext &context, QQmlJS::DiagnosticMessage *error) const
{
if (context.instantiatingProperty) {
return context.instantiatingPropertyCache(enginePrivate);
@@ -221,15 +223,15 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
if (typeRef->isFullyDynamicType) {
if (obj->propertyCount() > 0 || obj->aliasCount() > 0) {
- *error = QQmlCompileError(obj->location, QQmlPropertyCacheCreatorBase::tr("Fully dynamic types cannot declare new properties."));
+ *error = qQmlCompileError(obj->location, QQmlPropertyCacheCreatorBase::tr("Fully dynamic types cannot declare new properties."));
return nullptr;
}
if (obj->signalCount() > 0) {
- *error = QQmlCompileError(obj->location, QQmlPropertyCacheCreatorBase::tr("Fully dynamic types cannot declare new signals."));
+ *error = qQmlCompileError(obj->location, QQmlPropertyCacheCreatorBase::tr("Fully dynamic types cannot declare new signals."));
return nullptr;
}
if (obj->functionCount() > 0) {
- *error = QQmlCompileError(obj->location, QQmlPropertyCacheCreatorBase::tr("Fully Dynamic types cannot declare new functions."));
+ *error = qQmlCompileError(obj->location, QQmlPropertyCacheCreatorBase::tr("Fully Dynamic types cannot declare new functions."));
return nullptr;
}
}
@@ -256,7 +258,7 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
const QMetaObject *attachedMo = qmltype.attachedPropertiesType(enginePrivate);
if (!attachedMo) {
- *error = QQmlCompileError(context.instantiatingBinding->location, QQmlPropertyCacheCreatorBase::tr("Non-existent attached object"));
+ *error = qQmlCompileError(context.instantiatingBinding->location, QQmlPropertyCacheCreatorBase::tr("Non-existent attached object"));
return nullptr;
}
return enginePrivate->cache(attachedMo);
@@ -265,7 +267,7 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
}
template <typename ObjectContainer>
-inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache)
+inline QQmlJS::DiagnosticMessage QQmlPropertyCacheCreator<ObjectContainer>::createMetaObject(int objectIndex, const CompiledObject *obj, const QQmlRefPointer<QQmlPropertyCache> &baseTypeCache)
{
QQmlRefPointer<QQmlPropertyCache> cache;
cache.adopt(baseTypeCache->copyAndReserve(obj->propertyCount() + obj->aliasCount(),
@@ -275,33 +277,6 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
propertyCaches->set(objectIndex, cache);
propertyCaches->setNeedsVMEMetaObject(objectIndex);
- struct TypeData {
- QV4::CompiledData::Property::Type dtype;
- int metaType;
- } builtinTypes[] = {
- { QV4::CompiledData::Property::Var, QMetaType::QVariant },
- { QV4::CompiledData::Property::Variant, QMetaType::QVariant },
- { QV4::CompiledData::Property::Int, QMetaType::Int },
- { QV4::CompiledData::Property::Bool, QMetaType::Bool },
- { QV4::CompiledData::Property::Real, QMetaType::Double },
- { QV4::CompiledData::Property::String, QMetaType::QString },
- { QV4::CompiledData::Property::Url, QMetaType::QUrl },
- { QV4::CompiledData::Property::Color, QMetaType::QColor },
- { QV4::CompiledData::Property::Font, QMetaType::QFont },
- { QV4::CompiledData::Property::Time, QMetaType::QTime },
- { QV4::CompiledData::Property::Date, QMetaType::QDate },
- { QV4::CompiledData::Property::DateTime, QMetaType::QDateTime },
- { QV4::CompiledData::Property::Rect, QMetaType::QRectF },
- { QV4::CompiledData::Property::Point, QMetaType::QPointF },
- { QV4::CompiledData::Property::Size, QMetaType::QSizeF },
- { QV4::CompiledData::Property::Vector2D, QMetaType::QVector2D },
- { QV4::CompiledData::Property::Vector3D, QMetaType::QVector3D },
- { QV4::CompiledData::Property::Vector4D, QMetaType::QVector4D },
- { QV4::CompiledData::Property::Matrix4x4, QMetaType::QMatrix4x4 },
- { QV4::CompiledData::Property::Quaternion, QMetaType::QQuaternion }
-};
- static const uint builtinTypeCount = sizeof(builtinTypes) / sizeof(TypeData);
-
QByteArray newClassName;
if (objectIndex == /*root object*/0) {
@@ -329,13 +304,13 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
auto p = obj->propertiesBegin();
auto pend = obj->propertiesEnd();
for ( ; p != pend; ++p) {
- if (p->type == QV4::CompiledData::Property::Var)
+ if (p->builtinType() == QV4::CompiledData::BuiltinType::Var)
varPropCount++;
bool notInRevision = false;
QQmlPropertyData *d = resolver.property(stringAt(p->nameIndex), &notInRevision);
if (d && d->isFinal())
- return QQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Cannot override FINAL property"));
+ return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Cannot override FINAL property"));
}
auto a = obj->aliasesBegin();
@@ -344,7 +319,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
bool notInRevision = false;
QQmlPropertyData *d = resolver.property(stringAt(a->nameIndex), &notInRevision);
if (d && d->isFinal())
- return QQmlCompileError(a->location, QQmlPropertyCacheCreatorBase::tr("Cannot override FINAL property"));
+ return qQmlCompileError(a->location, QQmlPropertyCacheCreatorBase::tr("Cannot override FINAL property"));
}
int effectivePropertyIndex = cache->propertyIndexCacheStart;
@@ -429,16 +404,15 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
auto end = s->parametersEnd();
for ( ; param != end; ++param, ++i) {
names.append(stringAt(param->nameIndex).toUtf8());
- if (param->type < builtinTypeCount) {
+ if (param->indexIsBuiltinType) {
// built-in type
- paramTypes[i + 1] = builtinTypes[param->type].metaType;
+ paramTypes[i + 1] = metaTypeForPropertyType(static_cast<QV4::CompiledData::BuiltinType>(int(param->typeNameIndexOrBuiltinType)));
} else {
// lazily resolved type
- Q_ASSERT(param->type == QV4::CompiledData::Property::Custom);
- const QString customTypeName = stringAt(param->customTypeNameIndex);
+ const QString customTypeName = stringAt(param->typeNameIndexOrBuiltinType);
QQmlType qmltype;
if (!imports->resolveType(customTypeName, &qmltype, nullptr, nullptr, nullptr))
- return QQmlCompileError(s->location, QQmlPropertyCacheCreatorBase::tr("Invalid signal parameter type: %1").arg(customTypeName));
+ return qQmlCompileError(s->location, QQmlPropertyCacheCreatorBase::tr("Invalid signal parameter type: %1").arg(customTypeName));
if (qmltype.isComposite()) {
QQmlRefPointer<QQmlTypeData> tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl());
@@ -461,7 +435,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
QString signalName = stringAt(s->nameIndex);
if (seenSignals.contains(signalName))
- return QQmlCompileError(s->location, QQmlPropertyCacheCreatorBase::tr("Duplicate signal name: invalid override of property change signal or superclass signal"));
+ return qQmlCompileError(s->location, QQmlPropertyCacheCreatorBase::tr("Duplicate signal name: invalid override of property change signal or superclass signal"));
seenSignals.insert(signalName);
cache->appendSignal(signalName, flags, effectiveMethodIndex++,
@@ -477,7 +451,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
const QString slotName = stringAt(function->nameIndex);
if (seenSignals.contains(slotName))
- return QQmlCompileError(function->location, QQmlPropertyCacheCreatorBase::tr("Duplicate method name: invalid override of property change signal or superclass signal"));
+ return qQmlCompileError(function->location, QQmlPropertyCacheCreatorBase::tr("Duplicate method name: invalid override of property change signal or superclass signal"));
// Note: we don't append slotName to the seenSignals list, since we don't
// protect against overriding change signals or methods with properties.
@@ -503,21 +477,23 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
int propertTypeMinorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
- if (p->type == QV4::CompiledData::Property::Var) {
- propertyType = QMetaType::QVariant;
+ const QV4::CompiledData::BuiltinType type = p->builtinType();
+
+ if (type == QV4::CompiledData::BuiltinType::Var)
propertyFlags.type = QQmlPropertyData::Flags::VarPropertyType;
- } else if (p->type < builtinTypeCount) {
- propertyType = builtinTypes[p->type].metaType;
- if (p->type == QV4::CompiledData::Property::Variant)
+
+ if (type != QV4::CompiledData::BuiltinType::InvalidBuiltin) {
+ propertyType = metaTypeForPropertyType(type);
+
+ if (type == QV4::CompiledData::BuiltinType::Variant)
propertyFlags.type = QQmlPropertyData::Flags::QVariantType;
} else {
- Q_ASSERT(p->type == QV4::CompiledData::Property::CustomList ||
- p->type == QV4::CompiledData::Property::Custom);
+ Q_ASSERT(!p->isBuiltinType);
QQmlType qmltype;
- if (!imports->resolveType(stringAt(p->customTypeNameIndex), &qmltype, nullptr, nullptr, nullptr)) {
- return QQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type"));
+ if (!imports->resolveType(stringAt(p->builtinTypeOrTypeNameIndex), &qmltype, nullptr, nullptr, nullptr)) {
+ return qQmlCompileError(p->location, QQmlPropertyCacheCreatorBase::tr("Invalid property type"));
}
Q_ASSERT(qmltype.isValid());
@@ -528,27 +504,27 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
auto compilationUnit = tdata->compilationUnit();
- if (p->type == QV4::CompiledData::Property::Custom) {
- propertyType = compilationUnit->metaTypeId;
- } else {
+ if (p->isList) {
propertyType = compilationUnit->listMetaTypeId;
+ } else {
+ propertyType = compilationUnit->metaTypeId;
}
} else {
- if (p->type == QV4::CompiledData::Property::Custom) {
+ if (p->isList) {
+ propertyType = qmltype.qListTypeId();
+ } else {
propertyType = qmltype.typeId();
propertTypeMinorVersion = qmltype.minorVersion();
- } else {
- propertyType = qmltype.qListTypeId();
}
}
- if (p->type == QV4::CompiledData::Property::Custom)
- propertyFlags.type = QQmlPropertyData::Flags::QObjectDerivedType;
- else
+ if (p->isList)
propertyFlags.type = QQmlPropertyData::Flags::QListType;
+ else
+ propertyFlags.type = QQmlPropertyData::Flags::QObjectDerivedType;
}
- if (!(p->flags & QV4::CompiledData::Property::IsReadOnly) && p->type != QV4::CompiledData::Property::CustomList)
+ if (!p->isReadOnly && !p->isList)
propertyFlags.isWritable = true;
@@ -561,7 +537,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
effectiveSignalIndex++;
}
- QQmlCompileError noError;
+ QQmlJS::DiagnosticMessage noError;
return noError;
}
@@ -575,11 +551,11 @@ public:
void appendAliasPropertiesToMetaObjects();
- QQmlCompileError appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex);
+ QQmlJS::DiagnosticMessage appendAliasesToPropertyCache(const CompiledObject &component, int objectIndex);
private:
void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex);
- QQmlCompileError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags);
+ QQmlJS::DiagnosticMessage propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyData::Flags *propertyFlags);
void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const;
@@ -690,7 +666,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl
}
template <typename ObjectContainer>
-inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(
+inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(
const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion,
QQmlPropertyData::Flags *propertyFlags)
{
@@ -716,7 +692,7 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property
const QV4::CompiledData::Alias *targetAlias = &(*nextAlias);
if (seenAliases.contains(targetAlias)) {
- return QQmlCompileError(targetAlias->location,
+ return qQmlCompileError(targetAlias->location,
QQmlPropertyCacheCreatorBase::tr("Cyclic alias"));
}
@@ -738,7 +714,8 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property
// Can be caused by the alias target not being a valid id or property. E.g.:
// property alias dataValue: dataVal
// invalidAliasComponent { id: dataVal }
- return QQmlCompileError(targetObject.location, QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
+ return qQmlCompileError(targetObject.location,
+ QQmlPropertyCacheCreatorBase::tr("Invalid alias target"));
}
if (typeRef->type.isValid())
@@ -782,18 +759,18 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property
}
}
- propertyFlags->isWritable = !(alias.flags & QV4::CompiledData::Property::IsReadOnly) && writable;
+ propertyFlags->isWritable = !(alias.flags & QV4::CompiledData::Alias::IsReadOnly) && writable;
propertyFlags->isResettable = resettable;
- return QQmlCompileError();
+ return QQmlJS::DiagnosticMessage();
}
template <typename ObjectContainer>
-inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache(
+inline QQmlJS::DiagnosticMessage QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAliasesToPropertyCache(
const CompiledObject &component, int objectIndex)
{
const CompiledObject &object = *objectContainer->objectAt(objectIndex);
if (!object.aliasCount())
- return QQmlCompileError();
+ return QQmlJS::DiagnosticMessage();
QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex);
Q_ASSERT(propertyCache);
@@ -810,8 +787,8 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAl
int type = 0;
int minorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
- QQmlCompileError error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags);
- if (error.isSet())
+ QQmlJS::DiagnosticMessage error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags);
+ if (error.isValid())
return error;
const QString propertyName = objectContainer->stringAt(alias->nameIndex);
@@ -823,7 +800,7 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAl
type, minorVersion, effectiveSignalIndex++);
}
- return QQmlCompileError();
+ return QQmlJS::DiagnosticMessage();
}
template <typename ObjectContainer>
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index 71d5318652..6bb00e438d 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -57,7 +57,7 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, c
bindingPropertyDataPerObject->resize(compilationUnit->objectCount());
}
-QVector<QQmlCompileError> QQmlPropertyValidator::validate()
+QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validate()
{
return validateObject(/*root object*/0, /*instantiatingBinding*/nullptr);
}
@@ -80,7 +80,8 @@ struct BindingFinder
}
};
-QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty) const
+QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::validateObject(
+ int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty) const
{
const QV4::CompiledData::Object *obj = compilationUnit->objectAt(objectIndex);
@@ -93,7 +94,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex);
if (!propertyCache)
- return QVector<QQmlCompileError>();
+ return QVector<QQmlJS::DiagnosticMessage>();
QQmlCustomParser *customParser = nullptr;
if (auto typeRef = resolvedType(obj->inheritedTypeNameIndex)) {
@@ -203,7 +204,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
= pd
&& QQmlValueTypeFactory::metaObjectForMetaType(pd->propType())
&& !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment);
- const QVector<QQmlCompileError> subObjectValidatorErrors
+ const QVector<QQmlJS::DiagnosticMessage> subObjectValidatorErrors
= validateObject(binding->value.objectIndex, binding,
populatingValueTypeGroupProperty);
if (!subObjectValidatorErrors.isEmpty())
@@ -260,12 +261,12 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
}
if (binding->type < QV4::CompiledData::Binding::Type_Script) {
- QQmlCompileError bindingError = validateLiteralBinding(propertyCache, pd, binding);
- if (bindingError.isSet())
+ QQmlJS::DiagnosticMessage bindingError = validateLiteralBinding(propertyCache, pd, binding);
+ if (bindingError.isValid())
return recordError(bindingError);
} else if (binding->type == QV4::CompiledData::Binding::Type_Object) {
- QQmlCompileError bindingError = validateObjectBinding(pd, name, binding);
- if (bindingError.isSet())
+ QQmlJS::DiagnosticMessage bindingError = validateObjectBinding(pd, name, binding);
+ if (bindingError.isValid())
return recordError(bindingError);
} else if (binding->isGroupProperty()) {
if (QQmlValueTypeFactory::isValueType(pd->propType())) {
@@ -316,24 +317,24 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
customParser->validator = nullptr;
customParser->engine = nullptr;
customParser->imports = (QQmlImports*)nullptr;
- QVector<QQmlCompileError> parserErrors = customParser->errors();
+ QVector<QQmlJS::DiagnosticMessage> parserErrors = customParser->errors();
if (!parserErrors.isEmpty())
return parserErrors;
}
(*bindingPropertyDataPerObject)[objectIndex] = collectedBindingPropertyData;
- QVector<QQmlCompileError> noError;
+ QVector<QQmlJS::DiagnosticMessage> noError;
return noError;
}
-QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const
+QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const
{
if (property->isQList()) {
- return QQmlCompileError(binding->valueLocation, tr("Cannot assign primitives to lists"));
+ return qQmlCompileError(binding->valueLocation, tr("Cannot assign primitives to lists"));
}
- QQmlCompileError noError;
+ QQmlJS::DiagnosticMessage noError;
if (property->isEnum()) {
if (binding->flags & QV4::CompiledData::Binding::IsResolvedEnum)
@@ -348,7 +349,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache
p.enumerator().keyToValue(value.toUtf8().constData(), &ok);
if (!ok) {
- return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: unknown enumeration"));
+ return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: unknown enumeration"));
}
return noError;
}
@@ -365,7 +366,7 @@ QQmlCompileError QQmlPropertyValidator::validateLiteralBinding(QQmlPropertyCache
enginePrivate->warning(warning);
return noError;
}
- return QQmlCompileError(binding->valueLocation, error);
+ return qQmlCompileError(binding->valueLocation, error);
};
switch (property->propType()) {
@@ -629,23 +630,23 @@ bool QQmlPropertyValidator::canCoerce(int to, QQmlPropertyCache *fromMo) const
return false;
}
-QVector<QQmlCompileError> QQmlPropertyValidator::recordError(const QV4::CompiledData::Location &location, const QString &description) const
+QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::recordError(const QV4::CompiledData::Location &location, const QString &description) const
{
- QVector<QQmlCompileError> errors;
- errors.append(QQmlCompileError(location, description));
+ QVector<QQmlJS::DiagnosticMessage> errors;
+ errors.append(qQmlCompileError(location, description));
return errors;
}
-QVector<QQmlCompileError> QQmlPropertyValidator::recordError(const QQmlCompileError &error) const
+QVector<QQmlJS::DiagnosticMessage> QQmlPropertyValidator::recordError(const QQmlJS::DiagnosticMessage &error) const
{
- QVector<QQmlCompileError> errors;
+ QVector<QQmlJS::DiagnosticMessage> errors;
errors.append(error);
return errors;
}
-QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const
+QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const
{
- QQmlCompileError noError;
+ QQmlJS::DiagnosticMessage noError;
if (binding->flags & QV4::CompiledData::Binding::IsOnAssignment) {
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Object);
@@ -669,7 +670,7 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
}
if (!isValueSource && !isPropertyInterceptor) {
- return QQmlCompileError(binding->valueLocation, tr("\"%1\" cannot operate on \"%2\"").arg(stringAt(targetObject->inheritedTypeNameIndex)).arg(propertyName));
+ return qQmlCompileError(binding->valueLocation, tr("\"%1\" cannot operate on \"%2\"").arg(stringAt(targetObject->inheritedTypeNameIndex)).arg(propertyName));
}
return noError;
@@ -687,7 +688,7 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
if (!QQmlMetaType::isInterface(listType)) {
QQmlPropertyCache *source = propertyCaches.at(binding->value.objectIndex);
if (!canCoerce(listType, source)) {
- return QQmlCompileError(binding->valueLocation, tr("Cannot assign object to list property \"%1\"").arg(propertyName));
+ return qQmlCompileError(binding->valueLocation, tr("Cannot assign object to list property \"%1\"").arg(propertyName));
}
}
return noError;
@@ -695,11 +696,11 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
return noError;
} else if (QQmlValueTypeFactory::isValueType(property->propType())) {
auto typeName = QMetaType::typeName(property->propType());
- return QQmlCompileError(binding->location, tr("Can not assign value of type \"%1\" to property \"%2\", expecting an object")
+ return qQmlCompileError(binding->location, tr("Can not assign value of type \"%1\" to property \"%2\", expecting an object")
.arg(typeName ? QString::fromLatin1(typeName) : QString::fromLatin1("<unknown type>"))
.arg(propertyName));
} else if (property->propType() == qMetaTypeId<QQmlScriptString>()) {
- return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected"));
+ return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected"));
} else {
// We want to use the raw metaObject here as the raw metaobject is the
// actual property type before we applied any extensions that might
@@ -719,7 +720,7 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
}
if (!isAssignable) {
- return QQmlCompileError(binding->valueLocation, tr("Cannot assign object of type \"%1\" to property of type \"%2\" as the former is neither the same as the latter nor a sub-class of it.")
+ return qQmlCompileError(binding->valueLocation, tr("Cannot assign object of type \"%1\" to property of type \"%2\" as the former is neither the same as the latter nor a sub-class of it.")
.arg(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex)).arg(QLatin1String(QMetaType::typeName(property->propType()))));
}
}
diff --git a/src/qml/qml/qqmlpropertyvalidator_p.h b/src/qml/qml/qqmlpropertyvalidator_p.h
index 8244b2df21..f2b892e978 100644
--- a/src/qml/qml/qqmlpropertyvalidator_p.h
+++ b/src/qml/qml/qqmlpropertyvalidator_p.h
@@ -60,17 +60,25 @@ class QQmlPropertyValidator
public:
QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, const QQmlImports &imports, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit);
- QVector<QQmlCompileError> validate();
+ QVector<QQmlJS::DiagnosticMessage> validate();
private:
- QVector<QQmlCompileError> validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty = false) const;
- QQmlCompileError validateLiteralBinding(QQmlPropertyCache *propertyCache, QQmlPropertyData *property, const QV4::CompiledData::Binding *binding) const;
- QQmlCompileError validateObjectBinding(QQmlPropertyData *property, const QString &propertyName, const QV4::CompiledData::Binding *binding) const;
+ QVector<QQmlJS::DiagnosticMessage> validateObject(
+ int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding,
+ bool populatingValueTypeGroupProperty = false) const;
+ QQmlJS::DiagnosticMessage validateLiteralBinding(
+ QQmlPropertyCache *propertyCache, QQmlPropertyData *property,
+ const QV4::CompiledData::Binding *binding) const;
+ QQmlJS::DiagnosticMessage validateObjectBinding(
+ QQmlPropertyData *property, const QString &propertyName,
+ const QV4::CompiledData::Binding *binding) const;
bool canCoerce(int to, QQmlPropertyCache *fromMo) const;
- Q_REQUIRED_RESULT QVector<QQmlCompileError> recordError(const QV4::CompiledData::Location &location, const QString &description) const;
- Q_REQUIRED_RESULT QVector<QQmlCompileError> recordError(const QQmlCompileError &error) const;
+ Q_REQUIRED_RESULT QVector<QQmlJS::DiagnosticMessage> recordError(
+ const QV4::CompiledData::Location &location, const QString &description) const;
+ Q_REQUIRED_RESULT QVector<QQmlJS::DiagnosticMessage> recordError(
+ const QQmlJS::DiagnosticMessage &error) const;
QString stringAt(int index) const { return compilationUnit->stringAt(index); }
QV4::ResolvedTypeReference *resolvedType(int id) const
{
diff --git a/src/qml/qml/qqmlsourcecoordinate_p.h b/src/qml/qml/qqmlsourcecoordinate_p.h
new file mode 100644
index 0000000000..55e11fd147
--- /dev/null
+++ b/src/qml/qml/qqmlsourcecoordinate_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLSOURCECOORDINATE_P_H
+#define QQMLSOURCECOORDINATE_P_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 <QtCore/qglobal.h>
+
+#include <limits>
+
+QT_BEGIN_NAMESPACE
+
+// These methods are needed because in some public methods we historically interpret -1 as the
+// invalid line or column, even though all the lines and columns are 1-based. Also, the different
+// integer ranges may turn certain large values into invalid ones on conversion.
+
+template<typename From, typename To>
+To qmlConvertSourceCoordinate(From n);
+
+template<>
+inline quint16 qmlConvertSourceCoordinate<int, quint16>(int n)
+{
+ return (n > 0 && n <= int(std::numeric_limits<quint16>::max())) ? quint16(n) : 0;
+}
+
+template<>
+inline quint32 qmlConvertSourceCoordinate<int, quint32>(int n)
+{
+ return n > 0 ? quint32(n) : 0u;
+}
+
+// TODO: In Qt6, change behavior and make the invalid coordinate 0 for the following two methods.
+
+template<>
+inline int qmlConvertSourceCoordinate<quint16, int>(quint16 n)
+{
+ return (n == 0u) ? -1 : int(n);
+}
+
+template<>
+inline int qmlConvertSourceCoordinate<quint32, int>(quint32 n)
+{
+ return (n == 0u || n > quint32(std::numeric_limits<int>::max())) ? -1 : int(n);
+}
+
+QT_END_NAMESPACE
+
+#endif // QQMLSOURCECOORDINATE_P_H
diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h
index 1d65a08c8f..158fefad2c 100644
--- a/src/qml/qml/qqmltype_p.h
+++ b/src/qml/qml/qqmltype_p.h
@@ -51,6 +51,8 @@
// We mean it.
//
+#include <functional>
+
#include <private/qtqmlglobal_p.h>
#include <private/qqmlrefcount_p.h>
@@ -145,7 +147,7 @@ public:
struct Q_QML_PRIVATE_EXPORT SingletonInstanceInfo
{
QJSValue (*scriptCallback)(QQmlEngine *, QJSEngine *) = nullptr;
- QObject *(*qobjectCallback)(QQmlEngine *, QJSEngine *) = nullptr;
+ std::function<QObject *(QQmlEngine *, QJSEngine *)> qobjectCallback = {};
const QMetaObject *instanceMetaObject = nullptr;
QString typeName;
QUrl url; // used by composite singletons
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index 66320b8db9..6cbe81b4b8 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -83,8 +83,8 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
{
QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, &pendingGroupPropertyBindings,
engine, this, imports());
- QQmlCompileError error = propertyCacheBuilder.buildMetaObjects();
- if (error.isSet()) {
+ QQmlJS::DiagnosticMessage error = propertyCacheBuilder.buildMetaObjects();
+ if (error.isValid()) {
recordError(error);
return nullptr;
}
@@ -173,12 +173,6 @@ QQmlRefPointer<QV4::ExecutableCompilationUnit> QQmlTypeCompiler::compile()
return nullptr;
}
-void QQmlTypeCompiler::recordError(QQmlError error)
-{
- error.setUrl(url());
- errors << error;
-}
-
void QQmlTypeCompiler::recordError(const QV4::CompiledData::Location &location, const QString &description)
{
QQmlError error;
@@ -189,9 +183,14 @@ void QQmlTypeCompiler::recordError(const QV4::CompiledData::Location &location,
errors << error;
}
-void QQmlTypeCompiler::recordError(const QQmlCompileError &error)
+void QQmlTypeCompiler::recordError(const QQmlJS::DiagnosticMessage &message)
{
- recordError(error.location, error.description);
+ QQmlError error;
+ error.setDescription(message.message);
+ error.setLine(message.line);
+ error.setColumn(message.column);
+ error.setUrl(url());
+ errors << error;
}
QString QQmlTypeCompiler::stringAt(int idx) const
@@ -1020,17 +1019,17 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
for (int objectIndex: qAsConst(_objectsWithAliases)) {
- QQmlCompileError error;
+ QQmlJS::DiagnosticMessage error;
const auto result = resolveAliasesInObject(objectIndex, &error);
- if (error.isSet()) {
+ if (error.isValid()) {
recordError(error);
return false;
}
if (result == AllAliasesResolved) {
- QQmlCompileError error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex);
- if (error.isSet()) {
+ QQmlJS::DiagnosticMessage error = aliasCacheCreator.appendAliasesToPropertyCache(*qmlObjects->at(componentIndex), objectIndex);
+ if (error.isValid()) {
recordError(error);
return false;
}
@@ -1058,7 +1057,9 @@ bool QQmlComponentAndAliasResolver::resolveAliases(int componentIndex)
return true;
}
-QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex, QQmlCompileError *error)
+QQmlComponentAndAliasResolver::AliasResolutionResult
+QQmlComponentAndAliasResolver::resolveAliasesInObject(int objectIndex,
+ QQmlJS::DiagnosticMessage *error)
{
const QmlIR::Object * const obj = qmlObjects->at(objectIndex);
if (!obj->aliasCount())
@@ -1076,7 +1077,9 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
const int idIndex = alias->idIndex;
const int targetObjectIndex = _idToObjectIndex.value(idIndex, -1);
if (targetObjectIndex == -1) {
- *error = QQmlCompileError(alias->referenceLocation, tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex)));
+ *error = qQmlCompileError(
+ alias->referenceLocation,
+ tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex)));
break;
}
@@ -1104,7 +1107,9 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
} else {
QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex);
if (!targetCache) {
- *error = QQmlCompileError(alias->referenceLocation, tr("Invalid alias target location: %1").arg(property.toString()));
+ *error = qQmlCompileError(
+ alias->referenceLocation,
+ tr("Invalid alias target location: %1").arg(property.toString()));
break;
}
@@ -1139,7 +1144,9 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
}
if (!targetProperty || targetProperty->coreIndex() > 0x0000FFFF) {
- *error = QQmlCompileError(alias->referenceLocation, tr("Invalid alias target location: %1").arg(property.toString()));
+ *error = qQmlCompileError(
+ alias->referenceLocation,
+ tr("Invalid alias target location: %1").arg(property.toString()));
break;
}
@@ -1148,14 +1155,18 @@ QQmlComponentAndAliasResolver::AliasResolutionResult QQmlComponentAndAliasResolv
if (!subProperty.isEmpty()) {
const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(targetProperty->propType());
if (!valueTypeMetaObject) {
- *error = QQmlCompileError(alias->referenceLocation, tr("Invalid alias target location: %1").arg(subProperty.toString()));
+ *error = qQmlCompileError(
+ alias->referenceLocation,
+ tr("Invalid alias target location: %1").arg(subProperty.toString()));
break;
}
int valueTypeIndex =
valueTypeMetaObject->indexOfProperty(subProperty.toString().toUtf8().constData());
if (valueTypeIndex == -1) {
- *error = QQmlCompileError(alias->referenceLocation, tr("Invalid alias target location: %1").arg(subProperty.toString()));
+ *error = qQmlCompileError(
+ alias->referenceLocation,
+ tr("Invalid alias target location: %1").arg(subProperty.toString()));
break;
}
Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
@@ -1345,10 +1356,8 @@ bool QQmlJSCodeGenerator::compileJavaScriptCodeInObjectsRecursively(int objectIn
for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next)
functionsToCompile << *foe;
const QVector<int> runtimeFunctionIndices = v4CodeGen->generateJSCodeForFunctionsAndBindings(functionsToCompile);
- const QList<QQmlError> jsErrors = v4CodeGen->qmlErrors();
- if (!jsErrors.isEmpty()) {
- for (const QQmlError &e : jsErrors)
- compiler->recordError(e);
+ if (v4CodeGen->hasError()) {
+ compiler->recordError(v4CodeGen->error());
return false;
}
diff --git a/src/qml/qml/qqmltypecompiler_p.h b/src/qml/qml/qqmltypecompiler_p.h
index f588909c42..615694d4bc 100644
--- a/src/qml/qml/qqmltypecompiler_p.h
+++ b/src/qml/qml/qqmltypecompiler_p.h
@@ -97,9 +97,8 @@ public:
QQmlRefPointer<QV4::ExecutableCompilationUnit> compile();
QList<QQmlError> compilationErrors() const { return errors; }
- void recordError(QQmlError error);
void recordError(const QV4::CompiledData::Location &location, const QString &description);
- void recordError(const QQmlCompileError &error);
+ void recordError(const QQmlJS::DiagnosticMessage &error);
int registerString(const QString &str);
int registerConstant(QV4::ReturnedValue v);
@@ -153,7 +152,7 @@ struct QQmlCompilePass
protected:
void recordError(const QV4::CompiledData::Location &location, const QString &description) const
{ compiler->recordError(location, description); }
- void recordError(const QQmlCompileError &error)
+ void recordError(const QQmlJS::DiagnosticMessage &error)
{ compiler->recordError(error); }
QV4::ResolvedTypeReference *resolvedType(int id) const
@@ -276,7 +275,7 @@ protected:
AllAliasesResolved
};
- AliasResolutionResult resolveAliasesInObject(int objectIndex, QQmlCompileError *error);
+ AliasResolutionResult resolveAliasesInObject(int objectIndex, QQmlJS::DiagnosticMessage *error);
QQmlEnginePrivate *enginePrivate;
QQmlJS::MemoryPool *pool;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 1022412292..0bfdbdd2fa 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -47,7 +47,6 @@
#include <private/qv4codegen_p.h>
#include <private/qqmlcomponent_p.h>
#include <private/qqmlprofiler_p.h>
-#include <private/qqmlmemoryprofiler_p.h>
#include <private/qqmltypecompiler_p.h>
#include <private/qqmlpropertyvalidator_p.h>
#include <private/qqmlpropertycachecreator_p.h>
@@ -459,25 +458,25 @@ void QQmlDataBlob::setError(const QList<QQmlError> &errors)
tryDone();
}
-void QQmlDataBlob::setError(const QQmlCompileError &error)
+void QQmlDataBlob::setError(const QQmlJS::DiagnosticMessage &error)
{
QQmlError e;
- e.setColumn(error.location.column);
- e.setLine(error.location.line);
- e.setDescription(error.description);
+ e.setColumn(error.column);
+ e.setLine(error.line);
+ e.setDescription(error.message);
e.setUrl(url());
setError(e);
}
-void QQmlDataBlob::setError(const QVector<QQmlCompileError> &errors)
+void QQmlDataBlob::setError(const QVector<QQmlJS::DiagnosticMessage> &errors)
{
QList<QQmlError> finalErrors;
finalErrors.reserve(errors.count());
- for (const QQmlCompileError &error: errors) {
+ for (const auto &error : errors) {
QQmlError e;
- e.setColumn(error.location.column);
- e.setLine(error.location.line);
- e.setDescription(error.description);
+ e.setColumn(error.column);
+ e.setLine(error.line);
+ e.setDescription(error.message);
e.setUrl(url());
finalErrors << e;
}
@@ -757,13 +756,13 @@ QQmlDataBlob::ThreadData::ThreadData()
QQmlDataBlob::Status QQmlDataBlob::ThreadData::status() const
{
- return QQmlDataBlob::Status((_p.load() & TD_STATUS_MASK) >> TD_STATUS_SHIFT);
+ return QQmlDataBlob::Status((_p.loadRelaxed() & TD_STATUS_MASK) >> TD_STATUS_SHIFT);
}
void QQmlDataBlob::ThreadData::setStatus(QQmlDataBlob::Status status)
{
while (true) {
- int d = _p.load();
+ int d = _p.loadRelaxed();
int nd = (d & ~TD_STATUS_MASK) | ((status << TD_STATUS_SHIFT) & TD_STATUS_MASK);
if (d == nd || _p.testAndSetOrdered(d, nd)) return;
}
@@ -771,13 +770,13 @@ void QQmlDataBlob::ThreadData::setStatus(QQmlDataBlob::Status status)
bool QQmlDataBlob::ThreadData::isAsync() const
{
- return _p.load() & TD_ASYNC_MASK;
+ return _p.loadRelaxed() & TD_ASYNC_MASK;
}
void QQmlDataBlob::ThreadData::setIsAsync(bool v)
{
while (true) {
- int d = _p.load();
+ int d = _p.loadRelaxed();
int nd = (d & ~TD_ASYNC_MASK) | (v?TD_ASYNC_MASK:0);
if (d == nd || _p.testAndSetOrdered(d, nd)) return;
}
@@ -785,13 +784,13 @@ void QQmlDataBlob::ThreadData::setIsAsync(bool v)
quint8 QQmlDataBlob::ThreadData::progress() const
{
- return quint8((_p.load() & TD_PROGRESS_MASK) >> TD_PROGRESS_SHIFT);
+ return quint8((_p.loadRelaxed() & TD_PROGRESS_MASK) >> TD_PROGRESS_SHIFT);
}
void QQmlDataBlob::ThreadData::setProgress(quint8 v)
{
while (true) {
- int d = _p.load();
+ int d = _p.loadRelaxed();
int nd = (d & ~TD_PROGRESS_MASK) | ((v << TD_PROGRESS_SHIFT) & TD_PROGRESS_MASK);
if (d == nd || _p.testAndSetOrdered(d, nd)) return;
}
@@ -921,7 +920,6 @@ void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::
void QQmlTypeLoaderThread::callCompletedMain(QQmlDataBlob *b)
{
- QML_MEMORY_SCOPE_URL(b->url());
#ifdef DATABLOB_DEBUG
qWarning("QQmlTypeLoaderThread: %s completed() callback", qPrintable(b->urlString()));
#endif
@@ -1147,8 +1145,6 @@ void QQmlTypeLoader::loadThread(QQmlDataBlob *blob)
return;
}
- QML_MEMORY_SCOPE_URL(blob->m_url);
-
if (QQmlFile::isSynchronous(blob->m_url)) {
const QString fileName = QQmlFile::urlToLocalFileOrQrc(blob->m_url);
if (!QQml_isFileCaseCorrect(fileName)) {
@@ -1278,7 +1274,6 @@ void QQmlTypeLoader::initializeEngine(QQmlExtensionInterface *iface,
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QByteArray &data)
{
- QML_MEMORY_SCOPE_URL(blob->url());
QQmlDataBlob::SourceCodeData d;
d.inlineSourceCode = QString::fromUtf8(data);
d.hasInlineSourceCode = true;
@@ -1287,7 +1282,6 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QByteArray &data)
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName)
{
- QML_MEMORY_SCOPE_URL(blob->url());
QQmlDataBlob::SourceCodeData d;
d.fileInfo = QFileInfo(fileName);
setData(blob, d);
@@ -1295,7 +1289,6 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName)
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeData &d)
{
- QML_MEMORY_SCOPE_URL(blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -1315,7 +1308,6 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeD
void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
- QML_MEMORY_SCOPE_URL(blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -1584,7 +1576,17 @@ bool QQmlTypeLoaderQmldirContent::hasError() const
QList<QQmlError> QQmlTypeLoaderQmldirContent::errors(const QString &uri) const
{
- return m_parser.errors(uri);
+ QList<QQmlError> errors;
+ const QUrl url(uri);
+ for (const auto parseError : m_parser.errors(uri)) {
+ QQmlError error;
+ error.setUrl(url);
+ error.setLine(parseError.line);
+ error.setColumn(parseError.column);
+ error.setDescription(parseError.message);
+ errors.append(error);
+ }
+ return errors;
}
QString QQmlTypeLoaderQmldirContent::typeNamespace() const
@@ -1601,7 +1603,11 @@ void QQmlTypeLoaderQmldirContent::setContent(const QString &location, const QStr
void QQmlTypeLoaderQmldirContent::setError(const QQmlError &error)
{
- m_parser.setError(error);
+ QQmlJS::DiagnosticMessage parseError;
+ parseError.line = error.line();
+ parseError.column = error.column();
+ parseError.message = error.description();
+ m_parser.setError(parseError);
}
QQmlDirComponents QQmlTypeLoaderQmldirContent::components() const
@@ -2248,8 +2254,8 @@ void QQmlTypeData::createTypeAndPropertyCaches(
QQmlPropertyCacheCreator<QV4::ExecutableCompilationUnit> propertyCacheCreator(
&m_compiledData->propertyCaches, &pendingGroupPropertyBindings, engine,
m_compiledData.data(), &m_importCache);
- QQmlCompileError error = propertyCacheCreator.buildMetaObjects();
- if (error.isSet()) {
+ QQmlJS::DiagnosticMessage error = propertyCacheCreator.buildMetaObjects();
+ if (error.isValid()) {
setError(error);
return;
}
@@ -2350,8 +2356,8 @@ void QQmlTypeData::done()
QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
QV4::ResolvedTypeReferenceMap resolvedTypeCache;
{
- QQmlCompileError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
- if (error.isSet()) {
+ QQmlJS::DiagnosticMessage error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
+ if (error.isValid()) {
setError(error);
return;
}
@@ -2391,7 +2397,7 @@ void QQmlTypeData::done()
{
// Sanity check property bindings
QQmlPropertyValidator validator(enginePrivate, m_importCache, m_compiledData);
- QVector<QQmlCompileError> errors = validator.validate();
+ QVector<QQmlJS::DiagnosticMessage> errors = validator.validate();
if (!errors.isEmpty()) {
setError(errors);
return;
@@ -2535,8 +2541,8 @@ bool QQmlTypeData::loadFromSource()
for (const QQmlJS::DiagnosticMessage &msg : qAsConst(compiler.errors)) {
QQmlError e;
e.setUrl(url());
- e.setLine(msg.loc.startLine);
- e.setColumn(msg.loc.startColumn);
+ e.setLine(msg.line);
+ e.setColumn(msg.column);
e.setDescription(msg.message);
errors << e;
}
@@ -2775,7 +2781,7 @@ void QQmlTypeData::resolveTypes()
loadImplicitImport();
}
-QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
+QQmlJS::DiagnosticMessage QQmlTypeData::buildTypeResolutionCaches(
QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
QV4::ResolvedTypeReferenceMap *resolvedTypeCache
) const
@@ -2798,7 +2804,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
QQmlType qmlType = resolvedType->type;
if (resolvedType->typeData) {
if (resolvedType->needsCreation && qmlType.isCompositeSingleton()) {
- return QQmlCompileError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType.qmlTypeName()));
+ return qQmlCompileError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType.qmlTypeName()));
}
ref->compilationUnit = resolvedType->typeData->compilationUnit();
} else if (qmlType.isValid()) {
@@ -2809,7 +2815,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
QString reason = ref->type.noCreationReason();
if (reason.isEmpty())
reason = tr("Element is not creatable.");
- return QQmlCompileError(resolvedType->location, reason);
+ return qQmlCompileError(resolvedType->location, reason);
}
if (ref->type.containsRevisionedAttributes()) {
@@ -2822,7 +2828,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
ref->doDynamicTypeCheck();
resolvedTypeCache->insert(resolvedType.key(), ref.take());
}
- QQmlCompileError noError;
+ QQmlJS::DiagnosticMessage noError;
return noError;
}
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index d87812d48e..3330d52e56 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -86,7 +86,6 @@ class QQmlTypeData;
class QQmlTypeLoader;
class QQmlExtensionInterface;
class QQmlProfiler;
-struct QQmlCompileError;
namespace QmlIR {
struct Document;
@@ -154,8 +153,8 @@ protected:
// Can be called from within callbacks
void setError(const QQmlError &);
void setError(const QList<QQmlError> &errors);
- void setError(const QQmlCompileError &error);
- void setError(const QVector<QQmlCompileError> &errors);
+ void setError(const QQmlJS::DiagnosticMessage &error);
+ void setError(const QVector<QQmlJS::DiagnosticMessage> &errors);
void setError(const QString &description);
void addDependency(QQmlDataBlob *);
@@ -481,7 +480,7 @@ private:
void restoreIR(QV4::CompiledData::CompilationUnit &&unit);
void continueLoadFromIR();
void resolveTypes();
- QQmlCompileError buildTypeResolutionCaches(
+ QQmlJS::DiagnosticMessage buildTypeResolutionCaches(
QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
QV4::ResolvedTypeReferenceMap *resolvedTypeCache
) const;
diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp
index 4d7553fbab..9c9bf3e48f 100644
--- a/src/qml/qml/qqmltypemodule.cpp
+++ b/src/qml/qml/qqmltypemodule.cpp
@@ -69,24 +69,24 @@ int QQmlTypeModule::majorVersion() const
int QQmlTypeModule::minimumMinorVersion() const
{
- return d->minMinorVersion.load();
+ return d->minMinorVersion.loadRelaxed();
}
int QQmlTypeModule::maximumMinorVersion() const
{
- return d->maxMinorVersion.load();
+ return d->maxMinorVersion.loadRelaxed();
}
void QQmlTypeModule::addMinorVersion(int version)
{
- for (int oldVersion = d->minMinorVersion.load();
+ for (int oldVersion = d->minMinorVersion.loadRelaxed();
oldVersion > version && !d->minMinorVersion.testAndSetOrdered(oldVersion, version);
- oldVersion = d->minMinorVersion.load()) {
+ oldVersion = d->minMinorVersion.loadRelaxed()) {
}
- for (int oldVersion = d->maxMinorVersion.load();
+ for (int oldVersion = d->maxMinorVersion.loadRelaxed();
oldVersion < version && !d->maxMinorVersion.testAndSetOrdered(oldVersion, version);
- oldVersion = d->maxMinorVersion.load()) {
+ oldVersion = d->maxMinorVersion.loadRelaxed()) {
}
}
@@ -125,12 +125,12 @@ void QQmlTypeModule::remove(const QQmlTypePrivate *type)
bool QQmlTypeModule::isLocked() const
{
- return d->locked.load() != 0;
+ return d->locked.loadRelaxed() != 0;
}
void QQmlTypeModule::lock()
{
- d->locked.store(1);
+ d->locked.storeRelaxed(1);
}
QQmlType QQmlTypeModule::type(const QHashedStringRef &name, int minor) const
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 9db089c330..57c4eec879 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -454,16 +454,16 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object,
if (!includeEnums || !name->startsWithUpper()) {
QQmlData *ddata = QQmlData::get(qobjectSingleton, false);
if (ddata && ddata->propertyCache) {
- ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton)));
QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobjectSingleton, qmlContext);
if (property) {
- lookup->qobjectLookup.ic = This->internalClass();
- lookup->qobjectLookup.staticQObject = static_cast<Heap::QObjectWrapper *>(val->heapObject());
+ ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton)));
+ lookup->qobjectLookup.qmlTypeIc = This->internalClass();
+ lookup->qobjectLookup.ic = val->objectValue()->internalClass();
lookup->qobjectLookup.propertyCache = ddata->propertyCache;
lookup->qobjectLookup.propertyCache->addref();
lookup->qobjectLookup.propertyData = property;
- lookup->getter = QV4::QObjectWrapper::lookupGetter;
- return lookup->getter(lookup, engine, *This);
+ lookup->getter = QQmlTypeWrapper::lookupSingletonProperty;
+ return lookup->getter(lookup, engine, *object);
}
// Fall through to base implementation
}
@@ -485,6 +485,39 @@ bool QQmlTypeWrapper::virtualResolveLookupSetter(Object *object, ExecutionEngine
return Object::virtualResolveLookupSetter(object, engine, lookup, value);
}
+ReturnedValue QQmlTypeWrapper::lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &object)
+{
+ const auto revertLookup = [l, engine, &object]() {
+ l->qobjectLookup.propertyCache->release();
+ l->qobjectLookup.propertyCache = nullptr;
+ l->getter = Lookup::getterGeneric;
+ return Lookup::getterGeneric(l, engine, object);
+ };
+
+ // we can safely cast to a QV4::Object here. If object is something else,
+ // the internal class won't match
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (!o || o->internalClass != l->qobjectLookup.qmlTypeIc)
+ return revertLookup();
+
+ Heap::QQmlTypeWrapper *This = static_cast<Heap::QQmlTypeWrapper *>(o);
+
+ QQmlType type = This->type();
+ if (!type.isValid())
+ return revertLookup();
+
+ if (!type.isQObjectSingleton() && !type.isCompositeSingleton())
+ return revertLookup();
+
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(engine->qmlEngine());
+ QObject *qobjectSingleton = e->singletonInstance<QObject *>(type);
+ Q_ASSERT(qobjectSingleton);
+
+ Scope scope(engine);
+ ScopedValue obj(scope, QV4::QObjectWrapper::wrap(engine, qobjectSingleton));
+ return QObjectWrapper::lookupGetterImpl(l, engine, obj, /*useOriginalProperty*/ true, revertLookup);
+}
+
void Heap::QQmlScopedEnumWrapper::destroy()
{
QQmlType::derefHandle(typePrivate);
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index c797a4ac10..6b51f421b3 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -114,6 +114,8 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object
static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup);
static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value);
+ static ReturnedValue lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &base);
+
protected:
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 2881e71805..458f26b465 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -57,6 +57,7 @@
#include <private/qv4scopedvalue_p.h>
#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qqmlpropertycachecreator_p.h>
QT_BEGIN_NAMESPACE
@@ -638,205 +639,170 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
id -= propOffset();
if (id < propertyCount) {
- const QV4::CompiledData::Property::Type t = static_cast<QV4::CompiledData::Property::Type>(qint32(compiledObject->propertyTable()[id].type));
- bool needActivate = false;
-
- if (t == QV4::CompiledData::Property::Var) {
- // the context can be null if accessing var properties from cpp after re-parenting an item.
- QQmlEnginePrivate *ep = (ctxt == nullptr || ctxt->engine == nullptr) ? nullptr : QQmlEnginePrivate::get(ctxt->engine);
- if (ep) {
- if (c == QMetaObject::ReadProperty) {
- *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
- } else if (c == QMetaObject::WriteProperty) {
- writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
- }
- } else if (c == QMetaObject::ReadProperty) {
- // if the context was disposed, we just return an invalid variant from read.
- *reinterpret_cast<QVariant *>(a[0]) = QVariant();
- }
+ const QV4::CompiledData::Property &property = compiledObject->propertyTable()[id];
+ const QV4::CompiledData::BuiltinType t = property.builtinType();
- } else {
- int fallbackMetaType = QMetaType::UnknownType;
+ // the context can be null if accessing var properties from cpp after re-parenting an item.
+ QQmlEnginePrivate *ep = (ctxt == nullptr || ctxt->engine == nullptr) ? nullptr : QQmlEnginePrivate::get(ctxt->engine);
+
+ const int fallbackMetaType = QQmlPropertyCacheCreatorBase::metaTypeForPropertyType(t);
+
+ if (c == QMetaObject::ReadProperty) {
switch (t) {
- case QV4::CompiledData::Property::Font:
- fallbackMetaType = QMetaType::QFont;
+ case QV4::CompiledData::BuiltinType::Int:
+ *reinterpret_cast<int *>(a[0]) = readPropertyAsInt(id);
break;
- case QV4::CompiledData::Property::Time:
- fallbackMetaType = QMetaType::QTime;
+ case QV4::CompiledData::BuiltinType::Bool:
+ *reinterpret_cast<bool *>(a[0]) = readPropertyAsBool(id);
break;
- case QV4::CompiledData::Property::Color:
- fallbackMetaType = QMetaType::QColor;
+ case QV4::CompiledData::BuiltinType::Real:
+ *reinterpret_cast<double *>(a[0]) = readPropertyAsDouble(id);
break;
- case QV4::CompiledData::Property::Vector2D:
- fallbackMetaType = QMetaType::QVector2D;
+ case QV4::CompiledData::BuiltinType::String:
+ *reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
break;
- case QV4::CompiledData::Property::Vector3D:
- fallbackMetaType = QMetaType::QVector3D;
+ case QV4::CompiledData::BuiltinType::Url:
+ *reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
break;
- case QV4::CompiledData::Property::Vector4D:
- fallbackMetaType = QMetaType::QVector4D;
+ case QV4::CompiledData::BuiltinType::Date:
+ *reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
break;
- case QV4::CompiledData::Property::Matrix4x4:
- fallbackMetaType = QMetaType::QMatrix4x4;
+ case QV4::CompiledData::BuiltinType::DateTime:
+ *reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
break;
- case QV4::CompiledData::Property::Quaternion:
- fallbackMetaType = QMetaType::QQuaternion;
+ case QV4::CompiledData::BuiltinType::Rect:
+ *reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
break;
- default: break;
- }
-
-
- if (c == QMetaObject::ReadProperty) {
- switch (t) {
- case QV4::CompiledData::Property::Int:
- *reinterpret_cast<int *>(a[0]) = readPropertyAsInt(id);
- break;
- case QV4::CompiledData::Property::Bool:
- *reinterpret_cast<bool *>(a[0]) = readPropertyAsBool(id);
- break;
- case QV4::CompiledData::Property::Real:
- *reinterpret_cast<double *>(a[0]) = readPropertyAsDouble(id);
- break;
- case QV4::CompiledData::Property::String:
- *reinterpret_cast<QString *>(a[0]) = readPropertyAsString(id);
- break;
- case QV4::CompiledData::Property::Url:
- *reinterpret_cast<QUrl *>(a[0]) = readPropertyAsUrl(id);
- break;
- case QV4::CompiledData::Property::Date:
- *reinterpret_cast<QDate *>(a[0]) = readPropertyAsDate(id);
- break;
- case QV4::CompiledData::Property::DateTime:
- *reinterpret_cast<QDateTime *>(a[0]) = readPropertyAsDateTime(id);
- break;
- case QV4::CompiledData::Property::Rect:
- *reinterpret_cast<QRectF *>(a[0]) = readPropertyAsRectF(id);
- break;
- case QV4::CompiledData::Property::Size:
- *reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
- break;
- case QV4::CompiledData::Property::Point:
- *reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
- break;
- case QV4::CompiledData::Property::Custom:
- *reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
- break;
- case QV4::CompiledData::Property::Variant:
+ case QV4::CompiledData::BuiltinType::Size:
+ *reinterpret_cast<QSizeF *>(a[0]) = readPropertyAsSizeF(id);
+ break;
+ case QV4::CompiledData::BuiltinType::Point:
+ *reinterpret_cast<QPointF *>(a[0]) = readPropertyAsPointF(id);
+ break;
+ case QV4::CompiledData::BuiltinType::Variant:
+ *reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
+ break;
+ case QV4::CompiledData::BuiltinType::Font:
+ case QV4::CompiledData::BuiltinType::Time:
+ case QV4::CompiledData::BuiltinType::Color:
+ case QV4::CompiledData::BuiltinType::Vector2D:
+ case QV4::CompiledData::BuiltinType::Vector3D:
+ case QV4::CompiledData::BuiltinType::Vector4D:
+ case QV4::CompiledData::BuiltinType::Matrix4x4:
+ case QV4::CompiledData::BuiltinType::Quaternion:
+ Q_ASSERT(fallbackMetaType != QMetaType::UnknownType);
+ if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
+ QVariant propertyAsVariant;
+ if (const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>())
+ propertyAsVariant = v->d()->data();
+ QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], fallbackMetaType);
+ }
+ break;
+ case QV4::CompiledData::BuiltinType::Var:
+ if (ep) {
*reinterpret_cast<QVariant *>(a[0]) = readPropertyAsVariant(id);
- break;
- case QV4::CompiledData::Property::CustomList: {
+ } else {
+ // if the context was disposed, we just return an invalid variant from read.
+ *reinterpret_cast<QVariant *>(a[0]) = QVariant();
+ }
+ break;
+ case QV4::CompiledData::BuiltinType::InvalidBuiltin:
+ if (property.isList) {
QList<QObject *> *list = readPropertyAsList(id);
QQmlListProperty<QObject> *p = static_cast<QQmlListProperty<QObject> *>(a[0]);
*p = QQmlListProperty<QObject>(object, list,
- list_append, list_count, list_at,
- list_clear);
+ list_append, list_count, list_at,
+ list_clear);
p->dummy1 = this;
p->dummy2 = reinterpret_cast<void *>(quintptr(methodOffset() + id));
- break;
+ } else {
+ *reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
}
- case QV4::CompiledData::Property::Font:
- case QV4::CompiledData::Property::Time:
- case QV4::CompiledData::Property::Color:
- case QV4::CompiledData::Property::Vector2D:
- case QV4::CompiledData::Property::Vector3D:
- case QV4::CompiledData::Property::Vector4D:
- case QV4::CompiledData::Property::Matrix4x4:
- case QV4::CompiledData::Property::Quaternion:
- Q_ASSERT(fallbackMetaType != QMetaType::UnknownType);
- if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
- QVariant propertyAsVariant;
- if (const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>())
- propertyAsVariant = v->d()->data();
- QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], fallbackMetaType);
+ }
+
+ } else if (c == QMetaObject::WriteProperty) {
+ bool needActivate = false;
+ switch (t) {
+ case QV4::CompiledData::BuiltinType::Int:
+ needActivate = *reinterpret_cast<int *>(a[0]) != readPropertyAsInt(id);
+ writeProperty(id, *reinterpret_cast<int *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Bool:
+ needActivate = *reinterpret_cast<bool *>(a[0]) != readPropertyAsBool(id);
+ writeProperty(id, *reinterpret_cast<bool *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Real:
+ needActivate = *reinterpret_cast<double *>(a[0]) != readPropertyAsDouble(id);
+ writeProperty(id, *reinterpret_cast<double *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::String:
+ needActivate = *reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
+ writeProperty(id, *reinterpret_cast<QString *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Url:
+ needActivate = *reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
+ writeProperty(id, *reinterpret_cast<QUrl *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Date:
+ needActivate = *reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
+ writeProperty(id, *reinterpret_cast<QDate *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::DateTime:
+ needActivate = *reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
+ writeProperty(id, *reinterpret_cast<QDateTime *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Rect:
+ needActivate = *reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
+ writeProperty(id, *reinterpret_cast<QRectF *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Size:
+ needActivate = *reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
+ writeProperty(id, *reinterpret_cast<QSizeF *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Point:
+ needActivate = *reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
+ writeProperty(id, *reinterpret_cast<QPointF *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Variant:
+ writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
+ break;
+ case QV4::CompiledData::BuiltinType::Font:
+ case QV4::CompiledData::BuiltinType::Time:
+ case QV4::CompiledData::BuiltinType::Color:
+ case QV4::CompiledData::BuiltinType::Vector2D:
+ case QV4::CompiledData::BuiltinType::Vector3D:
+ case QV4::CompiledData::BuiltinType::Vector4D:
+ case QV4::CompiledData::BuiltinType::Matrix4x4:
+ case QV4::CompiledData::BuiltinType::Quaternion:
+ Q_ASSERT(fallbackMetaType != QMetaType::UnknownType);
+ if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
+ const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
+ if (!v) {
+ md->set(engine, id, engine->newVariantObject(QVariant()));
+ v = (md->data() + id)->as<QV4::VariantObject>();
+ QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data());
}
- break;
- case QV4::CompiledData::Property::Var:
- Q_UNREACHABLE();
+ needActivate = !QQml_valueTypeProvider()->equalValueType(fallbackMetaType, a[0], v->d()->data());
+ QQml_valueTypeProvider()->writeValueType(fallbackMetaType, a[0], v->d()->data());
}
-
- } else if (c == QMetaObject::WriteProperty) {
-
- switch(t) {
- case QV4::CompiledData::Property::Int:
- needActivate = *reinterpret_cast<int *>(a[0]) != readPropertyAsInt(id);
- writeProperty(id, *reinterpret_cast<int *>(a[0]));
- break;
- case QV4::CompiledData::Property::Bool:
- needActivate = *reinterpret_cast<bool *>(a[0]) != readPropertyAsBool(id);
- writeProperty(id, *reinterpret_cast<bool *>(a[0]));
- break;
- case QV4::CompiledData::Property::Real:
- needActivate = *reinterpret_cast<double *>(a[0]) != readPropertyAsDouble(id);
- writeProperty(id, *reinterpret_cast<double *>(a[0]));
- break;
- case QV4::CompiledData::Property::String:
- needActivate = *reinterpret_cast<QString *>(a[0]) != readPropertyAsString(id);
- writeProperty(id, *reinterpret_cast<QString *>(a[0]));
- break;
- case QV4::CompiledData::Property::Url:
- needActivate = *reinterpret_cast<QUrl *>(a[0]) != readPropertyAsUrl(id);
- writeProperty(id, *reinterpret_cast<QUrl *>(a[0]));
- break;
- case QV4::CompiledData::Property::Date:
- needActivate = *reinterpret_cast<QDate *>(a[0]) != readPropertyAsDate(id);
- writeProperty(id, *reinterpret_cast<QDate *>(a[0]));
- break;
- case QV4::CompiledData::Property::DateTime:
- needActivate = *reinterpret_cast<QDateTime *>(a[0]) != readPropertyAsDateTime(id);
- writeProperty(id, *reinterpret_cast<QDateTime *>(a[0]));
- break;
- case QV4::CompiledData::Property::Rect:
- needActivate = *reinterpret_cast<QRectF *>(a[0]) != readPropertyAsRectF(id);
- writeProperty(id, *reinterpret_cast<QRectF *>(a[0]));
- break;
- case QV4::CompiledData::Property::Size:
- needActivate = *reinterpret_cast<QSizeF *>(a[0]) != readPropertyAsSizeF(id);
- writeProperty(id, *reinterpret_cast<QSizeF *>(a[0]));
- break;
- case QV4::CompiledData::Property::Point:
- needActivate = *reinterpret_cast<QPointF *>(a[0]) != readPropertyAsPointF(id);
- writeProperty(id, *reinterpret_cast<QPointF *>(a[0]));
- break;
- case QV4::CompiledData::Property::Custom:
- needActivate = *reinterpret_cast<QObject **>(a[0]) != readPropertyAsQObject(id);
- writeProperty(id, *reinterpret_cast<QObject **>(a[0]));
- break;
- case QV4::CompiledData::Property::Variant:
+ break;
+ case QV4::CompiledData::BuiltinType::Var:
+ if (ep)
writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
- break;
- case QV4::CompiledData::Property::CustomList:
+ break;
+ case QV4::CompiledData::BuiltinType::InvalidBuiltin:
+ if (property.isList) {
// Writing such a property is not supported. Content is added through the list property
// methods.
- break;
- case QV4::CompiledData::Property::Font:
- case QV4::CompiledData::Property::Time:
- case QV4::CompiledData::Property::Color:
- case QV4::CompiledData::Property::Vector2D:
- case QV4::CompiledData::Property::Vector3D:
- case QV4::CompiledData::Property::Vector4D:
- case QV4::CompiledData::Property::Matrix4x4:
- case QV4::CompiledData::Property::Quaternion:
- Q_ASSERT(fallbackMetaType != QMetaType::UnknownType);
- if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
- const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
- if (!v) {
- md->set(engine, id, engine->newVariantObject(QVariant()));
- v = (md->data() + id)->as<QV4::VariantObject>();
- QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data());
- }
- needActivate = !QQml_valueTypeProvider()->equalValueType(fallbackMetaType, a[0], v->d()->data());
- QQml_valueTypeProvider()->writeValueType(fallbackMetaType, a[0], v->d()->data());
- }
- break;
- case QV4::CompiledData::Property::Var:
- Q_UNREACHABLE();
+ } else {
+ needActivate = *reinterpret_cast<QObject **>(a[0]) != readPropertyAsQObject(id);
+ writeProperty(id, *reinterpret_cast<QObject **>(a[0]));
}
- }
- }
+ }
- if (c == QMetaObject::WriteProperty && needActivate) {
- activate(object, methodOffset() + id, nullptr);
+ if (needActivate)
+ activate(object, methodOffset() + id, nullptr);
}
return -1;
@@ -1000,7 +966,7 @@ QV4::ReturnedValue QQmlVMEMetaObject::method(int index) const
QV4::ReturnedValue QQmlVMEMetaObject::readVarProperty(int id) const
{
- Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].type == QV4::CompiledData::Property::Var);
+ Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].builtinType() == QV4::CompiledData::BuiltinType::Var);
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
@@ -1025,7 +991,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) const
void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
{
- Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].type == QV4::CompiledData::Property::Var);
+ Q_ASSERT(compiledObject && compiledObject->propertyTable()[id].builtinType() == QV4::CompiledData::BuiltinType::Var);
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
@@ -1065,7 +1031,7 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
{
- if (compiledObject && compiledObject->propertyTable()[id].type == QV4::CompiledData::Property::Var) {
+ if (compiledObject && compiledObject->propertyTable()[id].builtinType() == QV4::CompiledData::BuiltinType::Var) {
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
return;