aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-20 01:00:04 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-20 01:00:04 +0100
commit03097d5038fe6331df97182a38fac3a9a84fe195 (patch)
tree928675991970423a6b06a8bcf5aeb79b43d2710e /src/qml
parentfee0fcfef08a05ed4ba9369d2352c876b514d69c (diff)
parent407e2769c7b7909fdb2979090e71fa636f109a04 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator_p.h9
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp7
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator_p.h5
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp27
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h23
-rw-r--r--src/qml/compiler/qv4compileddata_p.h1
-rw-r--r--src/qml/jsruntime/qv4propertykey_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp40
-rw-r--r--src/qml/parser/qqmljs.g8
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp7
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h5
-rw-r--r--src/qml/qml/qqmltypeloader.cpp7
-rw-r--r--src/qml/qml/qqmltypeloader_p.h3
13 files changed, 92 insertions, 52 deletions
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h
index 02517ea6bb..6bee599c0a 100644
--- a/src/qml/compiler/qqmlpropertycachecreator_p.h
+++ b/src/qml/compiler/qqmlpropertycachecreator_p.h
@@ -150,7 +150,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObje
if (context.instantiatingProperty && QQmlValueTypeFactory::isValueType(context.instantiatingProperty->propType())) {
if (!propertyCaches->needsVMEMetaObject(context.referencingObjectIndex)) {
const CompiledObject *obj = objectContainer->objectAt(context.referencingObjectIndex);
- auto *typeRef = objectContainer->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
QQmlRefPointer<QQmlPropertyCache> baseTypeCache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
QQmlCompileError error = createMetaObject(context.referencingObjectIndex, obj, baseTypeCache);
@@ -214,7 +214,7 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
if (context.instantiatingProperty) {
return context.instantiatingPropertyCache(enginePrivate);
} else if (obj->inheritedTypeNameIndex != 0) {
- auto *typeRef = objectContainer->resolvedTypes.value(obj->inheritedTypeNameIndex);
+ auto *typeRef = objectContainer->resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
if (typeRef->isFullyDynamicType) {
@@ -234,7 +234,8 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine
return typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
} else if (context.instantiatingBinding && context.instantiatingBinding->isAttachedProperty()) {
- auto *typeRef = objectContainer->resolvedTypes.value(context.instantiatingBinding->propertyNameIndex);
+ auto *typeRef = objectContainer->resolvedType(
+ context.instantiatingBinding->propertyNameIndex);
Q_ASSERT(typeRef);
QQmlType qmltype = typeRef->type;
if (!qmltype.isValid()) {
@@ -709,7 +710,7 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property
return propertyDataForAlias(component, *targetAlias, type, minorVersion, propertyFlags);
} else if (alias.encodedMetaPropertyIndex == -1) {
Q_ASSERT(alias.flags & QV4::CompiledData::Alias::AliasPointsToPointerObject);
- auto *typeRef = objectContainer->resolvedTypes.value(targetObject.inheritedTypeNameIndex);
+ auto *typeRef = objectContainer->resolvedType(targetObject.inheritedTypeNameIndex);
if (!typeRef) {
// Can be caused by the alias target not being a valid id or property. E.g.:
// property alias dataValue: dataVal
diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp
index b1865121d3..a6b57841a8 100644
--- a/src/qml/compiler/qqmlpropertyvalidator.cpp
+++ b/src/qml/compiler/qqmlpropertyvalidator.cpp
@@ -50,7 +50,6 @@ QQmlPropertyValidator::QQmlPropertyValidator(QQmlEnginePrivate *enginePrivate, c
, compilationUnit(compilationUnit)
, imports(imports)
, qmlUnit(compilationUnit->unitData())
- , resolvedTypes(compilationUnit->resolvedTypes)
, propertyCaches(compilationUnit->propertyCaches)
, bindingPropertyDataPerObject(&compilationUnit->bindingPropertyDataPerObject)
{
@@ -96,7 +95,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
return QVector<QQmlCompileError>();
QQmlCustomParser *customParser = nullptr;
- if (auto typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex)) {
+ if (auto typeRef = resolvedType(obj->inheritedTypeNameIndex)) {
if (typeRef->type.isValid())
customParser = typeRef->type.customParser();
}
@@ -168,7 +167,7 @@ QVector<QQmlCompileError> QQmlPropertyValidator::validateObject(int objectIndex,
if (notInRevision) {
QString typeName = stringAt(obj->inheritedTypeNameIndex);
- auto *objectType = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ auto *objectType = resolvedType(obj->inheritedTypeNameIndex);
if (objectType && objectType->type.isValid()) {
return recordError(binding->location, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(name).arg(objectType->type.module()).arg(objectType->majorVersion).arg(objectType->minorVersion));
} else {
@@ -636,7 +635,7 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
bool isPropertyInterceptor = false;
const QV4::CompiledData::Object *targetObject = compilationUnit->objectAt(binding->value.objectIndex);
- if (auto *typeRef = resolvedTypes.value(targetObject->inheritedTypeNameIndex)) {
+ if (auto *typeRef = resolvedType(targetObject->inheritedTypeNameIndex)) {
QQmlRefPointer<QQmlPropertyCache> cache = typeRef->createPropertyCache(QQmlEnginePrivate::get(enginePrivate));
const QMetaObject *mo = cache->firstCppMetaObject();
QQmlType qmlType;
diff --git a/src/qml/compiler/qqmlpropertyvalidator_p.h b/src/qml/compiler/qqmlpropertyvalidator_p.h
index 67a2f989af..e9ae844ccb 100644
--- a/src/qml/compiler/qqmlpropertyvalidator_p.h
+++ b/src/qml/compiler/qqmlpropertyvalidator_p.h
@@ -72,12 +72,15 @@ private:
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;
QString stringAt(int index) const { return compilationUnit->stringAt(index); }
+ QV4::CompiledData::ResolvedTypeReference *resolvedType(int id) const
+ {
+ return compilationUnit->resolvedType(id);
+ }
QQmlEnginePrivate *enginePrivate;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
const QQmlImports &imports;
const QV4::CompiledData::Unit *qmlUnit;
- const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypes;
const QQmlPropertyCacheVector &propertyCaches;
QVector<QV4::CompiledData::BindingPropertyData> * const bindingPropertyDataPerObject;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index cb097a0410..70b048d737 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData,
QmlIR::Document *parsedQML, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
- const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
+ QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
: resolvedTypes(resolvedTypeCache)
, engine(engine)
, typeData(typeData)
@@ -70,7 +70,7 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile()
{
// Build property caches and VME meta object data
- for (auto it = resolvedTypes.constBegin(), end = resolvedTypes.constEnd();
+ for (auto it = resolvedTypes->constBegin(), end = resolvedTypes->constEnd();
it != end; ++it) {
QQmlCustomParser *customParser = (*it)->type.customParser();
if (customParser)
@@ -161,9 +161,8 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile()
qmlGenerator.generate(*document, dependencyHasher);
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = document->javaScriptCompilationUnit;
- compilationUnit = document->javaScriptCompilationUnit;
compilationUnit->typeNameCache = typeNameCache;
- compilationUnit->resolvedTypes = resolvedTypes;
+ compilationUnit->resolvedTypes = *resolvedTypes;
compilationUnit->propertyCaches = std::move(m_propertyCaches);
Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->objectCount()));
@@ -300,7 +299,6 @@ SignalHandlerConverter::SignalHandlerConverter(QQmlTypeCompiler *typeCompiler)
, qmlObjects(*typeCompiler->qmlObjects())
, imports(typeCompiler->imports())
, customParsers(typeCompiler->customParserCache())
- , resolvedTypes(typeCompiler->resolvedTypes)
, illegalNames(typeCompiler->enginePrivate()->v8engine()->illegalNames())
, propertyCaches(typeCompiler->propertyCaches())
{
@@ -334,7 +332,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
// Attached property?
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
const QmlIR::Object *attachedObj = qmlObjects.at(binding->value.objectIndex);
- auto *typeRef = resolvedTypes.value(binding->propertyNameIndex);
+ auto *typeRef = resolvedType(binding->propertyNameIndex);
QQmlType type = typeRef ? typeRef->type : QQmlType();
if (!type.isValid()) {
if (imports->resolveType(propertyName, &type, nullptr, nullptr, nullptr)) {
@@ -405,7 +403,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
const QString &originalPropertyName = stringAt(binding->propertyNameIndex);
- auto *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ auto *typeRef = resolvedType(obj->inheritedTypeNameIndex);
const QQmlType type = typeRef ? typeRef->type : QQmlType();
if (type.isValid()) {
COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(typeName).arg(originalPropertyName).arg(type.module()).arg(type.majorVersion()).arg(type.minorVersion()));
@@ -506,7 +504,6 @@ QQmlEnumTypeResolver::QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler)
, qmlObjects(*typeCompiler->qmlObjects())
, propertyCaches(typeCompiler->propertyCaches())
, imports(typeCompiler->imports())
- , resolvedTypes(&typeCompiler->resolvedTypes)
{
}
@@ -618,7 +615,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
int value = 0;
bool ok = false;
- auto *tr = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ auto *tr = resolvedType(obj->inheritedTypeNameIndex);
if (type.isValid() && tr && tr->type == type) {
// When these two match, we can short cut the search
QMetaProperty mprop = propertyCache->firstCppMetaObject()->property(prop->coreIndex());
@@ -785,7 +782,6 @@ QQmlComponentAndAliasResolver::QQmlComponentAndAliasResolver(QQmlTypeCompiler *t
, enginePrivate(typeCompiler->enginePrivate())
, pool(typeCompiler->memoryPool())
, qmlObjects(typeCompiler->qmlObjects())
- , resolvedTypes(&typeCompiler->resolvedTypes)
, propertyCaches(std::move(typeCompiler->takePropertyCaches()))
{
}
@@ -803,7 +799,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
continue;
const QmlIR::Object *targetObject = qmlObjects->at(binding->value.objectIndex);
- auto *tr = resolvedTypes->value(targetObject->inheritedTypeNameIndex);
+ auto *tr = resolvedType(targetObject->inheritedTypeNameIndex);
Q_ASSERT(tr);
const QMetaObject *firstMetaObject = nullptr;
@@ -854,12 +850,12 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
syntheticComponent->location = binding->valueLocation;
syntheticComponent->flags |= QV4::CompiledData::Object::IsComponent;
- if (!resolvedTypes->contains(syntheticComponent->inheritedTypeNameIndex)) {
+ if (!containsResolvedType(syntheticComponent->inheritedTypeNameIndex)) {
auto typeRef = new QV4::CompiledData::ResolvedTypeReference;
typeRef->type = componentType;
typeRef->majorVersion = componentType.majorVersion();
typeRef->minorVersion = componentType.minorVersion();
- resolvedTypes->insert(syntheticComponent->inheritedTypeNameIndex, typeRef);
+ insertResolvedType(syntheticComponent->inheritedTypeNameIndex, typeRef);
}
qmlObjects->append(syntheticComponent);
@@ -897,7 +893,7 @@ bool QQmlComponentAndAliasResolver::resolve()
bool isExplicitComponent = false;
if (obj->inheritedTypeNameIndex) {
- auto *tref = resolvedTypes->value(obj->inheritedTypeNameIndex);
+ auto *tref = resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(tref);
if (tref->type.metaObject() == &QQmlComponent::staticMetaObject)
isExplicitComponent = true;
@@ -1300,7 +1296,6 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex)
QQmlJSCodeGenerator::QQmlJSCodeGenerator(QQmlTypeCompiler *typeCompiler, QmlIR::JSCodeGen *v4CodeGen)
: QQmlCompilePass(typeCompiler)
- , resolvedTypes(typeCompiler->resolvedTypes)
, customParsers(typeCompiler->customParserCache())
, qmlObjects(*typeCompiler->qmlObjects())
, propertyCaches(typeCompiler->propertyCaches())
@@ -1339,7 +1334,7 @@ bool QQmlJSCodeGenerator::compileComponent(int contextObject)
m.idIndex = obj->id;
m.type = propertyCaches->at(objectIndex);
- auto *tref = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ auto *tref = resolvedType(obj->inheritedTypeNameIndex);
if (tref && tref->isFullyDynamicType)
m.type = nullptr;
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index ffe04eb090..a49b97453f 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -79,7 +79,9 @@ struct QQmlTypeCompiler
{
Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
public:
- QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache,
+ QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document,
+ const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
+ QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
// --- interface used by QQmlPropertyCacheCreator
@@ -89,7 +91,7 @@ public:
QString stringAt(int idx) const;
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
- QV4::CompiledData::ResolvedTypeReferenceMap resolvedTypes;
+ QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypes = nullptr;
// ---
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compile();
@@ -124,6 +126,11 @@ public:
void addImport(const QString &module, const QString &qualifier, int majorVersion, int minorVersion);
+ QV4::CompiledData::ResolvedTypeReference *resolvedType(int id) const
+ {
+ return resolvedTypes->value(id);
+ }
+
private:
QList<QQmlError> errors;
QQmlEnginePrivate *engine;
@@ -150,6 +157,14 @@ protected:
void recordError(const QQmlCompileError &error)
{ compiler->recordError(error); }
+ QV4::CompiledData::ResolvedTypeReference *resolvedType(int id) const
+ { return compiler->resolvedType(id); }
+ bool containsResolvedType(int id) const
+ { return compiler->resolvedTypes->contains(id); }
+ QV4::CompiledData::ResolvedTypeReferenceMap::iterator insertResolvedType(
+ int id, QV4::CompiledData::ResolvedTypeReference *value)
+ { return compiler->resolvedTypes->insert(id, value); }
+
QQmlTypeCompiler *compiler;
};
@@ -172,7 +187,6 @@ private:
const QVector<QmlIR::Object*> &qmlObjects;
const QQmlImports *imports;
const QHash<int, QQmlCustomParser*> &customParsers;
- const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypes;
const QSet<QString> &illegalNames;
const QQmlPropertyCacheVector * const propertyCaches;
};
@@ -203,7 +217,6 @@ private:
const QVector<QmlIR::Object*> &qmlObjects;
const QQmlPropertyCacheVector * const propertyCaches;
const QQmlImports *imports;
- QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypes;
};
class QQmlCustomParserScriptIndexer: public QQmlCompilePass
@@ -278,7 +291,6 @@ protected:
QMap<int, int> _idToObjectIndex;
QVector<int> _objectsWithAliases;
- QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypes;
QQmlPropertyCacheVector propertyCaches;
};
@@ -311,7 +323,6 @@ private:
bool compileComponent(int componentRoot);
bool compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex);
- const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypes;
const QHash<int, QQmlCustomParser*> &customParsers;
const QVector<QmlIR::Object*> &qmlObjects;
const QQmlPropertyCacheVector * const propertyCaches;
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 7197b4cde8..2dccc8db04 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -1187,6 +1187,7 @@ public:
QVector<QQmlRefPointer<QQmlScriptData>> dependentScripts;
ResolvedTypeReferenceMap resolvedTypes;
+ ResolvedTypeReference *resolvedType(int id) const { return resolvedTypes.value(id); }
bool verifyChecksum(const DependentTypesHasher &dependencyHasher) const;
diff --git a/src/qml/jsruntime/qv4propertykey_p.h b/src/qml/jsruntime/qv4propertykey_p.h
index cb2661f244..47867765db 100644
--- a/src/qml/jsruntime/qv4propertykey_p.h
+++ b/src/qml/jsruntime/qv4propertykey_p.h
@@ -114,7 +114,7 @@ public:
static PropertyKey fromArrayIndex(uint idx) { PropertyKey key; key.val = ArrayIndexMask | static_cast<quint64>(idx); return key; }
bool isStringOrSymbol() const { return isManaged() && val != 0; }
uint asArrayIndex() const { return (isManaged() || val == 0) ? std::numeric_limits<uint>::max() : static_cast<uint>(val & 0xffffffff); }
- uint isArrayIndex() const { return !isManaged() && val != 0; }
+ uint isArrayIndex() const { return !isManaged() && val != 0 && static_cast<uint>(val & 0xffffffff) != std::numeric_limits<uint>::max(); }
bool isValid() const { return val != 0; }
static PropertyKey fromStringOrSymbol(Heap::StringOrSymbol *b)
{ PropertyKey key; key.setM(b); return key; }
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 9344a231ff..6617dd5e89 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1144,7 +1144,7 @@ struct CallArgument {
inline void *dataPtr();
inline void initAsType(int type);
- inline void fromValue(int type, ExecutionEngine *, const QV4::Value &);
+ inline bool fromValue(int type, ExecutionEngine *, const QV4::Value &);
inline ReturnedValue toValue(ExecutionEngine *);
private:
@@ -1204,8 +1204,12 @@ static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index
// Convert all arguments.
QVarLengthArray<CallArgument, 9> args(argCount + 1);
args[0].initAsType(returnType);
- for (int ii = 0; ii < argCount; ++ii)
- args[ii + 1].fromValue(argTypes[ii], engine, callArgs->args[ii]);
+ for (int ii = 0; ii < argCount; ++ii) {
+ if (!args[ii + 1].fromValue(argTypes[ii], engine, callArgs->args[ii])) {
+ return engine->throwTypeError(QString::fromLatin1("Could not convert argument %1.")
+ .arg(ii));
+ }
+ }
QVarLengthArray<void *, 9> argData(args.count());
for (int ii = 0; ii < args.count(); ++ii)
argData[ii] = args[ii].dataPtr();
@@ -1672,7 +1676,7 @@ void CallArgument::fromContainerValue(const QV4::Object *object, int callType, M
}
#endif
-void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value)
+bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value)
{
if (type != 0) {
cleanup();
@@ -1708,11 +1712,13 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
type = callType;
} else if (callType == QMetaType::QObjectStar) {
qobjectPtr = nullptr;
+ type = callType;
if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
qobjectPtr = qobjectWrapper->object();
else if (const QV4::QQmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QQmlTypeWrapper>())
queryEngine = qmlTypeWrapper->isSingleton();
- type = callType;
+ else if (!value.isNull() && !value.isUndefined()) // null and undefined are nullptr
+ return false;
} else if (callType == qMetaTypeId<QVariant>()) {
qvariantPtr = new (&allocData) QVariant(scope.engine->toVariant(value, -1));
type = callType;
@@ -1734,6 +1740,8 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
QObject *o = nullptr;
if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
o = qobjectWrapper->object();
+ else if (!value.isNull() && !value.isUndefined())
+ return false;
qlistPtr->append(o);
}
type = callType;
@@ -1782,6 +1790,15 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
fromContainerValue<std::vector<QModelIndex>>(object, callType, &CallArgument::stdVectorQModelIndexPtr, queryEngine);
}
#endif
+ } else if (QMetaType::typeFlags(callType)
+ & (QMetaType::PointerToQObject | QMetaType::PointerToGadget)) {
+ // You can assign null or undefined to any pointer. The result is a nullptr.
+ if (value.isNull() || value.isUndefined()) {
+ qvariantPtr = new (&allocData) QVariant(callType, nullptr);
+ type = callType;
+ } else {
+ queryEngine = true;
+ }
} else {
queryEngine = true;
}
@@ -1803,15 +1820,20 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
if (!mo.isNull()) {
QObject *obj = ep->toQObject(v);
- if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo))
- obj = nullptr;
+ if (obj != nullptr && !QQmlMetaObject::canConvert(obj, mo)) {
+ *qvariantPtr = QVariant(callType, nullptr);
+ return false;
+ }
*qvariantPtr = QVariant(callType, &obj);
- } else {
- *qvariantPtr = QVariant(callType, (void *)nullptr);
+ return true;
}
+
+ *qvariantPtr = QVariant(callType, (void *)nullptr);
+ return false;
}
}
+ return true;
}
QV4::ReturnedValue CallArgument::toValue(QV4::ExecutionEngine *engine)
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 860a4e999e..b86dba6daa 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -3963,8 +3963,12 @@ ClassElementList: ClassElement;
ClassElementList: ClassElementList ClassElement;
/.
case $rule_number: {
- if (sym(2).Node)
- sym(1).ClassElementList = sym(1).ClassElementList->append(sym(2).ClassElementList);
+ if (sym(1).Node) {
+ if (sym(2).Node)
+ sym(1).ClassElementList = sym(1).ClassElementList->append(sym(2).ClassElementList);
+ } else if (sym(2).Node) {
+ sym(1).Node = sym(2).Node;
+ }
} break;
./
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index d015a2c0e8..ca5498d06c 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -75,7 +75,6 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlR
QQmlIncubatorPrivate *incubator)
: phase(Startup)
, compilationUnit(compilationUnit)
- , resolvedTypes(compilationUnit->resolvedTypes)
, propertyCaches(&compilationUnit->propertyCaches)
, sharedState(new QQmlObjectCreatorSharedState)
, topLevelCreator(true)
@@ -102,7 +101,6 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlR
QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit, QQmlObjectCreatorSharedState *inheritedSharedState)
: phase(Startup)
, compilationUnit(compilationUnit)
- , resolvedTypes(compilationUnit->resolvedTypes)
, propertyCaches(&compilationUnit->propertyCaches)
, sharedState(inheritedSharedState)
, topLevelCreator(false)
@@ -804,7 +802,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
{
if (binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
Q_ASSERT(stringAt(compilationUnit->objectAt(binding->value.objectIndex)->inheritedTypeNameIndex).isEmpty());
- QV4::CompiledData::ResolvedTypeReference *tr = resolvedTypes.value(binding->propertyNameIndex);
+ QV4::CompiledData::ResolvedTypeReference *tr = resolvedType(binding->propertyNameIndex);
Q_ASSERT(tr);
QQmlType attachedType = tr->type;
if (!attachedType.isValid()) {
@@ -1170,7 +1168,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
instance = component;
ddata = QQmlData::get(instance, /*create*/true);
} else {
- QV4::CompiledData::ResolvedTypeReference *typeRef = resolvedTypes.value(obj->inheritedTypeNameIndex);
+ QV4::CompiledData::ResolvedTypeReference *typeRef
+ = resolvedType(obj->inheritedTypeNameIndex);
Q_ASSERT(typeRef);
installPropertyCache = !typeRef->isFullyDynamicType;
QQmlType type = typeRef->type;
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 020e673941..5aca60e2f0 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -125,6 +125,10 @@ private:
inline QV4::QmlContext *currentQmlContext();
Q_NEVER_INLINE void createQmlContext();
+ QV4::CompiledData::ResolvedTypeReference *resolvedType(int id) const
+ {
+ return compilationUnit->resolvedType(id);
+ }
enum Phase {
Startup,
@@ -141,7 +145,6 @@ private:
const QV4::CompiledData::Unit *qmlUnit;
QQmlGuardedContextData parentContext;
QQmlContextData *context;
- const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypes;
const QQmlPropertyCacheVector *propertyCaches;
QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
bool topLevelCreator;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index b508a66f84..457558fb56 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2356,7 +2356,7 @@ void QQmlTypeData::done()
QQmlEngine *const engine = typeLoader()->engine();
- const auto dependencyHasher = [engine, resolvedTypeCache, this](QCryptographicHash *hash) {
+ const auto dependencyHasher = [engine, &resolvedTypeCache, this](QCryptographicHash *hash) {
if (!resolvedTypeCache.addToHash(hash, engine))
return false;
return ::addTypeReferenceChecksumsToHash(m_compositeSingletons, hash, engine);
@@ -2373,7 +2373,7 @@ void QQmlTypeData::done()
if (!m_document.isNull()) {
// Compile component
- compile(typeNameCache, resolvedTypeCache, dependencyHasher);
+ compile(typeNameCache, &resolvedTypeCache, dependencyHasher);
} else {
createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache);
}
@@ -2646,7 +2646,8 @@ QString QQmlTypeData::stringAt(int index) const
return m_document->jsGenerator.stringTable.stringForIndex(index);
}
-void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache,
+void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
+ QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
{
Q_ASSERT(m_compiledData.isNull());
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 5bb4e9d490..987e47222d 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -485,7 +485,8 @@ private:
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache
) const;
void compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
- const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
+ QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache,
+ const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion,