diff options
-rw-r--r-- | src/qmlcompiler/qqmljsimportvisitor.cpp | 12 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsmetatypes_p.h | 4 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope.cpp | 30 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope_p.h | 5 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypedescriptionreader.cpp | 5 |
5 files changed, 42 insertions, 14 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp index 5fe187f4d0..599f2bb00a 100644 --- a/src/qmlcompiler/qqmljsimportvisitor.cpp +++ b/src/qmlcompiler/qqmljsimportvisitor.cpp @@ -188,9 +188,10 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember) prop.setIsList(publicMember->typeModifier == QLatin1String("list")); prop.setIsWritable(!publicMember->isReadonlyMember); prop.setIsAlias(isAlias); - prop.setIsRequired(publicMember->isRequired); prop.setType(m_rootScopeImports.value(prop.typeName())); m_currentScope->insertPropertyIdentifier(prop); + if (publicMember->isRequired) + m_currentScope->setPropertyLocallyRequired(prop.propertyName(), true); break; } } @@ -211,14 +212,7 @@ bool QQmlJSImportVisitor::visit(UiRequired *required) return true; } - QQmlJSMetaProperty prop = m_currentScope->property(name); - prop.setIsRequired(true); - - // Add a synthetic property that is identical to the previous one in every way, except in our current scope. - // This is necessary as we can't just modify the existing property to be required as this would affect every use of it, - // not just the one where the property is actually marked as required. - m_currentScope->insertPropertyIdentifier(prop); - + m_currentScope->setPropertyLocallyRequired(name, true); return true; } diff --git a/src/qmlcompiler/qqmljsmetatypes_p.h b/src/qmlcompiler/qqmljsmetatypes_p.h index bc937e46f5..57328af836 100644 --- a/src/qmlcompiler/qqmljsmetatypes_p.h +++ b/src/qmlcompiler/qqmljsmetatypes_p.h @@ -242,7 +242,6 @@ class QQmlJSMetaProperty bool m_isWritable = false; bool m_isPointer = false; bool m_isAlias = false; - bool m_isRequired = false; int m_revision = 0; public: @@ -272,9 +271,6 @@ public: void setIsAlias(bool isAlias) { m_isAlias = isAlias; } bool isAlias() const { return m_isAlias; } - void setIsRequired(bool isRequired) { m_isRequired = isRequired; } - bool isRequired() const { return m_isRequired; } - void setRevision(int revision) { m_revision = revision; } int revision() const { return m_revision; } diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index ce4897d20e..aaeda2431f 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -334,6 +334,36 @@ QQmlJSMetaProperty QQmlJSScope::property(const QString &name) const return prop; } +void QQmlJSScope::setPropertyLocallyRequired(const QString &name, bool isRequired) +{ + if (!isRequired) + m_requiredPropertyNames.removeOne(name); + else if (!m_requiredPropertyNames.contains(name)) + m_requiredPropertyNames.append(name); +} + +bool QQmlJSScope::isPropertyRequired(const QString &name) const +{ + bool isRequired = false; + searchBaseAndExtensionTypes(this, [&](const QQmlJSScope *scope) { + if (scope->isPropertyLocallyRequired(name)) { + isRequired = true; + return true; + } + + // If it has a property of that name, and that is not required, then none of the + // base types matter. You cannot make a derived type's property required with + // a "required" specification in a base type. + return scope->hasOwnProperty(name); + }); + return isRequired; +} + +bool QQmlJSScope::isPropertyLocallyRequired(const QString &name) const +{ + return m_requiredPropertyNames.contains(name); +} + QQmlJSScope::Export::Export(QString package, QString type, const QTypeRevision &version) : m_package(std::move(package)), m_type(std::move(type)), diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h index cbfc109154..9f05c112b3 100644 --- a/src/qmlcompiler/qqmljsscope_p.h +++ b/src/qmlcompiler/qqmljsscope_p.h @@ -214,6 +214,10 @@ public: bool hasProperty(const QString &name) const; QQmlJSMetaProperty property(const QString &name) const; + void setPropertyLocallyRequired(const QString &name, bool isRequired); + bool isPropertyRequired(const QString &name) const; + bool isPropertyLocallyRequired(const QString &name) const; + QString defaultPropertyName() const { return m_defaultPropertyName; } void setDefaultPropertyName(const QString &name) { m_defaultPropertyName = name; } @@ -306,6 +310,7 @@ private: QString m_defaultPropertyName; QString m_attachedTypeName; + QStringList m_requiredPropertyNames; QQmlJSScope::WeakConstPtr m_attachedType; QString m_valueTypeName; diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp index 6de753c9ee..1e5b35c344 100644 --- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp +++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp @@ -323,6 +323,7 @@ void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQ { QQmlJSMetaProperty property; property.setIsWritable(true); // default is writable + bool isRequired = false; for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) { UiObjectMember *member = it->member; @@ -342,7 +343,7 @@ void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQ } else if (id == QLatin1String("isReadonly")) { property.setIsWritable(!readBoolBinding(script)); } else if (id == QLatin1String("isRequired")) { - property.setIsRequired(readBoolBinding(script)); + isRequired = readBoolBinding(script); } else if (id == QLatin1String("isList")) { property.setIsList(readBoolBinding(script)); } else if (id == QLatin1String("revision")) { @@ -366,6 +367,8 @@ void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQ } scope->addOwnProperty(property); + if (isRequired) + scope->setPropertyLocallyRequired(property.propertyName(), true); } void QQmlJSTypeDescriptionReader::readEnum(UiObjectDefinition *ast, const QQmlJSScope::Ptr &scope) |