QmlDesigner.MetaInfo: avoid endless recusion into "." properties

Actually "." properties can recurse infinitely.
If a type MyType has the property parenType of MyType and
it is a read only pointer, we get an infinitely recusion into
"." properties.

parentType.parentType.parentType...

Actually this seems to be valid QML and is really the case with Menu.
(In the private API though, indicated by "__")

Since we enumerate "." properties in the Qt Quick Designer, we
run into an infinite loop.

I just cut the recursion at level 3.
So we stop at myParent.myParent.myParent which I think is reasonable.

Change-Id: I80866ace00f940000407cc25cec9ad6fac8b6fee
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
This commit is contained in:
Thomas Hartmann
2013-04-30 10:15:22 +02:00
parent bdeb9371ee
commit 2ee3bae40f

View File

@@ -84,7 +84,7 @@ using namespace QmlJS;
typedef QPair<PropertyName, TypeName> PropertyInfo; typedef QPair<PropertyName, TypeName> PropertyInfo;
QList<PropertyInfo> getObjectTypes(const ObjectValue *ov, const ContextPtr &context, bool local = false); QList<PropertyInfo> getObjectTypes(const ObjectValue *ov, const ContextPtr &context, bool local = false, int rec = 0);
static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context, QList<PropertyInfo> &dotProperties) static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPtr &context, QList<PropertyInfo> &dotProperties)
{ {
@@ -226,7 +226,7 @@ QStringList prototypes(const ObjectValue *ov, const ContextPtr &context, bool ve
return list; return list;
} }
QList<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const ContextPtr &context, bool local = false) QList<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const ContextPtr &context, bool local = false, int rec = 0)
{ {
QList<PropertyInfo> propertyList; QList<PropertyInfo> propertyList;
@@ -235,6 +235,9 @@ QList<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const Cont
if (objectValue->className().isEmpty()) if (objectValue->className().isEmpty())
return propertyList; return propertyList;
if (rec > 2)
return propertyList;
PropertyMemberProcessor processor(context); PropertyMemberProcessor processor(context);
objectValue->processMembers(&processor); objectValue->processMembers(&processor);
@@ -246,7 +249,7 @@ QList<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const Cont
//dot property //dot property
const CppComponentValue * qmlValue = value_cast<CppComponentValue>(objectValue->lookupMember(name, context)); const CppComponentValue * qmlValue = value_cast<CppComponentValue>(objectValue->lookupMember(name, context));
if (qmlValue) { if (qmlValue) {
QList<PropertyInfo> dotProperties = getQmlTypes(qmlValue, context); QList<PropertyInfo> dotProperties = getQmlTypes(qmlValue, context, false, rec + 1);
foreach (const PropertyInfo &propertyInfo, dotProperties) { foreach (const PropertyInfo &propertyInfo, dotProperties) {
PropertyName dotName = propertyInfo.first; PropertyName dotName = propertyInfo.first;
TypeName type = propertyInfo.second; TypeName type = propertyInfo.second;
@@ -258,7 +261,7 @@ QList<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const Cont
if (isValueType(objectValue->propertyType(name))) { if (isValueType(objectValue->propertyType(name))) {
const ObjectValue *dotObjectValue = value_cast<ObjectValue>(objectValue->lookupMember(name, context)); const ObjectValue *dotObjectValue = value_cast<ObjectValue>(objectValue->lookupMember(name, context));
if (dotObjectValue) { if (dotObjectValue) {
QList<PropertyInfo> dotProperties = getObjectTypes(dotObjectValue, context); QList<PropertyInfo> dotProperties = getObjectTypes(dotObjectValue, context, false, rec + 1);
foreach (const PropertyInfo &propertyInfo, dotProperties) { foreach (const PropertyInfo &propertyInfo, dotProperties) {
PropertyName dotName = propertyInfo.first; PropertyName dotName = propertyInfo.first;
TypeName type = propertyInfo.second; TypeName type = propertyInfo.second;
@@ -279,9 +282,9 @@ QList<PropertyInfo> getQmlTypes(const CppComponentValue *objectValue, const Cont
const CppComponentValue * qmlObjectValue = value_cast<CppComponentValue>(prototype); const CppComponentValue * qmlObjectValue = value_cast<CppComponentValue>(prototype);
if (qmlObjectValue) if (qmlObjectValue)
propertyList.append(getQmlTypes(qmlObjectValue, context)); propertyList.append(getQmlTypes(qmlObjectValue, context, false, rec + 1));
else else
propertyList.append(getObjectTypes(prototype, context)); propertyList.append(getObjectTypes(prototype, context, false, rec + 1));
} }
return propertyList; return propertyList;
@@ -327,7 +330,7 @@ QList<PropertyInfo> getTypes(const ObjectValue *objectValue, const ContextPtr &c
return propertyList; return propertyList;
} }
QList<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const ContextPtr &context, bool local) QList<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const ContextPtr &context, bool local, int rec)
{ {
QList<PropertyInfo> propertyList; QList<PropertyInfo> propertyList;
@@ -336,6 +339,9 @@ QList<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Context
if (objectValue->className().isEmpty()) if (objectValue->className().isEmpty())
return propertyList; return propertyList;
if (rec > 2)
return propertyList;
PropertyMemberProcessor processor(context); PropertyMemberProcessor processor(context);
objectValue->processMembers(&processor); objectValue->processMembers(&processor);
@@ -350,9 +356,9 @@ QList<PropertyInfo> getObjectTypes(const ObjectValue *objectValue, const Context
const CppComponentValue * qmlObjectValue = value_cast<CppComponentValue>(prototype); const CppComponentValue * qmlObjectValue = value_cast<CppComponentValue>(prototype);
if (qmlObjectValue) if (qmlObjectValue)
propertyList.append(getQmlTypes(qmlObjectValue, context)); propertyList.append(getQmlTypes(qmlObjectValue, context, local, rec + 1));
else else
propertyList.append(getObjectTypes(prototype, context)); propertyList.append(getObjectTypes(prototype, context, local, rec + 1));
} }
return propertyList; return propertyList;