aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2021-06-04 15:59:26 +0200
committerAndrei Golubev <andrei.golubev@qt.io>2021-06-07 13:53:08 +0200
commit9a706f9715d2af914539656d507d149e4cab5c55 (patch)
tree7c47b9f0ed9871008810027597f503f34c664e60 /src
parent4b6655bf98467775f117e3b0edab4731551dbae5 (diff)
QQmlJSScope: add method to query the owner of the property
When calculating absolute property index from the relative QQmlJSMetaProperty::index() value, we need to know the QQmlJSScope that owns the property (to start the value calculation from). The logic of finding the property is non-trivial (due to extension types), so custom QQmlJSScope traversal should really be discouraged While adding a new method, revise existing QQmlJSScope traversal method and make it more generic, so that we could return both (const) QQmlJSScope * and QQmlJSScope::{Ptr, ConstPtr} depending on the use case Change-Id: I84ce038a6a40cdcab3f33ba6a448baa672d62826 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qmlcompiler/qqmljsscope.cpp58
-rw-r--r--src/qmlcompiler/qqmljsscope_p.h3
2 files changed, 56 insertions, 5 deletions
diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp
index 7d5e26bad9..2276c10814 100644
--- a/src/qmlcompiler/qqmljsscope.cpp
+++ b/src/qmlcompiler/qqmljsscope.cpp
@@ -35,16 +35,50 @@
#include <QtCore/qfileinfo.h>
#include <algorithm>
+#include <type_traits>
QT_BEGIN_NAMESPACE
-template<typename Action>
-static bool searchBaseAndExtensionTypes(const QQmlJSScope *type, const Action &check)
+/*! \internal
+
+ Utility method that returns proper value according to the type To. This
+ version returns From.
+*/
+template<typename To, typename From, typename std::enable_if_t<!std::is_pointer_v<To>, int> = 0>
+static auto getQQmlJSScopeFromSmartPtr(const From &p) -> From
+{
+ static_assert(!std::is_pointer_v<From>, "From has to be a smart pointer holding QQmlJSScope");
+ return p;
+}
+
+/*! \internal
+
+ Utility method that returns proper value according to the type To. This
+ version returns From::get(), which is a raw pointer. The returned type is
+ not necessary equal to To (e.g. To might be `QQmlJSScope *` while returned
+ is `const QQmlJSScope *`).
+*/
+template<typename To, typename From, typename std::enable_if_t<std::is_pointer_v<To>, int> = 0>
+static auto getQQmlJSScopeFromSmartPtr(const From &p) -> decltype(p.get())
+{
+ static_assert(!std::is_pointer_v<From>, "From has to be a smart pointer holding QQmlJSScope");
+ return p.get();
+}
+
+template<typename QQmlJSScopePtr, typename Action>
+static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check)
{
- for (const QQmlJSScope *scope = type; scope; scope = scope->baseType().data()) {
+ // NB: among other things, getQQmlJSScopeFromSmartPtr() also resolves const
+ // vs non-const pointer issue, so use it's return value as the type
+ using T = decltype(
+ getQQmlJSScopeFromSmartPtr<QQmlJSScopePtr>(std::declval<QQmlJSScope::ConstPtr>()));
+
+ for (T scope = type; scope;
+ scope = getQQmlJSScopeFromSmartPtr<QQmlJSScopePtr>(scope->baseType())) {
// Extensions override their base types
- for (const QQmlJSScope *extension = scope->extensionType().data(); extension;
- extension = extension->baseType().data()) {
+ for (T extension = getQQmlJSScopeFromSmartPtr<QQmlJSScopePtr>(scope->extensionType());
+ extension;
+ extension = getQQmlJSScopeFromSmartPtr<QQmlJSScopePtr>(extension->baseType())) {
if (check(extension))
return true;
}
@@ -343,6 +377,20 @@ QQmlJSMetaProperty QQmlJSScope::property(const QString &name) const
return prop;
}
+QQmlJSScope::ConstPtr QQmlJSScope::ownerOfProperty(const QQmlJSScope::ConstPtr &self,
+ const QString &name)
+{
+ QQmlJSScope::ConstPtr owner;
+ searchBaseAndExtensionTypes(self, [&](const QQmlJSScope::ConstPtr &scope) {
+ if (scope->hasOwnProperty(name)) {
+ owner = scope;
+ return true;
+ }
+ return false;
+ });
+ return owner;
+}
+
void QQmlJSScope::setPropertyLocallyRequired(const QString &name, bool isRequired)
{
if (!isRequired)
diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h
index fade4d84be..3822cd9c32 100644
--- a/src/qmlcompiler/qqmljsscope_p.h
+++ b/src/qmlcompiler/qqmljsscope_p.h
@@ -248,6 +248,9 @@ public:
bool hasPropertyBinding(const QString &name) const;
QQmlJSMetaPropertyBinding propertyBinding(const QString &name) const;
+ static QQmlJSScope::ConstPtr ownerOfProperty(const QQmlJSScope::ConstPtr &self,
+ const QString &name);
+
bool isResolved() const;
bool isFullyResolved() const;