aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsscope.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-02-18 11:40:31 +0100
committerUlf Hermann <ulf.hermann@qt.io>2021-02-24 08:33:21 +0100
commit120eb155ef1f0da51c473b080880169a85e5ceb2 (patch)
treeb8bc85734d68f125d424b1f45f2576d20c885a43 /src/qmlcompiler/qqmljsscope.cpp
parentae68d95b8c1c56ae907cbe88122dd79bafd20b72 (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.cpp54
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);
}
}