diff options
author | Maximilian Goldstein <max.goldstein@qt.io> | 2022-02-15 11:57:54 +0100 |
---|---|---|
committer | Maximilian Goldstein <max.goldstein@qt.io> | 2022-02-21 18:46:35 +0100 |
commit | d18b02ef4cd4dbe80554f7d71582d8cd6208dbdb (patch) | |
tree | 3be7e8a645781f77d92575e0ea53dbd842185d4d | |
parent | 9018514022259a35311d82cbd24a4685f3aff9a9 (diff) |
qmllint: Warn about missing property types on current scope
Previously we only warned about missing property types when the lookup
was not on the current scope but only on an id, parent etc.
This change makes sure we also warn in this case and don't produce false
positives for an unqualified access.
Task-number: QTBUG-100839
Change-Id: I732b8420c0c6b96dd8f93cde66a7f9813e704671
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io>
(cherry picked from commit 696f89b1988ed54833406ee8166ffa40e3edaee5)
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/qmlcompiler/qqmljstypepropagator.cpp | 44 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypepropagator_p.h | 1 | ||||
-rw-r--r-- | tests/auto/qml/qmllint/data/incompleteQmltypes3.qml | 6 | ||||
-rw-r--r-- | tests/auto/qml/qmllint/tst_qmllint.cpp | 4 |
4 files changed, 39 insertions, 16 deletions
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp index f4ddc2d8e0..203890d89b 100644 --- a/src/qmlcompiler/qqmljstypepropagator.cpp +++ b/src/qmlcompiler/qqmljstypepropagator.cpp @@ -268,6 +268,9 @@ void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name) const return; } + if (isMissingPropertyType(m_function->qmlScope, name)) + return; + std::optional<FixSuggestion> suggestion; auto childScopes = m_function->qmlScope->childScopes(); @@ -418,6 +421,30 @@ bool QQmlJSTypePropagator::checkRestricted(const QString &propertyName) const return !restrictedKind.isEmpty(); } +// Only to be called once a lookup has already failed +bool QQmlJSTypePropagator::isMissingPropertyType(QQmlJSScope::ConstPtr scope, + const QString &propertyName) const +{ + auto property = scope->property(propertyName); + if (!property.isValid()) + return false; + + QString errorType; + if (property.type().isNull()) + errorType = u"found"_qs; + else if (!property.type()->isFullyResolved()) + errorType = u"fully resolved"_qs; + + Q_ASSERT(!errorType.isEmpty()); + + m_logger->logWarning( + u"Type \"%1\" of property \"%2\" not %3. This is likely due to a missing dependency entry or a type not being exposed declaratively."_qs + .arg(property.typeName(), propertyName, errorType), + Log_Type, getCurrentSourceLocation()); + + return true; +} + void QQmlJSTypePropagator::generate_LoadQmlContextPropertyLookup(int index) { const int nameIndex = m_jsUnitGenerator->lookupNameIndex(index); @@ -603,23 +630,8 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName) auto baseType = m_typeResolver->containedType(m_state.accumulatorIn); // Warn separately when a property is only not found because of a missing type - if (auto property = baseType->property(propertyName); property.isValid()) { - - QString errorType; - if (property.type().isNull()) - errorType = u"found"_qs; - else if (!property.type()->isFullyResolved()) - errorType = u"fully resolved"_qs; - - Q_ASSERT(!errorType.isEmpty()); - - m_logger->logWarning( - u"Type \"%1\" of property \"%2\" not %3. This is likely due to a missing dependency entry or a type not being exposed declaratively."_qs - .arg(property.typeName(), propertyName, errorType), - Log_Type, getCurrentSourceLocation()); - + if (isMissingPropertyType(baseType, propertyName)) return; - } m_logger->logWarning( u"Property \"%1\" not found on type \"%2\""_qs.arg(propertyName).arg(typeName), diff --git a/src/qmlcompiler/qqmljstypepropagator_p.h b/src/qmlcompiler/qqmljstypepropagator_p.h index 1b3af43f60..bab88a003a 100644 --- a/src/qmlcompiler/qqmljstypepropagator_p.h +++ b/src/qmlcompiler/qqmljstypepropagator_p.h @@ -211,6 +211,7 @@ private: void handleUnqualifiedAccess(const QString &name) const; void checkDeprecated(QQmlJSScope::ConstPtr scope, const QString &name, bool isMethod) const; bool checkRestricted(const QString &propertyName) const; + bool isMissingPropertyType(QQmlJSScope::ConstPtr scope, const QString &type) const; QQmlJS::SourceLocation getCurrentSourceLocation() const; QQmlJS::SourceLocation getCurrentBindingSourceLocation() const; diff --git a/tests/auto/qml/qmllint/data/incompleteQmltypes3.qml b/tests/auto/qml/qmllint/data/incompleteQmltypes3.qml new file mode 100644 index 0000000000..142134d49e --- /dev/null +++ b/tests/auto/qml/qmllint/data/incompleteQmltypes3.qml @@ -0,0 +1,6 @@ +import Things 1.0 + +SomethingEntirelyStrange { + id: self + property var a: palette +} diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp index 27af9beed6..7057d31a66 100644 --- a/tests/auto/qml/qmllint/tst_qmllint.cpp +++ b/tests/auto/qml/qmllint/tst_qmllint.cpp @@ -440,6 +440,10 @@ void TestQmllint::dirtyQmlCode_data() << QString("Warning: %1: Cycle2 is part of an inheritance " "cycle: Cycle2 -> Cycle3 -> Cycle1 -> Cycle2") << QString() << QString() << false; + QTest::newRow("incompleteQmltypes3") + << QStringLiteral("incompleteQmltypes3.qml") + << QString("Warning: %1:5:21: Type \"QPalette\" of property \"palette\" not found") + << QString() << QString() << false; QTest::newRow("badQmldirImportAndDepend") << QStringLiteral("qmldirImportAndDepend/bad.qml") << QString("Warning: %1:3:1: Item was not found. Did you add all import paths?") |