From 120eb155ef1f0da51c473b080880169a85e5ceb2 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 18 Feb 2021 11:40:31 +0100 Subject: 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 (cherry picked from commit 08c8e8ac3ba8eb23ae5c158990f5d029ac9988ed) --- src/qmlcompiler/qqmljsscope.cpp | 54 +++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 16 deletions(-) (limited to 'src/qmlcompiler/qqmljsscope.cpp') 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{}; } -void QQmlJSScope::resolveTypes(const QHash &contextualTypes) +void QQmlJSScope::resolveTypes(const QQmlJSScope::Ptr &self, + const QHash &contextualTypes) { auto findType = [&](const QString &name) { auto type = contextualTypes.constFind(name); @@ -200,25 +201,46 @@ void QQmlJSScope::resolveTypes(const QHash &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 &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 &cont default: break; } - childScope->resolveTypes(contextualTypes); + resolveTypes(childScope, contextualTypes); } } -- cgit v1.2.3