Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmldomtypesreader.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5#include "qqmldomelements_p.h"
6#include "qqmldomcompare_p.h"
8
9#include <QtQml/private/qqmljsparser_p.h>
10#include <QtQml/private/qqmljslexer_p.h>
11#include <QtQml/private/qqmljsengine_p.h>
12#include <private/qqmljstypedescriptionreader_p.h>
13
14#include <QtCore/qdir.h>
15
17
18namespace QQmlJS {
19namespace Dom {
20
21using namespace QQmlJS::AST;
22
24{
25 static ErrorGroups errs = { { NewErrorGroup("Dom"), NewErrorGroup("QmltypesFile"),
26 NewErrorGroup("Parsing") } };
27 return errs;
28}
29
30void QmltypesReader::insertProperty(QQmlJSScope::Ptr jsScope, const QQmlJSMetaProperty &property,
32{
33 PropertyDefinition prop;
34 prop.name = property.propertyName();
35 prop.typeName = property.typeName();
36 prop.isPointer = property.isPointer();
37 prop.isReadonly = !property.isWritable();
38 prop.isRequired = jsScope->isPropertyLocallyRequired(prop.name);
39 prop.isList = property.isList();
40 int revision = property.revision();
41 prop.isFinal = property.isFinal();
42 prop.bindable = property.bindable();
43 prop.read = property.read();
44 prop.write = property.write();
45 prop.notify = property.notify();
46
47 if (prop.name.isEmpty() || prop.typeName.isEmpty()) {
48 addError(readerParseErrors()
49 .warning(tr("Property object is missing a name or type script binding."))
50 .handle());
51 return;
52 }
53 objs[revision].addPropertyDef(prop, AddOption::KeepExisting);
54}
55
56void QmltypesReader::insertSignalOrMethod(const QQmlJSMetaMethod &metaMethod,
58{
59 MethodInfo methodInfo;
60 // ### confusion between Method and Slot. Method should be removed.
61 switch (metaMethod.methodType()) {
62 case QQmlJSMetaMethodType::Method:
63 case QQmlJSMetaMethodType::Slot:
64 methodInfo.methodType = MethodInfo::MethodType::Method;
65 break;
66 case QQmlJSMetaMethodType::Signal:
67 methodInfo.methodType = MethodInfo::MethodType::Signal;
68 break;
69 default:
70 Q_UNREACHABLE();
71 }
72 auto parameters = metaMethod.parameters();
73 qsizetype nParam = parameters.size();
74 for (int i = 0; i < nParam; ++i) {
76 param.name = parameters[i].name();
77 param.typeName = parameters[i].typeName();
78 methodInfo.parameters.append(param);
79 }
80 methodInfo.name = metaMethod.methodName();
81 methodInfo.typeName = metaMethod.returnTypeName();
82 int revision = metaMethod.revision();
83 methodInfo.isConstructor = metaMethod.isConstructor();
84 if (methodInfo.name.isEmpty()) {
85 addError(readerParseErrors().error(tr("Method or signal is missing a name.")).handle());
86 return;
87 }
88
89 objs[revision].addMethod(methodInfo, AddOption::KeepExisting);
90}
91
92EnumDecl QmltypesReader::enumFromMetaEnum(const QQmlJSMetaEnum &metaEnum)
93{
95 res.setName(metaEnum.name());
96 res.setAlias(metaEnum.alias());
97 res.setIsFlag(metaEnum.isFlag());
99 int lastValue = -1;
100 for (const auto &k : metaEnum.keys()) {
101 if (metaEnum.hasValues())
102 lastValue = metaEnum.value(k);
103 else
104 ++lastValue;
105 values.append(EnumItem(k, lastValue));
106 }
107 res.setValues(values);
108 return res;
109}
110
111void QmltypesReader::insertComponent(const QQmlJSScope::Ptr &jsScope,
112 const QList<QQmlJSScope::Export> &exportsList)
113{
115 QMap<int, QmlObject> objects;
116 {
117 bool hasExports = false;
118 for (const QQmlJSScope::Export &jsE : exportsList) {
119 int metaRev = jsE.version().toEncodedVersion<int>();
120 hasExports = true;
121 objects.insert(metaRev, QmlObject());
122 }
123 if (!hasExports)
124 objects.insert(0, QmlObject());
125 }
126 bool incrementedPath = false;
127 QString prototype;
128 QString defaultPropertyName;
129 {
131 auto it = els.cbegin();
132 auto end = els.cend();
133 while (it != end) {
134 insertProperty(jsScope, it.value(), objects);
135 ++it;
136 }
137 }
138 {
140 auto it = els.cbegin();
141 auto end = els.cend();
142 while (it != end) {
143 insertSignalOrMethod(it.value(), objects);
144 ++it;
145 }
146 }
147 {
149 auto it = els.cbegin();
150 auto end = els.cend();
151 while (it != end) {
152 comp.addEnumeration(enumFromMetaEnum(it.value()));
153 ++it;
154 }
155 }
156 comp.setFileName(jsScope->filePath());
157 comp.setName(jsScope->internalName());
158 m_currentPath = m_currentPath.key(comp.name())
159 .index(qmltypesFilePtr()->components().values(comp.name()).size());
160 incrementedPath = true;
161 prototype = jsScope->baseTypeName();
162 defaultPropertyName = jsScope->ownDefaultPropertyName();
163 comp.setInterfaceNames(jsScope->interfaceNames());
165 comp.setAttachedTypeName(typeName);
166 if (!typeName.isEmpty())
167 comp.setAttachedTypePath(Paths::lookupCppTypePath(typeName));
168 comp.setIsSingleton(jsScope->isSingleton());
169 comp.setIsCreatable(jsScope->isCreatable());
170 comp.setIsComposite(jsScope->isComposite());
171 comp.setHasCustomParser(jsScope->hasCustomParser());
172 comp.setValueTypeName(jsScope->valueTypeName());
173 comp.setAccessSemantics(jsScope->accessSemantics());
174 comp.setExtensionTypeName(jsScope->extensionTypeName());
175 comp.setExtensionIsNamespace(jsScope->extensionIsNamespace());
176 Path exportSourcePath = qmltypesFile().canonicalPath();
177 QMap<int, Path> revToPath;
178 auto it = objects.end();
179 auto begin = objects.begin();
180 int objectIndex = 0;
181 QList<int> metaRevs;
182 Path compPath = qmltypesFile()
184 .field(Fields::components)
185 .key(comp.name())
186 .index(qmltypesFilePtr()->components().values(comp.name()).size());
187
188 // emit & map objs
189 while (it != begin) {
190 --it;
191 if (it.key() < 0) {
192 addError(readerParseErrors().error(
193 tr("negative meta revision %1 not supported").arg(it.key())));
194 }
195 revToPath.insert(it.key(), compPath.field(Fields::objects).index(objectIndex));
196 Path nextObjectPath = compPath.field(Fields::objects).index(++objectIndex);
197 if (it == begin) {
198 if (!prototype.isEmpty())
199 it->addPrototypePath(Paths::lookupCppTypePath(prototype));
200 it->setName(prototype);
201 } else {
202 it->addPrototypePath(nextObjectPath);
203 it->setName(comp.name() + QLatin1String("-") + QString::number(it.key()));
204 }
205 comp.addObject(*it);
206 metaRevs.append(it.key());
207 }
208 comp.setMetaRevisions(metaRevs);
209
210 // exports:
211 QList<Export> exports;
212 for (const QQmlJSScope::Export &jsE : exportsList) {
213 auto v = jsE.version();
214 int metaRev = v.toEncodedVersion<int>();
215 Export e;
216 e.uri = jsE.package();
217 e.typeName = jsE.type();
218 e.version = Version((v.hasMajorVersion() ? v.majorVersion() : Version::Latest),
219 (v.hasMinorVersion() ? v.minorVersion() : Version::Latest));
220 e.typePath = revToPath.value(metaRev);
221 if (!e.typePath) {
222 qCWarning(domLog) << "could not find version" << metaRev << "in" << revToPath.keys();
223 }
224 e.exportSourcePath = exportSourcePath;
225 comp.addExport(e);
226 }
227
228 if (comp.name().isEmpty()) {
229 addError(readerParseErrors()
230 .error(tr("Component definition is missing a name binding."))
231 .handle());
232 return;
233 }
234 qmltypesFilePtr()->addComponent(comp, AddOption::KeepExisting);
235 if (incrementedPath)
236 m_currentPath = m_currentPath.dropTail().dropTail();
237}
238
240{
241 QQmlJSTypeDescriptionReader reader(qmltypesFilePtr()->canonicalFilePath(),
242 qmltypesFilePtr()->code());
243 QStringList dependencies;
245 m_isValid = reader(&objects, &dependencies);
246 for (const auto &obj : std::as_const(objects))
247 insertComponent(obj.scope, obj.exports);
248 qmltypesFilePtr()->setIsValid(m_isValid);
249 return m_isValid;
250}
251
252void QmltypesReader::addError(ErrorMessage message)
253{
254 if (message.file.isEmpty())
255 message.file = qmltypesFile().canonicalFilePath();
256 if (!message.path)
257 message.path = m_currentPath;
258 qmltypesFilePtr()->addErrorLocal(message.handle());
259}
260
261} // end namespace Dom
262} // end namespace QQmlJS
\inmodule QtCore
Definition qhash.h:818
const_iterator cbegin() const noexcept
Definition qhash.h:1204
const_iterator cend() const noexcept
Definition qhash.h:1208
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
void append(parameter_type t)
Definition qlist.h:441
Definition qmap.h:186
iterator insert(const Key &key, const T &value)
Definition qmap.h:687
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:356
QList< Key > keys() const
Definition qmap.h:382
iterator begin()
Definition qmap.h:597
iterator end()
Definition qmap.h:601
\inmodule QtCore
Definition qhash.h:1348
const_iterator cbegin() const noexcept
Definition qhash.h:1828
const_iterator cend() const noexcept
Definition qhash.h:1832
int value(const QString &key) const
bool isFlag() const
QString alias() const
QString name() const
bool hasValues() const
bool isConstructor() const
QString methodName() const
QString returnTypeName() const
QList< QQmlJSMetaParameter > parameters() const
QQmlJSMetaMethodType methodType() const
bool isComposite() const
QString filePath() const
QString extensionTypeName() const
QHash< QString, QQmlJSMetaEnum > ownEnumerations() const
bool isSingleton() const
QString baseTypeName() const
QString internalName() const
AccessSemantics accessSemantics() const
QString ownDefaultPropertyName() const
bool hasCustomParser() const
bool isCreatable() const
QString valueTypeName() const
QStringList interfaceNames() const
bool extensionIsNamespace() const
bool isPropertyLocallyRequired(const QString &name) const
QHash< QString, QQmlJSMetaProperty > ownProperties() const
QMultiHash< QString, QQmlJSMetaMethod > ownMethods() const
QString ownAttachedTypeName() const
QString canonicalFilePath()
Represents a set of tags grouping a set of related error messages.
Represents an error message connected to the dom.
Path dropTail(int n=1) const
Path key(QString name) const
Path field(QString name) const
Path index(index_type i) const
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
double e
QSet< QString >::iterator it
Path lookupCppTypePath(QString name)
static ErrorGroups readerParseErrors()
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
#define qCWarning(category,...)
const char * typeName
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
GLuint64 GLenum void * handle
GLint GLenum GLint components
GLuint GLuint end
GLuint GLsizei const GLchar * message
GLenum const GLint * param
GLhandleARB obj
[2]
GLuint res
#define NewErrorGroup(name)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
SSL_CTX int(*) void arg)
#define tr(X)
ptrdiff_t qsizetype
Definition qtypes.h:70
const char property[13]
Definition qwizard.cpp:101
QStringList keys