Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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 LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
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(
32 QMap<int, QmlObject> &objs)
33{
35 prop.name = property.propertyName();
36 prop.typeName = property.typeName();
37 prop.isPointer = property.isPointer();
38 prop.isReadonly = !property.isWritable();
39 prop.isRequired = jsScope->isPropertyLocallyRequired(prop.name);
40 prop.isList = property.isList();
41 int revision = property.revision();
42 prop.isFinal = property.isFinal();
43 prop.bindable = property.bindable();
44 prop.read = property.read();
45 prop.write = property.write();
46 prop.notify = property.notify();
47
48 if (prop.name.isEmpty() || prop.typeName.isEmpty()) {
49 addError(readerParseErrors()
50 .warning(tr("Property object is missing a name or type script binding."))
51 .handle());
52 return;
53 }
54 objs[revision].addPropertyDef(prop, AddOption::KeepExisting);
55}
56
57void QmltypesReader::insertSignalOrMethod(const QQmlJSMetaMethod &metaMethod,
58 QMap<int, QmlObject> &objs)
59{
60 MethodInfo methodInfo;
61 // ### confusion between Method and Slot. Method should be removed.
62 switch (metaMethod.methodType()) {
63 case QQmlJSMetaMethodType::Method:
64 case QQmlJSMetaMethodType::Slot:
65 methodInfo.methodType = MethodInfo::MethodType::Method;
66 break;
67 case QQmlJSMetaMethodType::Signal:
68 methodInfo.methodType = MethodInfo::MethodType::Signal;
69 break;
70 default:
71 Q_UNREACHABLE();
72 }
73 auto parameters = metaMethod.parameters();
74 qsizetype nParam = parameters.size();
75 for (int i = 0; i < nParam; ++i) {
77 param.name = parameters[i].name();
78 param.typeName = parameters[i].typeName();
79 methodInfo.parameters.append(param);
80 }
81 methodInfo.name = metaMethod.methodName();
82 methodInfo.typeName = metaMethod.returnTypeName();
83 int revision = metaMethod.revision();
84 methodInfo.isConstructor = metaMethod.isConstructor();
85 if (methodInfo.name.isEmpty()) {
86 addError(readerParseErrors().error(tr("Method or signal is missing a name.")).handle());
87 return;
88 }
89
90 objs[revision].addMethod(methodInfo, AddOption::KeepExisting);
91}
92
93EnumDecl QmltypesReader::enumFromMetaEnum(const QQmlJSMetaEnum &metaEnum)
94{
96 res.setName(metaEnum.name());
97 res.setAlias(metaEnum.alias());
98 res.setIsFlag(metaEnum.isFlag());
99 QList<EnumItem> values;
100 int lastValue = -1;
101 for (const auto &k : metaEnum.keys()) {
102 if (metaEnum.hasValues())
103 lastValue = metaEnum.value(k);
104 else
105 ++lastValue;
106 values.append(EnumItem(k, lastValue));
107 }
108 res.setValues(values);
109 return res;
110}
111
112void QmltypesReader::insertComponent(const QQmlJSScope::ConstPtr &jsScope,
113 const QList<QQmlJSScope::Export> &exportsList)
114{
116 comp.setSemanticScope(jsScope);
117 QMap<int, QmlObject> objects;
118 {
119 bool hasExports = false;
120 for (const QQmlJSScope::Export &jsE : exportsList) {
121 int metaRev = jsE.version().toEncodedVersion<int>();
122 hasExports = true;
124 object.setSemanticScope(jsScope);
125 objects.insert(metaRev, object);
126 }
127 if (!hasExports) {
129 object.setSemanticScope(jsScope);
130 objects.insert(0, object);
131 }
132 }
133 bool incrementedPath = false;
134 QString prototype;
135 QString defaultPropertyName;
136 {
137 QHash<QString, QQmlJSMetaProperty> els = jsScope->ownProperties();
138 auto it = els.cbegin();
139 auto end = els.cend();
140 while (it != end) {
141 insertProperty(jsScope, it.value(), objects);
142 ++it;
143 }
144 }
145 {
146 QMultiHash<QString, QQmlJSMetaMethod> els = jsScope->ownMethods();
147 auto it = els.cbegin();
148 auto end = els.cend();
149 while (it != end) {
150 insertSignalOrMethod(it.value(), objects);
151 ++it;
152 }
153 }
154 {
155 QHash<QString, QQmlJSMetaEnum> els = jsScope->ownEnumerations();
156 auto it = els.cbegin();
157 auto end = els.cend();
158 while (it != end) {
159 comp.addEnumeration(enumFromMetaEnum(it.value()));
160 ++it;
161 }
162 }
163 comp.setFileName(jsScope->filePath());
164 comp.setName(jsScope->internalName());
165 m_currentPath = m_currentPath.key(comp.name())
166 .index(qmltypesFilePtr()->components().values(comp.name()).size());
167 incrementedPath = true;
168 prototype = jsScope->baseTypeName();
169 defaultPropertyName = jsScope->ownDefaultPropertyName();
170 comp.setInterfaceNames(jsScope->interfaceNames());
171 QString typeName = jsScope->ownAttachedTypeName();
172 comp.setAttachedTypeName(typeName);
173 if (!typeName.isEmpty())
174 comp.setAttachedTypePath(Paths::lookupCppTypePath(typeName));
175 comp.setIsSingleton(jsScope->isSingleton());
176 comp.setIsCreatable(jsScope->isCreatable());
177 comp.setIsComposite(jsScope->isComposite());
178 comp.setHasCustomParser(jsScope->hasCustomParser());
179 comp.setValueTypeName(jsScope->valueTypeName());
180 comp.setAccessSemantics(jsScope->accessSemantics());
181 comp.setExtensionTypeName(jsScope->extensionTypeName());
182 comp.setExtensionIsJavaScript(jsScope->extensionIsJavaScript());
183 comp.setExtensionIsNamespace(jsScope->extensionIsNamespace());
184 Path exportSourcePath = qmltypesFile().canonicalPath();
185 QMap<int, Path> revToPath;
186 auto it = objects.end();
187 auto begin = objects.begin();
188 int objectIndex = 0;
189 QList<int> metaRevs;
190 Path compPath = qmltypesFile()
192 .field(Fields::components)
193 .key(comp.name())
194 .index(qmltypesFilePtr()->components().values(comp.name()).size());
195
196 // emit & map objs
197 while (it != begin) {
198 --it;
199 if (it.key() < 0) {
200 addError(readerParseErrors().error(
201 tr("negative meta revision %1 not supported").arg(it.key())));
202 }
203 revToPath.insert(it.key(), compPath.field(Fields::objects).index(objectIndex));
204 Path nextObjectPath = compPath.field(Fields::objects).index(++objectIndex);
205 if (it == begin) {
206 if (!prototype.isEmpty())
207 it->addPrototypePath(Paths::lookupCppTypePath(prototype));
208 it->setName(prototype);
209 } else {
210 it->addPrototypePath(nextObjectPath);
211 it->setName(comp.name() + QLatin1String("-") + QString::number(it.key()));
212 }
213 comp.addObject(*it);
214 metaRevs.append(it.key());
215 }
216 comp.setMetaRevisions(metaRevs);
217
218 // exports:
219 QList<Export> exports;
220 for (const QQmlJSScope::Export &jsE : exportsList) {
221 auto v = jsE.version();
222 int metaRev = v.toEncodedVersion<int>();
223 Export e;
224 e.uri = jsE.package();
225 e.typeName = jsE.type();
226 e.isSingleton = jsScope->isSingleton();
227 e.version = Version((v.hasMajorVersion() ? v.majorVersion() : Version::Latest),
228 (v.hasMinorVersion() ? v.minorVersion() : Version::Latest));
229 e.typePath = revToPath.value(metaRev);
230 if (!e.typePath) {
231 qCWarning(domLog) << "could not find version" << metaRev << "in" << revToPath.keys();
232 }
233 e.exportSourcePath = exportSourcePath;
234 comp.addExport(e);
235 }
236
237 if (comp.name().isEmpty()) {
238 addError(readerParseErrors()
239 .error(tr("Component definition is missing a name binding."))
240 .handle());
241 return;
242 }
243 qmltypesFilePtr()->addComponent(comp, AddOption::KeepExisting);
244 if (incrementedPath)
245 m_currentPath = m_currentPath.dropTail().dropTail();
246}
247
249{
250 QQmlJSTypeDescriptionReader reader(qmltypesFilePtr()->canonicalFilePath(),
251 qmltypesFilePtr()->code());
252 QStringList dependencies;
253 QList<QQmlJSExportedScope> objects;
254 const bool isValid = reader(&objects, &dependencies);
255 for (const auto &obj : std::as_const(objects))
256 insertComponent(obj.scope, obj.exports);
257 qmltypesFilePtr()->setIsValid(isValid);
258 return isValid;
259}
260
261void QmltypesReader::addError(ErrorMessage &&message)
262{
263 if (message.file.isEmpty())
264 message.file = qmltypesFile().canonicalFilePath();
265 if (!message.path)
266 message.path = m_currentPath;
267 qmltypesFilePtr()->addErrorLocal(message.handle());
268}
269
270} // end namespace Dom
271} // end namespace QQmlJS
qsizetype size() const noexcept
Definition qlist.h:397
bool isConstructor() const
QString methodName() const
QString returnTypeName() const
QList< QQmlJSMetaParameter > parameters() const
QQmlJSMetaMethodType methodType() const
QString canonicalFilePath() const
Path canonicalPath() const
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(const QString &name) const
Path field(const QString &name) const
Path index(index_type i) const
const_iterator cbegin() const noexcept
Definition qset.h:138
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
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:8084
QSet< QString >::iterator it
Path lookupCppTypePath(const 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 object
[3]
GLuint GLsizei const GLchar * message
GLenum const GLint * param
GLhandleARB obj
[2]
GLuint res
#define NewErrorGroup(name)
QDebug warning(QAnyStringView fileName, int lineNumber)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
SSL_CTX int void * arg
#define tr(X)
ptrdiff_t qsizetype
Definition qtypes.h:165
const char property[13]
Definition qwizard.cpp:101
QStringList keys