qmllint: Do not warn when accessing properties of global constructors

We are treating global constructor functions as methods. But while they
are callable, they also have properties that can be accessed.
Accessing those should not trigger any warning. However, prior to this
commit, any property access to a method would yield a warning.
As we don't store the list of known properties in the
jsroot.qmltypes, we cannot really validate them. Moreover, it is also
possilbe to extend the prototypes, so it might never be feasible to
generate warnings.
Thus, for now simply don't create warnings for JS globals in
QQmlJSTypePropagator::isRestricted.

Fixes: QTBUG-109204
Pick-to: 6.5 6.4
Change-Id: I992365ea716827a562886d7204b2401062772f9a
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Fabian Kosmale 2023-01-04 14:35:17 +01:00
parent 0c5821b366
commit 59d6cf324d
3 changed files with 22 additions and 0 deletions

View File

@ -487,6 +487,22 @@ bool QQmlJSTypePropagator::isRestricted(const QString &propertyName) const
restrictedKind = u"an unscoped enum"_s;
}
} else if (accumulatorIn.value().content.isMethod()) {
auto overloadSet = accumulatorIn.value().content.method();
auto potentiallyJSMethod = std::any_of(
overloadSet.cbegin(), overloadSet.cend(),
[](const QQmlJSMetaMethod &overload){
return overload.isJavaScriptFunction();
});
if (potentiallyJSMethod) {
/* JS global constructors like Number get detected as methods
However, they still have properties that can be accessed
e.g. Number.EPSILON. This also isn't restricted to constructor
functions, so use isJavaScriptFunction as an overapproximation.
That catches also QQmlV4Function, but we're purging uses of it
anyway.
*/
return false;
}
restrictedKind = u"a method"_s;
}

View File

@ -0,0 +1,5 @@
import QtQml
QtObject {
property double f: Number.EPSILON
}

View File

@ -1198,6 +1198,7 @@ void TestQmllint::cleanQmlCode_data()
QTest::newRow("qtquickdialog") << QStringLiteral("qtquickdialog.qml");
QTest::newRow("callBase") << QStringLiteral("callBase.qml");
QTest::newRow("propertyWithOn") << QStringLiteral("switcher.qml");
QTest::newRow("constructorProperty") << QStringLiteral("constructorProperty.qml");
}
void TestQmllint::cleanQmlCode()