qmllint: Support "length" property of sequence types
In particular, you can set and get the length of QQmlListProperty. Change-Id: I5c8e03a752aad9bf9789faf85a0c3e280f0cbb4b Reviewed-by: Maximilian Goldstein <max.goldstein@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
This commit is contained in:
parent
5a8b5f59e4
commit
a4893077c6
|
@ -90,7 +90,7 @@ QQmlJSTypeResolver::QQmlJSTypeResolver(QQmlJSImporter *importer, const QmlIR::Do
|
||||||
QQmlJSScope::Ptr listPropertyType = QQmlJSScope::create();
|
QQmlJSScope::Ptr listPropertyType = QQmlJSScope::create();
|
||||||
listPropertyType->setInternalName(u"QQmlListProperty<QObject>"_qs);
|
listPropertyType->setInternalName(u"QQmlListProperty<QObject>"_qs);
|
||||||
listPropertyType->setFileName(u"qqmllist.h"_qs);
|
listPropertyType->setFileName(u"qqmllist.h"_qs);
|
||||||
listPropertyType->setAccessSemantics(QQmlJSScope::AccessSemantics::Value);
|
listPropertyType->setAccessSemantics(QQmlJSScope::AccessSemantics::Sequence);
|
||||||
m_listPropertyType = listPropertyType;
|
m_listPropertyType = listPropertyType;
|
||||||
|
|
||||||
// This is pre-sorted. Don't mess it up.
|
// This is pre-sorted. Don't mess it up.
|
||||||
|
@ -754,6 +754,17 @@ bool QQmlJSTypeResolver::checkEnums(const QQmlJSScope::ConstPtr &scope, const QS
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQmlJSRegisterContent QQmlJSTypeResolver::lengthProperty(
|
||||||
|
bool isWritable, const QQmlJSScope::ConstPtr &scope) const
|
||||||
|
{
|
||||||
|
QQmlJSMetaProperty prop;
|
||||||
|
prop.setPropertyName(u"length"_qs);
|
||||||
|
prop.setTypeName(u"int"_qs);
|
||||||
|
prop.setType(intType());
|
||||||
|
prop.setIsWritable(isWritable);
|
||||||
|
return QQmlJSRegisterContent::create(intType(), prop, QQmlJSRegisterContent::Builtin, scope);
|
||||||
|
}
|
||||||
|
|
||||||
QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSScope::ConstPtr &type,
|
QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSScope::ConstPtr &type,
|
||||||
const QString &name) const
|
const QString &name) const
|
||||||
{
|
{
|
||||||
|
@ -769,13 +780,9 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSScope::ConstPtr
|
||||||
QQmlJSRegisterContent::JavaScriptObjectProperty, type);
|
QQmlJSRegisterContent::JavaScriptObjectProperty, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == stringType() && name == u"length"_qs) {
|
if ((type == stringType() || type->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence)
|
||||||
QQmlJSMetaProperty prop;
|
&& name == u"length"_qs) {
|
||||||
prop.setPropertyName(name);
|
return lengthProperty(type != stringType(), type);
|
||||||
prop.setTypeName(u"int"_qs);
|
|
||||||
prop.setType(intType());
|
|
||||||
prop.setIsWritable(false);
|
|
||||||
return QQmlJSRegisterContent::create(intType(), prop, QQmlJSRegisterContent::Builtin, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto check = [&](const QQmlJSScope::ConstPtr &scope, BaseOrExtension mode) {
|
const auto check = [&](const QQmlJSScope::ConstPtr &scope, BaseOrExtension mode) {
|
||||||
|
@ -859,8 +866,8 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSRegisterContent
|
||||||
}
|
}
|
||||||
if (type.isProperty()) {
|
if (type.isProperty()) {
|
||||||
const auto prop = type.property();
|
const auto prop = type.property();
|
||||||
if (prop.isList())
|
if (prop.isList() && name == u"length"_qs)
|
||||||
return {};
|
return lengthProperty(true, listPropertyType());
|
||||||
return memberType(prop.type(), name);
|
return memberType(prop.type(), name);
|
||||||
}
|
}
|
||||||
if (type.isEnumeration()) {
|
if (type.isEnumeration()) {
|
||||||
|
|
|
@ -158,6 +158,7 @@ protected:
|
||||||
bool isNumeric(const QQmlJSScope::ConstPtr &type) const;
|
bool isNumeric(const QQmlJSScope::ConstPtr &type) const;
|
||||||
bool checkEnums(const QQmlJSScope::ConstPtr &scope, const QString &name,
|
bool checkEnums(const QQmlJSScope::ConstPtr &scope, const QString &name,
|
||||||
QQmlJSRegisterContent *result, BaseOrExtension mode) const;
|
QQmlJSRegisterContent *result, BaseOrExtension mode) const;
|
||||||
|
QQmlJSRegisterContent lengthProperty(bool isWritable, const QQmlJSScope::ConstPtr &scope) const;
|
||||||
|
|
||||||
QQmlJSScope::ConstPtr m_voidType;
|
QQmlJSScope::ConstPtr m_voidType;
|
||||||
QQmlJSScope::ConstPtr m_numberType;
|
QQmlJSScope::ConstPtr m_numberType;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
pragma Strict
|
||||||
|
import QtQml
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: self
|
||||||
|
property list<QtObject> items
|
||||||
|
property int numItems: items.length
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
items.length = 3
|
||||||
|
for (var i = 0; i < 3; ++i)
|
||||||
|
items[i] = self
|
||||||
|
}
|
||||||
|
}
|
|
@ -71,6 +71,7 @@ private Q_SLOTS:
|
||||||
void settingsFile();
|
void settingsFile();
|
||||||
|
|
||||||
void additionalImplicitImport();
|
void additionalImplicitImport();
|
||||||
|
void listIndices();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString runQmllint(const QString &fileToLint, std::function<void(QProcess &)> handleResult,
|
QString runQmllint(const QString &fileToLint, std::function<void(QProcess &)> handleResult,
|
||||||
|
@ -947,7 +948,12 @@ void TestQmllint::additionalImplicitImport()
|
||||||
QVERIFY(runQmllint("additionalImplicitImport.qml", true,
|
QVERIFY(runQmllint("additionalImplicitImport.qml", true,
|
||||||
QStringList() << "--resource" << testFile("implicitImportResource.qrc"),
|
QStringList() << "--resource" << testFile("implicitImportResource.qrc"),
|
||||||
false)
|
false)
|
||||||
.isEmpty());
|
.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestQmllint::listIndices()
|
||||||
|
{
|
||||||
|
QVERIFY(runQmllint("listIndices.qml", true, {"--compiler=warning"}, false).isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(TestQmllint)
|
QTEST_MAIN(TestQmllint)
|
||||||
|
|
Loading…
Reference in New Issue