Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmlcustomparser.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <private/qv4compileddata_p.h>
8#include <private/qqmlsourcecoordinate_p.h>
9
10#include <QtCore/qdebug.h>
11
13
30/*
31 \fn QByteArray QQmlCustomParser::compile(const QList<QQmlCustomParserProperty> & properties)
32
33 The custom parser processes \a properties, and returns
34 a QByteArray containing data meaningful only to the
35 custom parser; the type engine will pass this same data to
36 setCustomData() when making an instance of the data.
37
38 Errors must be reported via the error() functions.
39
40 The QByteArray may be cached between executions of the system, so
41 it must contain correctly-serialized data (not, for example,
42 pointers to stack objects).
43*/
44
45/*
46 \fn void QQmlCustomParser::setCustomData(QObject *object, const QByteArray &data)
47
48 This function sets \a object to have the properties defined
49 by \a data, which is a block of data previously returned by a call
50 to compile().
51
52 Errors should be reported using qmlWarning(object).
53
54 The \a object will be an instance of the TypeClass specified by QML_REGISTER_CUSTOM_TYPE.
55*/
56
58{
59 exceptions.clear();
60}
61
68{
72 error.setDescription(description);
73
74 exceptions << error;
75}
76
85int QQmlCustomParser::evaluateEnum(const QString &script, bool *ok) const
86{
87 Q_ASSERT_X(ok, "QQmlCustomParser::evaluateEnum", "ok must not be a null pointer");
88 *ok = false;
89
90 // we support one or two '.' in the enum phrase:
91 // * <TypeName>.<EnumValue>
92 // * <TypeName>.<ScopedEnumName>.<EnumValue>
93
94 auto nextDot = [&](int dot) {
95 const int nextDot = script.indexOf(u'.', dot + 1);
96 return (nextDot == script.size() - 1) ? -1 : nextDot;
97 };
98
99 int dot = nextDot(-1);
100 if (dot == -1)
101 return -1;
102
103 const QString scope = script.left(dot);
104
105 if (scope != QLatin1String("Qt")) {
106 if (imports.isNull())
107 return -1;
109
110 if (imports.isT1()) {
111 QQmlImportNamespace *ns = nullptr;
112
113 // Pass &recursionDetected to resolveType because that implicitly allows recursion.
114 // This way we can find the QQmlType of the document we're currently validating.
115 bool recursionDetected = false;
116
117 if (!imports.asT1()->resolveType(
118 scope, &type, nullptr, &ns, nullptr,
119 QQmlType::AnyRegistrationType, &recursionDetected)) {
120 return -1;
121 }
122
123 if (!type.isValid() && ns != nullptr) {
124 dot = nextDot(dot);
125 if (dot == -1 || !imports.asT1()->resolveType(
126 script.left(dot), &type, nullptr, nullptr, nullptr,
127 QQmlType::AnyRegistrationType, &recursionDetected)) {
128 return -1;
129 }
130 }
131 } else {
132 // Allow recursion so that we can find enums from the same document.
134 = imports.asT2()->query<QQmlImport::AllowRecursion>(scope);
135 if (result.isValid()) {
136 type = result.type;
137 } else if (result.importNamespace) {
138 dot = nextDot(dot);
139 if (dot != -1)
140 type = imports.asT2()->query<QQmlImport::AllowRecursion>(script.left(dot)).type;
141 }
142 }
143
144 if (!type.isValid())
145 return -1;
146
147 const int dot2 = nextDot(dot);
148 const bool dot2Valid = (dot2 != -1);
149 const QString enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
150 const QString scopedEnumName = dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QString();
151
152 // If we're currently validating the same document, we won't be able to find its enums using
153 // the QQmlType. However, we do have the property cache already, and that one contains the
154 // enums.
155 const QUrl documentUrl = validator ? validator->documentSourceUrl() : QUrl();
156 if (documentUrl.isValid() && documentUrl == type.sourceUrl()) {
157 Q_ASSERT(validator);
158 const QQmlPropertyCache::ConstPtr rootCache = validator->rootPropertyCache();
159 const int count = rootCache->qmlEnumCount();
160 for (int ii = 0; ii < count; ++ii) {
161 const QQmlEnumData *enumData = rootCache->qmlEnum(ii);
162 if (!scopedEnumName.isEmpty() && scopedEnumName != enumData->name)
163 continue;
164
165 for (int jj = 0; jj < enumData->values.size(); ++jj) {
166 const QQmlEnumValue value = enumData->values.at(jj);
167 if (value.namedValue == enumValue) {
168 *ok = true;
169 return value.value;
170 }
171 }
172 }
173 return -1;
174 }
175
176 if (!scopedEnumName.isEmpty())
177 return type.scopedEnumValue(engine, scopedEnumName, enumValue, ok);
178 else
179 return type.enumValue(engine, enumValue, ok);
180 }
181
182 const QString enumValue = script.mid(dot + 1);
183 const QMetaObject *mo = &Qt::staticMetaObject;
184 int i = mo->enumeratorCount();
185 while (i--) {
186 int v = mo->enumerator(i).keyToValue(enumValue.toUtf8().constData(), ok);
187 if (*ok)
188 return v;
189 }
190 return -1;
191}
192
198{
199 if (!imports.isT1())
200 return nullptr;
201 QQmlType qmltype;
202 if (!imports.asT1()->resolveType(name, &qmltype, nullptr, nullptr, nullptr))
203 return nullptr;
204 return qmltype.metaObject();
205}
206
T * asT1() const
bool isNull() const
bool isT1() const
T2 * asT2() const
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
const QMetaObject * resolveType(const QString &) const
Resolves name to a type, or 0 if it is not a type.
void error(const QV4::CompiledData::Binding *binding, const QString &description)
int evaluateEnum(const QString &, bool *ok) const
If script is a simple enumeration expression (eg.
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
bool resolveType(const QHashedStringRef &type, QQmlType *type_return, QTypeRevision *version_return, QQmlImportNamespace **ns_return, QList< QQmlError > *errors=nullptr, QQmlType::RegistrationType registrationType=QQmlType::AnyRegistrationType, bool *typeRecursionDetected=nullptr) const
QQmlPropertyCache::ConstPtr rootPropertyCache() const
Result query(const QHashedStringRef &key) const
@ AnyRegistrationType
Definition qqmltype_p.h:158
const QMetaObject * metaObject() const
Definition qqmltype.cpp:658
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
QByteArray toUtf8() const &
Definition qstring.h:563
\inmodule QtCore
Definition qurl.h:94
bool isValid() const
Returns true if the URL is non-empty and valid; otherwise returns false.
Definition qurl.cpp:1874
auto mo
[7]
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLint location
GLsizei const GLfloat * v
[13]
GLenum GLenum GLsizei count
GLenum type
GLuint name
GLuint64EXT * result
[6]
static qreal dot(const QPointF &a, const QPointF &b)
int qmlConvertSourceCoordinate< quint32, int >(quint32 n)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
\inmodule QtCore
QVector< QQmlEnumValue > values