diff options
| author | Sami Shalayel <sami.shalayel@qt.io> | 2022-10-11 11:41:13 +0200 |
|---|---|---|
| committer | Sami Shalayel <sami.shalayel@qt.io> | 2022-10-11 15:52:12 +0000 |
| commit | 259ff52e64cd8725bfaa7330a33f8d36456e8b1a (patch) | |
| tree | 910fb64469f29e473cb2699e81e9b4ef3361bdca /src/qmlcompiler/qqmljsutils.cpp | |
| parent | cba96b3a97977f71931f311db9d5644d1d74d694 (diff) | |
qmltc: Remove broken alias optimization
Remove the recursive alias resolution mechanism. It tried to resolve
aliases recursively but only knew the id's of the current component.
This means that an alias pointing to a property defined in another
component (e.g. a different qml file) was resolved using the
id-to-scope map of the component containing the alias property.
This leads to unresolved aliases at best and endless loops when the
aliased property was itself an alias pointing to some property also
existing in the original component (see
QmltcTests/ComponentWithAlias{1..3}.qml for an example).
Also added the reproducer in the qmltc tests.
Fixes: QTBUG-107533
Fixes: QTBUG-107534
Change-Id: Idbf0cff3e45213bc7fbb4a98a9393c6754b00046
Pick-to: 6.4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljsutils.cpp')
| -rw-r--r-- | src/qmlcompiler/qqmljsutils.cpp | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/src/qmlcompiler/qqmljsutils.cpp b/src/qmlcompiler/qqmljsutils.cpp index 229e8f29ad..0ced8254b5 100644 --- a/src/qmlcompiler/qqmljsutils.cpp +++ b/src/qmlcompiler/qqmljsutils.cpp @@ -25,17 +25,23 @@ resolveAlias(ScopeForId scopeForId, const QQmlJSMetaProperty &property, QQmlJSUtils::ResolvedAlias result {}; result.owner = owner; - for (QQmlJSMetaProperty nextProperty = property; nextProperty.isAlias();) { - - // this is a special (seemingly useless) section which is necessary when - // we have an alias pointing to an alias. this way we avoid a check - // whether a property is an alias at the very end of the loop body + // TODO: one could optimize the generated alias code for aliases pointing to aliases + // e.g., if idA.myAlias -> idB.myAlias2 -> idC.myProp, then one could directly generate + // idA.myProp as pointing to idC.myProp. + // This gets complicated when idB.myAlias is in a different Component than where the + // idA.myAlias is defined: scopeForId currently only contains the ids of the current + // component and alias resolution on the ids of a different component fails then. + if (QQmlJSMetaProperty nextProperty = property; nextProperty.isAlias()) { QQmlJSScope::ConstPtr resultOwner = result.owner; result = QQmlJSUtils::ResolvedAlias {}; visitor.reset(); auto aliasExprBits = nextProperty.aliasExpression().split(u'.'); + // do not crash on invalid aliasexprbits when accessing aliasExprBits[0] + if (aliasExprBits.size() < 1) + return {}; + // resolve id first: resultOwner = scopeForId(aliasExprBits[0], resultOwner); if (!resultOwner) @@ -46,8 +52,6 @@ resolveAlias(ScopeForId scopeForId, const QQmlJSMetaProperty &property, aliasExprBits.removeFirst(); // Note: for simplicity, remove the <id> result.owner = resultOwner; result.kind = QQmlJSUtils::AliasTarget_Object; - // reset the property to avoid endless loop when aliasExprBits is empty - nextProperty = QQmlJSMetaProperty {}; for (const QString &bit : std::as_const(aliasExprBits)) { nextProperty = resultOwner->property(bit); |
