diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-01-20 12:17:42 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-01-20 13:33:52 +0100 |
commit | 3ae2a6a47c960d159e1110b434795fc69ecf3d80 (patch) | |
tree | bb703e7dc88eaedb2ac064a345008295eec20fd2 /src/qmlcompiler/qqmljsscope.cpp | |
parent | bf573ad295fbc1eee9379bfaafcded293c4b81f4 (diff) |
qmllint: Support extended types
Fixes: QTBUG-90448
Change-Id: I5fb6b3d9223ae95ca7e039c5b9139ed086052c29
Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljsscope.cpp')
-rw-r--r-- | src/qmlcompiler/qqmljsscope.cpp | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index 202e292838..85c84420a3 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -78,18 +78,38 @@ bool QQmlJSScope::isIdInCurrentScope(const QString &id) const bool QQmlJSScope::hasMethod(const QString &name) const { + const QQmlJSScope *nonCompositeBase = isComposite() ? this : nullptr; for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { if (scope->m_methods.contains(name)) return true; + if (!nonCompositeBase && !scope->isComposite()) + nonCompositeBase = scope; } + + if (nonCompositeBase && nonCompositeBase != this) { + if (QQmlJSScope::ConstPtr extension = nonCompositeBase->extensionType()) + return extension->hasMethod(name); + } + return false; } QList<QQmlJSMetaMethod> QQmlJSScope::methods(const QString &name) const { QList<QQmlJSMetaMethod> results; - for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) + + const QQmlJSScope *nonCompositeBase = isComposite() ? this : nullptr; + for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { results.append(scope->ownMethods(name)); + if (!nonCompositeBase && !scope->isComposite()) + nonCompositeBase = scope; + } + + if (nonCompositeBase && nonCompositeBase != this) { + if (QQmlJSScope::ConstPtr extension = nonCompositeBase->extensionType()) + results.append(extension->methods(name)); + } + return results; } @@ -157,6 +177,9 @@ void QQmlJSScope::resolveTypes(const QHash<QString, QQmlJSScope::ConstPtr> &cont if (!m_valueType && !m_valueTypeName.isEmpty()) m_valueType = findType(m_valueTypeName); + if (!m_extensionType && !m_extensionTypeName.isEmpty()) + m_extensionType = findType(m_extensionTypeName); + for (auto it = m_properties.begin(), end = m_properties.end(); it != end; ++it) { const QString typeName = it->typeName(); if (!it->type() && !typeName.isEmpty()) @@ -192,12 +215,30 @@ void QQmlJSScope::resolveGroupedScopes() continue; const QString propertyName = childScope->internalName(); - for (const QQmlJSScope *type = this; type; type = type->baseType().data()) { + auto findProperty = [&](const QQmlJSScope *type) { auto propertyIt = type->m_properties.find(propertyName); if (propertyIt != type->m_properties.end()) { childScope->m_baseType = QQmlJSScope::ConstPtr(propertyIt->type()); childScope->m_baseTypeName = propertyIt->typeName(); + return true; + } + return false; + }; + + const QQmlJSScope *nonCompositeBase = isComposite() ? this : nullptr; + for (const QQmlJSScope *type = this; type; type = type->baseType().data()) { + if (findProperty(type)) break; + + if (!nonCompositeBase && !type->isComposite()) + nonCompositeBase = type; + } + + if (!childScope->m_baseType && nonCompositeBase && nonCompositeBase != this) { + for (const QQmlJSScope *type = nonCompositeBase->extensionType().data(); type; + type = type->baseType().data()) { + if (findProperty(type)) + break; } } @@ -221,20 +262,40 @@ void QQmlJSScope::addExport(const QString &name, const QString &package, bool QQmlJSScope::hasProperty(const QString &name) const { + const QQmlJSScope *nonCompositeBase = isComposite() ? this : nullptr; for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { if (scope->m_properties.contains(name)) return true; + + if (!nonCompositeBase && !scope->isComposite()) + nonCompositeBase = scope; + } + + if (nonCompositeBase && nonCompositeBase != this) { + if (QQmlJSScope::ConstPtr extension = nonCompositeBase->extensionType()) + return extension->hasProperty(name); } + return false; } QQmlJSMetaProperty QQmlJSScope::property(const QString &name) const { + const QQmlJSScope *nonCompositeBase = isComposite() ? this : nullptr; for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { const auto it = scope->m_properties.find(name); if (it != scope->m_properties.end()) return *it; + + if (!nonCompositeBase && !scope->isComposite()) + nonCompositeBase = scope; } + + if (nonCompositeBase && nonCompositeBase != this) { + if (QQmlJSScope::ConstPtr extension = nonCompositeBase->extensionType()) + return extension->property(name); + } + return {}; } |