qmllint: Do not warn about QQmlPropertyMap access

A QQmlPropertyMap can store anything, and we can't know what is
available. Treat it like QVariantMap as far as qmllint is concerned.

Task-number: QTBUG-139240
Pick-to: 6.10
Change-Id: I9ebc0a963159cfc930ff14300df50b6fab5b7035
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Fabian Kosmale 2025-08-18 15:59:55 +02:00
parent 4ab1e09c0e
commit 8721ff9e83
8 changed files with 90 additions and 1 deletions

View File

@ -5,6 +5,7 @@
#define QQMLPROPERTYMAP_H
#include <QtQml/qtqmlglobal.h>
#include <QtQml/qqmlregistration.h>
#include <QtCore/QObject>
#include <QtCore/QHash>
@ -18,6 +19,7 @@ class QQmlPropertyMapPrivate;
class Q_QML_EXPORT QQmlPropertyMap : public QObject
{
Q_OBJECT
QML_ANONYMOUS
public:
explicit QQmlPropertyMap(QObject *parent = nullptr);
~QQmlPropertyMap() override;

View File

@ -109,6 +109,9 @@ QQmlJSTypeResolver::QQmlJSTypeResolver(QQmlJSImporter *importer)
m_varType = builtinTypes.type(u"QVariant"_s).scope;
Q_ASSERT(m_varType);
m_qmlPropertyMapType = builtinTypes.type(u"QQmlPropertyMap"_s).scope;
Q_ASSERT(m_qmlPropertyMapType);
m_jsValueType = builtinTypes.type(u"QJSValue"_s).scope;
Q_ASSERT(m_jsValueType);
@ -1557,7 +1560,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
if (contained == metaObjectType())
return {};
if (contained == variantMapType()) {
if (contained == variantMapType() || contained->inherits(qmlPropertyMapType())) {
QQmlJSMetaProperty prop;
prop.setPropertyName(name);
prop.setTypeName(u"QVariant"_s);

View File

@ -80,6 +80,7 @@ public:
QQmlJSScope::ConstPtr variantListType() const { return m_variantListType; }
QQmlJSScope::ConstPtr variantMapType() const { return m_variantMapType; }
QQmlJSScope::ConstPtr varType() const { return m_varType; }
QQmlJSScope::ConstPtr qmlPropertyMapType() const { return m_qmlPropertyMapType; }
QQmlJSScope::ConstPtr jsValueType() const { return m_jsValueType; }
QQmlJSScope::ConstPtr jsPrimitiveType() const { return m_jsPrimitiveType; }
QQmlJSScope::ConstPtr listPropertyType() const { return m_listPropertyType; }
@ -332,6 +333,7 @@ protected:
QQmlJSScope::ConstPtr m_variantListType;
QQmlJSScope::ConstPtr m_variantMapType;
QQmlJSScope::ConstPtr m_varType;
QQmlJSScope::ConstPtr m_qmlPropertyMapType;
QQmlJSScope::ConstPtr m_jsValueType;
QQmlJSScope::ConstPtr m_jsPrimitiveType;
QQmlJSScope::ConstPtr m_listPropertyType;

View File

@ -0,0 +1,15 @@
import QtQuick
import org.kde.foo
Item {
width: t.map["width"]
height: t.map.height
x: t.derivedMap["x"]
y: t.derivedMap.y
Thing {
id: t
}
}

View File

@ -0,0 +1,47 @@
import QtQuick.tooling 1.2
// This file describes the plugin-supplied types contained in the library.
// It is used for QML tooling purposes only.
//
// This file was auto-generated by qmltyperegistrar.
Module {
Component {
file: "thing.h"
lineNumber: 7
name: "PropMap"
accessSemantics: "reference"
prototype: "QQmlPropertyMap"
exports: ["org.kde.foo/PropMap 254.0"]
exportMetaObjectRevisions: [65024]
}
Component {
file: "thing.h"
lineNumber: 15
name: "Thing"
accessSemantics: "reference"
prototype: "QObject"
exports: ["org.kde.foo/Thing 254.0"]
exportMetaObjectRevisions: [65024]
Property {
name: "map"
type: "QQmlPropertyMap"
isPointer: true
read: "map"
index: 0
isReadonly: true
isFinal: true
isPropertyConstant: true
}
Property {
name: "derivedMap"
type: "PropMap"
isPointer: true
read: "derivedMap"
index: 1
isReadonly: true
isFinal: true
isPropertyConstant: true
}
}
}

View File

@ -0,0 +1,4 @@
module org.kde.foo
typeinfo foo.qmltypes
depends QtQuick

View File

@ -0,0 +1,15 @@
import QtQuick
import org.kde.foo
Item {
width: t.map["width"]
height: t.map.height
x: t.derivedMap["x"]
y: t.derivedMap.y
Thing {
id: t
}
}

View File

@ -2275,6 +2275,7 @@ void TestQmllint::cleanQmlCode_data()
QTest::newRow("prefixedAttachedProperty") << QStringLiteral("prefixedAttachedProperty.qml");
QTest::newRow("propertyBindingValue") << QStringLiteral("propertyBindingValue.qml");
QTest::newRow("propertyDelegate") << QStringLiteral("propertyDelegate.qml");
QTest::newRow("propertyMapUsage") << QStringLiteral("propertyMapUsage.qml");
QTest::newRow("propertyOverride") << QStringLiteral("propertyOverride.qml");
QTest::newRow("propertyWithOn") << QStringLiteral("switcher.qml");
QTest::newRow("qjsroot") << QStringLiteral("qjsroot.qml");