Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmljscontextualtypes.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant
4
7
9
10namespace QQmlJS {
11
12void ContextualTypes::setType(const QString &name, const ContextualType &type)
13{
14 const auto it = m_types.find(name);
15 auto insertName = [this, &name, &type]() {
16 if (!name.startsWith(u'$')) {
17 if (!m_names.contains(type.scope, name))
18 m_names.insert(type.scope, name);
19 }
20 };
21 if (const QString fileSelector = QQmlJSUtils::fileSelectorFor(type.scope);
22 !fileSelector.isEmpty()) {
23 setFileSelectedType(fileSelector, name, type);
24 // If a non-selected variant was already added, we're done;
25 // file-selected variants don't replace a main entry. Otherwise we still
26 // need to add the type, in case _all_ variants use file selectors
27 // this assumes that at least one file selector will actually be active
28 if (it == m_types.end()) {
29 m_types.insert(name, type);
30 insertName();
31 }
32 return;
33 }
34
35 if (it == m_types.end()) {
36 m_types.insert(name, type);
37 insertName();
38 return;
39 }
40
41 if (it->m_precedence < type.m_precedence)
42 return;
43 // The old scope keeps its (scope, name) link in m_names only if it remains
44 // referenced via m_fileSelectedTypes for the same name.
45 const QQmlJSScope::ConstPtr oldScope = it->scope;
46 *it = type;
47 const bool isOldScopeStillRefencedAsFileSelected = [&]() {
48 for (auto [it, end] = m_fileSelectedTypes.equal_range(name); it != end; ++it) {
49 if (it->type.scope == oldScope)
50 return true;
51 }
52 return false;
53 }();
54 if (!isOldScopeStillRefencedAsFileSelected)
55 m_names.remove(oldScope, name);
56 insertName();
57}
58
59void ContextualTypes::setFileSelectedType(const QString &fileSelector, const QString &name,
60 const ContextualType &type)
61{
62 auto insertName = [this, &name, &type]() {
63 if (!name.startsWith(u'$')) {
64 if (!m_names.contains(type.scope, name))
65 m_names.insert(type.scope, name);
66 }
67 };
68
69 auto [it, end] = m_fileSelectedTypes.equal_range(name);
70 auto match = std::find_if(it, end, [&fileSelector](const FileSelectedType &entry) {
71 return entry.fileSelector == fileSelector;
72 });
73 if (match == end) {
74 insertName();
75 m_fileSelectedTypes.insert(name, { fileSelector, type });
76 return;
77 }
78
79 if (match->type.m_precedence < type.m_precedence)
80 return;
81
82 m_names.remove(type.scope, name);
83 *it = { fileSelector, type };
84
85 insertName();
86}
87
88std::optional<ContextualType>
89ContextualTypes::fileSelectedTypeFor(const QString &name, const QString &selector) const
90{
91 Q_ASSERT(!selector.isEmpty());
92 for (auto [it, end] = m_fileSelectedTypes.equal_range(name); it != end; ++it) {
93 if (it->fileSelector == selector)
94 return it->type;
95 }
96 return std::nullopt;
97}
98
99FileSelectorInfo ContextualTypes::fileSelectorInfoFor(const QQmlJSScope::ConstPtr &scope) const
100{
101 FileSelectorInfo result;
102 for (auto [it, end] = m_names.equal_range(scope); it != end; ++it) {
103 if (auto mainTypeIt = m_types.find(*it); mainTypeIt != m_types.end())
104 result.mainType = mainTypeIt->scope;
105
106 for (auto [it2, end2] = m_fileSelectedTypes.equal_range(*it); it2 != end2; ++it2) {
107 result.fileSelectedTypes.append(*it2);
108 }
109 }
110 return result;
111}
112} // namespace QQmlJS
113
114QT_END_NAMESPACE
Combined button and popup list for selecting options.
std::optional< ContextualType > fileSelectedTypeFor(const QString &name, const QString &selector) const
void setType(const QString &name, const ContextualType &type)
void setFileSelectedType(const QString &fileSelector, const QString &name, const ContextualType &type)