diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-18 11:40:31 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-02-24 08:33:21 +0100 |
commit | 120eb155ef1f0da51c473b080880169a85e5ceb2 (patch) | |
tree | b8bc85734d68f125d424b1f45f2576d20c885a43 /src/qmlcompiler/qqmljsscope.cpp | |
parent | ae68d95b8c1c56ae907cbe88122dd79bafd20b72 (diff) |
qmllint: Check for existence of property types
For each binding there should be a property and that property should
have a type we recognize.
Enums can be property types in C++. We support this by adding child
scopes for such enums. The child scopes are then referenced by the
QQmlJSMetaEnums and derive from int.
The test then reveals that we were missing a few properties in
QtQuick.tooling. Add those.
Change-Id: I1deef94393ee0e17d34c2dc5980ebfbf25417f36
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 08c8e8ac3ba8eb23ae5c158990f5d029ac9988ed)
Diffstat (limited to 'src/qmlcompiler/qqmljsscope.cpp')
-rw-r--r-- | src/qmlcompiler/qqmljsscope.cpp | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index 64fa44ef82..5c3ce8d139 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -190,7 +190,8 @@ QQmlJSScope::findJSIdentifier(const QString &id) const return std::optional<JavaScriptIdentifier>{}; } -void QQmlJSScope::resolveTypes(const QHash<QString, QQmlJSScope::ConstPtr> &contextualTypes) +void QQmlJSScope::resolveTypes(const QQmlJSScope::Ptr &self, + const QHash<QString, QQmlJSScope::ConstPtr> &contextualTypes) { auto findType = [&](const QString &name) { auto type = contextualTypes.constFind(name); @@ -200,25 +201,46 @@ void QQmlJSScope::resolveTypes(const QHash<QString, QQmlJSScope::ConstPtr> &cont return QQmlJSScope::ConstPtr(); }; - if (!m_baseType && !m_baseTypeName.isEmpty()) - m_baseType = findType(m_baseTypeName); + if (!self->m_baseType && !self->m_baseTypeName.isEmpty()) + self->m_baseType = findType(self->m_baseTypeName); - if (!m_attachedType && !m_attachedTypeName.isEmpty()) - m_attachedType = findType(m_attachedTypeName); + if (!self->m_attachedType && !self->m_attachedTypeName.isEmpty()) + self->m_attachedType = findType(self->m_attachedTypeName); - if (!m_valueType && !m_valueTypeName.isEmpty()) - m_valueType = findType(m_valueTypeName); + if (!self->m_valueType && !self->m_valueTypeName.isEmpty()) + self->m_valueType = findType(self->m_valueTypeName); - if (!m_extensionType && !m_extensionTypeName.isEmpty()) - m_extensionType = findType(m_extensionTypeName); + if (!self->m_extensionType && !self->m_extensionTypeName.isEmpty()) + self->m_extensionType = findType(self->m_extensionTypeName); - for (auto it = m_properties.begin(), end = m_properties.end(); it != end; ++it) { + const auto intType = findType(QStringLiteral("int")); + Q_ASSERT(intType); // There always has to be a builtin "int" type + for (auto it = self->m_enumerations.begin(), end = self->m_enumerations.end(); + it != end; ++it) { + auto enumScope = QQmlJSScope::create(EnumScope, self); + enumScope->m_baseTypeName = QStringLiteral("int"); + enumScope->m_baseType = intType; + enumScope->m_semantics = AccessSemantics::Value; + enumScope->m_internalName = self->internalName() + QStringLiteral("::") + it->name(); + it->setType(ConstPtr(enumScope)); + } + + for (auto it = self->m_properties.begin(), end = self->m_properties.end(); it != end; ++it) { const QString typeName = it->typeName(); - if (!it->type() && !typeName.isEmpty()) - it->setType(findType(typeName)); + if (it->type() || typeName.isEmpty()) + continue; + + if (const auto type = findType(typeName)) { + it->setType(type); + continue; + } + + const auto enumeration = self->m_enumerations.find(typeName); + if (enumeration != self->m_enumerations.end()) + it->setType(enumeration->type()); } - for (auto it = m_methods.begin(), end = m_methods.end(); it != end; ++it) { + for (auto it = self->m_methods.begin(), end = self->m_methods.end(); it != end; ++it) { const QString returnTypeName = it->returnTypeName(); if (!it->returnType() && !returnTypeName.isEmpty()) it->setReturnType(findType(returnTypeName)); @@ -238,11 +260,11 @@ void QQmlJSScope::resolveTypes(const QHash<QString, QQmlJSScope::ConstPtr> &cont it->setParameterTypes(paramTypes); } - for (auto it = m_childScopes.begin(), end = m_childScopes.end(); it != end; ++it) { + for (auto it = self->m_childScopes.begin(), end = self->m_childScopes.end(); it != end; ++it) { QQmlJSScope::Ptr childScope = *it; switch (childScope->scopeType()) { case QQmlJSScope::GroupedPropertyScope: - searchBaseAndExtensionTypes(this, [&](const QQmlJSScope *type) { + searchBaseAndExtensionTypes(self.data(), [&](const QQmlJSScope *type) { const auto propertyIt = type->m_properties.find(childScope->internalName()); if (propertyIt != type->m_properties.end()) { childScope->m_baseType = QQmlJSScope::ConstPtr(propertyIt->type()); @@ -261,7 +283,7 @@ void QQmlJSScope::resolveTypes(const QHash<QString, QQmlJSScope::ConstPtr> &cont default: break; } - childScope->resolveTypes(contextualTypes); + resolveTypes(childScope, contextualTypes); } } |