1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef QQMLJSSCOPESBYID_P_H
5#define QQMLJSSCOPESBYID_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16
17
18#include "qqmljsscope_p.h"
19
20#include <QtCore/qhash.h>
21#include <QtCore/qstring.h>
22
23QT_BEGIN_NAMESPACE
24
25enum QQmlJSScopesByIdOption: char {
26 Default = 0,
27 AssumeComponentsAreBound = 1,
28};
29Q_DECLARE_FLAGS(QQmlJSScopesByIdOptions, QQmlJSScopesByIdOption);
30
31class QQmlJSScopesById
32{
33public:
34 bool componentsAreBound() const { return m_componentsAreBound; }
35 void setComponentsAreBound(bool bound) { m_componentsAreBound = bound; }
36
37 void setSignaturesAreEnforced(bool enforced) { m_signaturesAreEnforced = enforced; }
38 bool signaturesAreEnforced() const { return m_signaturesAreEnforced; }
39
40 void setValueTypesAreAddressable(bool addressable) { m_valueTypesAreAddressable = addressable; }
41 bool valueTypesAreAddressable() const { return m_valueTypesAreAddressable; }
42
43 QString id(const QQmlJSScope::ConstPtr &scope, const QQmlJSScope::ConstPtr &referrer,
44 QQmlJSScopesByIdOptions options = Default) const
45 {
46 const QQmlJSScope::ConstPtr referrerRoot = componentRoot(inner: referrer);
47 for (auto it = m_scopesById.begin(), end = m_scopesById.end(); it != end; ++it) {
48 if (*it == scope && isComponentVisible(observed: componentRoot(inner: *it), observer: referrerRoot, options))
49 return it.key();
50 }
51 return QString();
52 }
53
54 /*!
55 \internal
56 Returns the scope that has id \a id in the component to which \a referrer belongs to.
57 If no such scope exists, a null scope is returned.
58 */
59 QQmlJSScope::ConstPtr scope(const QString &id, const QQmlJSScope::ConstPtr &referrer,
60 QQmlJSScopesByIdOptions options = Default) const
61 {
62 Q_ASSERT(!id.isEmpty());
63 const auto range = m_scopesById.equal_range(key: id);
64 if (range.first == range.second)
65 return QQmlJSScope::ConstPtr();
66 const QQmlJSScope::ConstPtr referrerRoot = componentRoot(inner: referrer);
67
68 for (auto it = range.first; it != range.second; ++it) {
69 if (isComponentVisible(observed: componentRoot(inner: *it), observer: referrerRoot, options))
70 return *it;
71 }
72
73 return QQmlJSScope::ConstPtr();
74 }
75
76 void insert(const QString &id, const QQmlJSScope::ConstPtr &scope)
77 {
78 Q_ASSERT(!id.isEmpty());
79 m_scopesById.insert(key: id, value: scope);
80 }
81
82 void clear() { m_scopesById.clear(); }
83
84 /*!
85 \internal
86 Returns \c true if \a id exists anywhere in the current document.
87 This is still allowed if the other occurrence is in a different (inline) component.
88 Check the return value of scope to know whether the id has already been assigned
89 in a givne scope.
90 */
91 bool existsAnywhereInDocument(const QString &id) const { return m_scopesById.contains(key: id); }
92
93private:
94 static QQmlJSScope::ConstPtr componentRoot(const QQmlJSScope::ConstPtr &inner)
95 {
96 QQmlJSScope::ConstPtr scope = inner;
97 while (scope && !scope->isComponentRootElement() && !scope->isInlineComponent()) {
98 if (QQmlJSScope::ConstPtr parent = scope->parentScope())
99 scope = parent;
100 else
101 break;
102 }
103 return scope;
104 }
105
106 bool isComponentVisible(const QQmlJSScope::ConstPtr &observed,
107 const QQmlJSScope::ConstPtr &observer,
108 QQmlJSScopesByIdOptions options) const
109 {
110 if (!m_componentsAreBound && !options.testAnyFlag(flag: AssumeComponentsAreBound))
111 return observed == observer;
112
113 for (QQmlJSScope::ConstPtr scope = observer; scope; scope = scope->parentScope()) {
114 if (scope == observed)
115 return true;
116 }
117
118 return false;
119 }
120
121 QMultiHash<QString, QQmlJSScope::ConstPtr> m_scopesById;
122 bool m_componentsAreBound = false;
123 bool m_signaturesAreEnforced = true;
124 bool m_valueTypesAreAddressable = false;
125};
126
127QT_END_NAMESPACE
128
129#endif // QQMLJSSCOPESBYID_P_H
130

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtdeclarative/src/qmlcompiler/qqmljsscopesbyid_p.h