diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-20 01:00:04 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-20 01:00:04 +0100 |
commit | 03097d5038fe6331df97182a38fac3a9a84fe195 (patch) | |
tree | 928675991970423a6b06a8bcf5aeb79b43d2710e /src/qml | |
parent | fee0fcfef08a05ed4ba9369d2352c876b514d69c (diff) | |
parent | 407e2769c7b7909fdb2979090e71fa636f109a04 (diff) |
Merge remote-tracking branch 'origin/5.12' into 5.13
Change-Id: I69c3e6610ff590d9c18f386fc17ed2e429b58d26
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qqmlpropertycachecreator_p.h | 9 | ||||
-rw-r--r-- | src/qml/compiler/qqmlpropertyvalidator.cpp | 7 | ||||
-rw-r--r-- | src/qml/compiler/qqmlpropertyvalidator_p.h | 5 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 27 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 23 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4propertykey_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 40 | ||||
-rw-r--r-- | src/qml/parser/qqmljs.g | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 3 |
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, |