aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp12
-rw-r--r--src/qmlcompiler/qqmljsmetatypes_p.h4
-rw-r--r--src/qmlcompiler/qqmljsscope.cpp30
-rw-r--r--src/qmlcompiler/qqmljsscope_p.h5
-rw-r--r--src/qmlcompiler/qqmljstypedescriptionreader.cpp5
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)