Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmldomexternalitems_p.h
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
4#ifndef QQMLDOMEXTERNALITEMS_P_H
5#define QQMLDOMEXTERNALITEMS_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 "qqmldomitem_p.h"
19#include "qqmldomelements_p.h"
21#include "qqmldomcomments_p.h"
22
23#include <QtQml/private/qqmljsast_p.h>
24#include <QtQml/private/qqmljsengine_p.h>
25#include <QtQml/private/qqmldirparser_p.h>
26#include <QtQmlCompiler/private/qqmljstyperesolver_p.h>
27#include <QtCore/QMetaType>
28
29#include <limits>
30#include <memory>
31
33
35
36namespace QQmlJS {
37namespace Dom {
38
50public:
51 ExternalOwningItem(QString filePath, QDateTime lastDataUpdateAt, Path pathFromTop,
52 int derivedFrom = 0, QString code = QString());
54 QString canonicalFilePath(DomItem &) const override;
55 QString canonicalFilePath() const;
56 Path canonicalPath(DomItem &) const override;
57 Path canonicalPath() const;
58 bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override
59 {
60 bool cont = OwningItem::iterateDirectSubpaths(self, visitor);
61 cont = cont && self.dvValueLazyField(visitor, Fields::canonicalFilePath, [this]() {
62 return canonicalFilePath();
63 });
64 cont = cont
65 && self.dvValueLazyField(visitor, Fields::isValid, [this]() { return isValid(); });
66 if (!code().isNull())
67 cont = cont
68 && self.dvValueLazyField(visitor, Fields::code, [this]() { return code(); });
69 return cont;
70 }
71
72 bool iterateSubOwners(DomItem &self, function_ref<bool(DomItem &owner)> visitor) override
73 {
74 bool cont = OwningItem::iterateSubOwners(self, visitor);
75 cont = cont && self.field(Fields::components).visitKeys([visitor](QString, DomItem &comps) {
76 return comps.visitIndexes([visitor](DomItem &comp) {
77 return comp.field(Fields::objects).visitIndexes([visitor](DomItem &qmlObj) {
78 if (const QmlObject *qmlObjPtr = qmlObj.as<QmlObject>())
79 return qmlObjPtr->iterateSubOwners(qmlObj, visitor);
80 Q_ASSERT(false);
81 return true;
82 });
83 });
84 });
85 return cont;
86 }
87
88 bool isValid() const {
90 return m_isValid;
91 }
92 void setIsValid(bool val) {
94 m_isValid = val;
95 }
96 // null code means invalid
97 const QString &code() const { return m_code; }
98
99protected:
103 bool m_isValid = false;
104};
105
107{
108protected:
109 std::shared_ptr<OwningItem> doCopy(DomItem &) const override
110 {
111 return std::make_shared<QmlDirectory>(*this);
112 }
113
114public:
115 constexpr static DomType kindValue = DomType::QmlDirectory;
116 DomType kind() const override { return kindValue; }
117 QmlDirectory(QString filePath = QString(), QStringList dirList = QStringList(),
119 int derivedFrom = 0);
120 QmlDirectory(const QmlDirectory &o) = default;
121
122 std::shared_ptr<QmlDirectory> makeCopy(DomItem &self) const
123 {
124 return std::static_pointer_cast<QmlDirectory>(doCopy(self));
125 }
126
127 bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override;
128
129 const QMultiMap<QString, Export> &exports() const & { return m_exports; }
130
131 const QMultiMap<QString, QString> &qmlFiles() const & { return m_qmlFiles; }
132
133 bool addQmlFilePath(QString relativePath);
134
135private:
138};
139
141{
143protected:
144 std::shared_ptr<OwningItem> doCopy(DomItem &) const override
145 {
146 auto copy = std::make_shared<QmldirFile>(*this);
147 return copy;
148 }
149
150public:
151 constexpr static DomType kindValue = DomType::QmldirFile;
152 DomType kind() const override { return kindValue; }
153
154 static ErrorGroups myParsingErrors();
155
156 QmldirFile(QString filePath = QString(), QString code = QString(),
158 int derivedFrom = 0)
159 : ExternalOwningItem(filePath, lastDataUpdateAt, Paths::qmldirFilePath(filePath),
160 derivedFrom, code)
161 {
162 }
163 QmldirFile(const QmldirFile &o) = default;
164
165 static std::shared_ptr<QmldirFile> fromPathAndCode(QString path, QString code);
166
167 std::shared_ptr<QmldirFile> makeCopy(DomItem &self) const
168 {
169 return std::static_pointer_cast<QmldirFile>(doCopy(self));
170 }
171
172 bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override;
173
174 QmlUri uri() const { return m_uri; }
175
176 const QSet<int> &majorVersions() const & { return m_majorVersions; }
177
178 const QMultiMap<QString, Export> &exports() const & { return m_exports; }
179
180 const QList<Import> &imports() const & { return m_imports; }
181
182 const QList<Path> &qmltypesFilePaths() const & { return m_qmltypesFilePaths; }
183
184 QMap<QString, QString> qmlFiles() const;
185
186 bool designerSupported() const { return m_qmldir.designerSupported(); }
187
188 QStringList classNames() const { return m_qmldir.classNames(); }
189
190 QList<ModuleAutoExport> autoExports() const;
191 void setAutoExports(const QList<ModuleAutoExport> &autoExport);
192
193 void ensureInModuleIndex(DomItem &self, QString uri);
194
195private:
196 void parse();
197 void setFromQmldir();
198
199 QmlUri m_uri;
200 QSet<int> m_majorVersions;
201 QQmlDirParser m_qmldir;
203 QList<Import> m_imports;
204 QList<ModuleAutoExport> m_autoExports;
206 QList<Path> m_qmltypesFilePaths;
207};
208
210{
211protected:
212 std::shared_ptr<OwningItem> doCopy(DomItem &) const override
213 {
214 auto copy = std::make_shared<JsFile>(*this);
215 return copy;
216 }
217
218public:
219 constexpr static DomType kindValue = DomType::JsFile;
220 DomType kind() const override { return kindValue; }
221 JsFile(QString filePath = QString(),
223 Path pathFromTop = Path(), int derivedFrom = 0)
224 : ExternalOwningItem(filePath, lastDataUpdateAt, pathFromTop, derivedFrom)
225 {
226 }
227 JsFile(const JsFile &o) = default;
228
229 std::shared_ptr<JsFile> makeCopy(DomItem &self) const
230 {
231 return std::static_pointer_cast<JsFile>(doCopy(self));
232 }
233
234 std::shared_ptr<QQmlJS::Engine> engine() const { return m_engine; }
235 JsResource rootComponent() const { return m_rootComponent; }
236
237private:
238 std::shared_ptr<QQmlJS::Engine> m_engine;
239 JsResource m_rootComponent;
240};
241
243{
244protected:
245 std::shared_ptr<OwningItem> doCopy(DomItem &self) const override;
246
247public:
248 constexpr static DomType kindValue = DomType::QmlFile;
249 DomType kind() const override { return kindValue; }
250
251 QmlFile(const QmlFile &o);
252 QmlFile(QString filePath = QString(), QString code = QString(),
254 int derivedFrom = 0);
255 static ErrorGroups myParsingErrors();
256 bool iterateDirectSubpaths(DomItem &self, DirectVisitor)
257 override; // iterates the *direct* subpaths, returns false if a quick end was requested
258 DomItem field(DomItem &self, QStringView name) const override
259 {
260 return const_cast<QmlFile *>(this)->field(self, name);
261 }
262 DomItem field(DomItem &self, QStringView name);
263 std::shared_ptr<QmlFile> makeCopy(DomItem &self) const
264 {
265 return std::static_pointer_cast<QmlFile>(doCopy(self));
266 }
267 void addError(DomItem &self, ErrorMessage msg) override;
268
269 const QMultiMap<QString, QmlComponent> &components() const & { return m_components; }
271 {
272 m_components = components;
273 }
274 Path addComponent(const QmlComponent &component, AddOption option = AddOption::Overwrite,
275 QmlComponent **cPtr = nullptr)
276 {
277 QStringList nameEls = component.name().split(QChar::fromLatin1('.'));
278 QString key = nameEls.mid(1).join(QChar::fromLatin1('.'));
279 return insertUpdatableElementInMultiMap(Path::Field(Fields::components), m_components, key,
280 component, option, cPtr);
281 }
282
283 void writeOut(DomItem &self, OutWriter &lw) const override;
284
286 {
287 return m_ast; // avoid making it public? would make moving away from it easier
288 }
289 const QList<Import> &imports() const & { return m_imports; }
290 void setImports(const QList<Import> &imports) { m_imports = imports; }
292 {
293 index_type idx = index_type(m_imports.size());
294 m_imports.append(i);
295 if (i.uri.isModule()) {
296 m_importScope.addImport((i.importId.isEmpty()
297 ? QStringList()
298 : i.importId.split(QChar::fromLatin1('.'))),
299 i.importedPath());
300 } else {
301 QString path = i.uri.absoluteLocalPath(canonicalFilePath());
302 if (!path.isEmpty())
303 m_importScope.addImport((i.importId.isEmpty()
304 ? QStringList()
305 : i.importId.split(QChar::fromLatin1('.'))),
306 Paths::qmlDirPath(path));
307 }
308 return Path::Field(Fields::imports).index(idx);
309 }
310 std::shared_ptr<QQmlJS::Engine> engine() const { return m_engine; }
311 RegionComments &comments() { return m_comments; }
312 std::shared_ptr<AstComments> astComments() const { return m_astComments; }
313 void setAstComments(std::shared_ptr<AstComments> comm) { m_astComments = comm; }
314 FileLocations::Tree fileLocationsTree() const { return m_fileLocationsTree; }
315 void setFileLocationsTree(FileLocations::Tree v) { m_fileLocationsTree = v; }
316 const QList<Pragma> &pragmas() const & { return m_pragmas; }
317 void setPragmas(QList<Pragma> pragmas) { m_pragmas = pragmas; }
318 Path addPragma(const Pragma &pragma)
319 {
320 int idx = m_pragmas.size();
321 m_pragmas.append(pragma);
322 return Path::Field(Fields::pragmas).index(idx);
323 }
324 ImportScope &importScope() { return m_importScope; }
325 const ImportScope &importScope() const { return m_importScope; }
326
327 std::optional<std::shared_ptr<QQmlJSTypeResolver>> typeResolver() const
328 {
329 return m_typeResolver;
330 }
331 void setTypeResolver(const std::shared_ptr<QQmlJSTypeResolver> &typeResolver)
332 {
333 m_typeResolver = typeResolver;
334 }
335
336private:
337 friend class QQmlDomAstCreator;
338 std::shared_ptr<Engine> m_engine;
339 AST::UiProgram *m_ast; // avoid? would make moving away from it easier
340 std::shared_ptr<AstComments> m_astComments;
341 RegionComments m_comments;
342 FileLocations::Tree m_fileLocationsTree;
344 QList<Pragma> m_pragmas;
345 QList<Import> m_imports;
346 ImportScope m_importScope;
347 std::optional<std::shared_ptr<QQmlJSTypeResolver>> m_typeResolver;
348};
349
351{
352protected:
353 std::shared_ptr<OwningItem> doCopy(DomItem &) const override
354 {
355 auto res = std::make_shared<QmltypesFile>(*this);
356 return res;
357 }
358
359public:
360 constexpr static DomType kindValue = DomType::QmltypesFile;
361 DomType kind() const override { return kindValue; }
362
365 int derivedFrom = 0)
366 : ExternalOwningItem(filePath, lastDataUpdateAt, Paths::qmltypesFilePath(filePath),
367 derivedFrom, code)
368 {
369 }
370
371 QmltypesFile(const QmltypesFile &o) = default;
372
373 void ensureInModuleIndex(DomItem &self);
374
375 bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
376 std::shared_ptr<QmltypesFile> makeCopy(DomItem &self) const
377 {
378 return std::static_pointer_cast<QmltypesFile>(doCopy(self));
379 }
380
381 void addImport(const Import i)
382 { // builder only: not threadsafe...
383 m_imports.append(i);
384 }
385 const QList<Import> &imports() const & { return m_imports; }
386 const QMultiMap<QString, QmltypesComponent> &components() const & { return m_components; }
387 void setComponents(QMultiMap<QString, QmltypesComponent> c) { m_components = std::move(c); }
388 Path addComponent(const QmltypesComponent &comp, AddOption option = AddOption::Overwrite,
389 QmltypesComponent **cPtr = nullptr)
390 {
391 for (const Export &e : comp.exports())
392 addExport(e);
393 return insertUpdatableElementInMultiMap(Path::Field(u"components"), m_components,
394 comp.name(), comp, option, cPtr);
395 }
396 const QMultiMap<QString, Export> &exports() const & { return m_exports; }
399 {
400 index_type i = m_exports.values(e.typeName).size();
401 m_exports.insert(e.typeName, e);
402 addUri(e.uri, e.version.majorVersion);
403 return canonicalPath().field(Fields::exports).index(i);
404 }
405
406 const QMap<QString, QSet<int>> &uris() const & { return m_uris; }
407 void addUri(QString uri, int majorVersion)
408 {
409 QSet<int> &v = m_uris[uri];
410 if (!v.contains(majorVersion)) {
411 v.insert(majorVersion);
412 }
413 }
414
415private:
416 QList<Import> m_imports;
420};
421
423{
424protected:
425 std::shared_ptr<OwningItem> doCopy(DomItem &) const override;
426
427public:
428 constexpr static DomType kindValue = DomType::GlobalScope;
429 DomType kind() const override { return kindValue; }
430
433 int derivedFrom = 0)
434 : ExternalOwningItem(filePath, lastDataUpdateAt, Paths::globalScopePath(filePath),
435 derivedFrom)
436 {
437 setIsValid(true);
438 }
439
440 bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override;
441 std::shared_ptr<GlobalScope> makeCopy(DomItem &self) const
442 {
443 return std::static_pointer_cast<GlobalScope>(doCopy(self));
444 }
445 QString name() const { return m_name; }
446 Language language() const { return m_language; }
447 GlobalComponent rootComponent() const { return m_rootComponent; }
448 void setName(QString name) { m_name = name; }
449 void setLanguage(Language language) { m_language = language; }
451 {
452 m_rootComponent = ob;
453 m_rootComponent.updatePathFromOwner(Path::Field(Fields::rootComponent));
454 }
455
456private:
457 QString m_name;
458 Language m_language;
459 GlobalComponent m_rootComponent;
460};
461
462} // end namespace Dom
463} // end namespace QQmlJS
465#endif // QQMLDOMEXTERNALITEMS_P_H
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
Definition qchar.h:461
\inmodule QtCore\reentrant
Definition qdatetime.h:257
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
Definition qlist.h:74
Definition qmap.h:186
\inmodule QtCore
Definition qmutex.h:317
void updatePathFromOwner(Path newPath) override
DomItem field(QStringView name)
bool visitIndexes(function_ref< bool(DomItem &)> visitor)
Represents a set of tags grouping a set of related error messages.
Represents an error message connected to the dom.
A OwningItem that refers to an external resource (file,...)
bool iterateSubOwners(DomItem &self, function_ref< bool(DomItem &owner)> visitor) override
ExternalOwningItem(const ExternalOwningItem &o)=default
bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override
std::shared_ptr< AttachedInfoT< FileLocations > > Tree
void setLanguage(Language language)
std::shared_ptr< GlobalScope > makeCopy(DomItem &self) const
void setRootComponent(const GlobalComponent &ob)
DomType kind() const override
GlobalScope(QString filePath=QString(), QDateTime lastDataUpdateAt=QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC), int derivedFrom=0)
GlobalComponent rootComponent() const
std::shared_ptr< OwningItem > doCopy(DomItem &) const override
std::shared_ptr< JsFile > makeCopy(DomItem &self) const
DomType kind() const override
JsFile(QString filePath=QString(), QDateTime lastDataUpdateAt=QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC), Path pathFromTop=Path(), int derivedFrom=0)
JsFile(const JsFile &o)=default
JsResource rootComponent() const
std::shared_ptr< QQmlJS::Engine > engine() const
Path index(index_type i) const
std::shared_ptr< QmlDirectory > makeCopy(DomItem &self) const
std::shared_ptr< OwningItem > doCopy(DomItem &) const override
DomType kind() const override
const QMultiMap< QString, QString > & qmlFiles() const &
const QMultiMap< QString, Export > & exports() const &
QmlDirectory(const QmlDirectory &o)=default
const QMultiMap< QString, QmlComponent > & components() const &
void setTypeResolver(const std::shared_ptr< QQmlJSTypeResolver > &typeResolver)
std::optional< std::shared_ptr< QQmlJSTypeResolver > > typeResolver() const
DomItem field(DomItem &self, QStringView name) const override
std::shared_ptr< QQmlJS::Engine > engine() const
std::shared_ptr< AstComments > astComments() const
Path addImport(const Import &i)
void setFileLocationsTree(FileLocations::Tree v)
void setComponents(const QMultiMap< QString, QmlComponent > &components)
void setAstComments(std::shared_ptr< AstComments > comm)
const QList< Import > & imports() const &
const QList< Pragma > & pragmas() const &
void setImports(const QList< Import > &imports)
AST::UiProgram * ast() const
DomType kind() const override
Path addPragma(const Pragma &pragma)
Path addComponent(const QmlComponent &component, AddOption option=AddOption::Overwrite, QmlComponent **cPtr=nullptr)
const ImportScope & importScope() const
void setPragmas(QList< Pragma > pragmas)
std::shared_ptr< QmlFile > makeCopy(DomItem &self) const
FileLocations::Tree fileLocationsTree() const
const QSet< int > & majorVersions() const &
const QList< Import > & imports() const &
DomType kind() const override
std::shared_ptr< QmldirFile > makeCopy(DomItem &self) const
QmldirFile(const QmldirFile &o)=default
QmldirFile(QString filePath=QString(), QString code=QString(), QDateTime lastDataUpdateAt=QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC), int derivedFrom=0)
const QMultiMap< QString, Export > & exports() const &
std::shared_ptr< OwningItem > doCopy(DomItem &) const override
const QList< Path > & qmltypesFilePaths() const &
const QList< Export > & exports() const &
DomType kind() const override
QmltypesFile(const QmltypesFile &o)=default
QmltypesFile(QString filePath=QString(), QString code=QString(), QDateTime lastDataUpdateAt=QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC), int derivedFrom=0)
const QList< Import > & imports() const &
const QMultiMap< QString, QmltypesComponent > & components() const &
std::shared_ptr< QmltypesFile > makeCopy(DomItem &self) const
void setExports(QMultiMap< QString, Export > e)
void setComponents(QMultiMap< QString, QmltypesComponent > c)
Path addComponent(const QmltypesComponent &comp, AddOption option=AddOption::Overwrite, QmltypesComponent **cPtr=nullptr)
void addUri(QString uri, int majorVersion)
std::shared_ptr< OwningItem > doCopy(DomItem &) const override
const QMultiMap< QString, Export > & exports() const &
const QMap< QString, QSet< int > > & uris() const &
Keeps the comments associated with a DomItem.
Definition qset.h:18
iterator insert(const T &value)
Definition qset.h:155
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isNull() const
Returns true if this string is null; otherwise returns false.
Definition qstring.h:898
double e
Path insertUpdatableElementInMultiMap(Path mapPathFromOwner, QMultiMap< K, T > &mmap, K key, const T &value, AddOption option=AddOption::KeepExisting, T **valuePtr=nullptr)
qint64 index_type
Combined button and popup list for selecting options.
static jboolean copy(JNIEnv *, jobject)
#define Q_DECLARE_TR_FUNCTIONS(context)
#define Q_DECLARE_METATYPE(TYPE)
Definition qmetatype.h:1504
GLsizei const GLfloat * v
[13]
GLuint64 key
GLint GLenum GLint components
GLuint name
GLuint res
const GLubyte * c
GLuint GLfloat * val
GLsizei const GLchar *const * path
GLuint GLenum option
static qreal component(const QPointF &point, unsigned int i)
#define QMLDOM_EXPORT
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QString canonicalPath(const QString &rootPath)
QMutex mutex
[2]