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 DOMTOP_H
5#define DOMTOP_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"
20#include "qqmldomexternalitems_p.h"
21
22#include <QtCore/QQueue>
23#include <QtCore/QString>
24#include <QtCore/QDateTime>
25
26#include <QtCore/QCborValue>
27#include <QtCore/QCborMap>
28
29#include <memory>
30#include <optional>
31
32QT_BEGIN_NAMESPACE
33
34using namespace Qt::Literals::StringLiterals;
35
36namespace QQmlJS {
37namespace Dom {
38
39class QMLDOM_EXPORT ParsingTask {
40public:
41 QCborMap toCbor() const {
42 return QCborMap({ { QString::fromUtf16(Fields::requestedAt), QCborValue(requestedAt) },
43 { QString::fromUtf16(Fields::loadOptions), int(loadOptions) },
44 { QString::fromUtf16(Fields::kind), int(kind) },
45 { QString::fromUtf16(Fields::canonicalPath), file.canonicalPath() },
46 { QString::fromUtf16(Fields::logicalPath), file.logicalPath() },
47 { QString::fromUtf16(Fields::contents),
48 file.content() ? file.content()->data : QString() },
49 { QString::fromUtf16(Fields::contentsDate),
50 QCborValue(file.content() ? file.content()->date
51 : QDateTime::fromMSecsSinceEpoch(
52 msecs: 0, timeZone: QTimeZone::UTC)) },
53 { QString::fromUtf16(Fields::hasCallback), bool(callback) } });
54 }
55
56 QDateTime requestedAt;
57 LoadOptions loadOptions;
58 DomType kind;
59 FileToLoad file;
60 std::weak_ptr<DomUniverse> requestingUniverse; // make it a shared_ptr?
61 function<void(Path, DomItem &, DomItem &)> callback;
62};
63
64class QMLDOM_EXPORT ExternalItemPairBase: public OwningItem { // all access should have the lock of the DomUniverse containing this
65 Q_DECLARE_TR_FUNCTIONS(ExternalItemPairBase);
66public:
67 constexpr static DomType kindValue = DomType::ExternalItemPair;
68 DomType kind() const final override { return kindValue; }
69 ExternalItemPairBase(QDateTime validExposedAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC),
70 QDateTime currentExposedAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC),
71 int derivedFrom = 0,
72 QDateTime lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC))
73 : OwningItem(derivedFrom, lastDataUpdateAt),
74 validExposedAt(validExposedAt),
75 currentExposedAt(currentExposedAt)
76 {}
77 ExternalItemPairBase(const ExternalItemPairBase &o):
78 OwningItem(o), validExposedAt(o.validExposedAt), currentExposedAt(o.currentExposedAt)
79 {}
80 virtual std::shared_ptr<ExternalOwningItem> validItem() const = 0;
81 virtual DomItem validItem(DomItem &self) const = 0;
82 virtual std::shared_ptr<ExternalOwningItem> currentItem() const = 0;
83 virtual DomItem currentItem(DomItem &self) const = 0;
84
85 QString canonicalFilePath(DomItem &) const final override;
86 Path canonicalPath(DomItem &self) const final override;
87 bool iterateDirectSubpaths(DomItem &self, DirectVisitor) final override;
88 DomItem field(DomItem &self, QStringView name) const final override
89 {
90 return OwningItem::field(self, name);
91 }
92
93 bool currentIsValid() const;
94
95 std::shared_ptr<ExternalItemPairBase> makeCopy(DomItem &self) const
96 {
97 return std::static_pointer_cast<ExternalItemPairBase>(r: doCopy(self));
98 }
99
100 QDateTime lastDataUpdateAt() const final override
101 {
102 if (currentItem())
103 return currentItem()->lastDataUpdateAt();
104 return ExternalItemPairBase::lastDataUpdateAt();
105 }
106
107 void refreshedDataAt(QDateTime tNew) final override
108 {
109 return OwningItem::refreshedDataAt(tNew);
110 if (currentItem())
111 currentItem()->refreshedDataAt(tNew);
112 }
113
114 friend class DomUniverse;
115
116 QDateTime validExposedAt;
117 QDateTime currentExposedAt;
118};
119
120template<class T>
121class QMLDOM_EXPORT ExternalItemPair final : public ExternalItemPairBase
122{ // all access should have the lock of the DomUniverse containing this
123protected:
124 std::shared_ptr<OwningItem> doCopy(DomItem &) const override
125 {
126 return std::make_shared<ExternalItemPair>(*this);
127 }
128
129public:
130 constexpr static DomType kindValue = DomType::ExternalItemPair;
131 friend class DomUniverse;
132 ExternalItemPair(std::shared_ptr<T> valid = {}, std::shared_ptr<T> current = {},
133 QDateTime validExposedAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC),
134 QDateTime currentExposedAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC),
135 int derivedFrom = 0,
136 QDateTime lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC))
137 : ExternalItemPairBase(validExposedAt, currentExposedAt, derivedFrom, lastDataUpdateAt),
138 valid(valid),
139 current(current)
140 {}
141 ExternalItemPair(const ExternalItemPair &o):
142 ExternalItemPairBase(o), valid(o.valid), current(o.current)
143 {
144 }
145 std::shared_ptr<ExternalOwningItem> validItem() const override { return valid; }
146 DomItem validItem(DomItem &self) const override { return self.copy(valid); }
147 std::shared_ptr<ExternalOwningItem> currentItem() const override { return current; }
148 DomItem currentItem(DomItem &self) const override { return self.copy(current); }
149 std::shared_ptr<ExternalItemPair> makeCopy(DomItem &self) const
150 {
151 return std::static_pointer_cast<ExternalItemPair>(doCopy(self));
152 }
153
154 std::shared_ptr<T> valid;
155 std::shared_ptr<T> current;
156};
157
158class QMLDOM_EXPORT DomTop: public OwningItem {
159public:
160 DomTop(QMap<QString, OwnerT> extraOwningItems = {}, int derivedFrom = 0)
161 : OwningItem(derivedFrom), m_extraOwningItems(extraOwningItems)
162 {}
163 DomTop(const DomTop &o):
164 OwningItem(o)
165 {
166 QMap<QString, OwnerT> items = o.extraOwningItems();
167 {
168 QMutexLocker l(mutex());
169 m_extraOwningItems = items;
170 }
171 }
172 using Callback = DomItem::Callback;
173
174 virtual Path canonicalPath() const = 0;
175
176 Path canonicalPath(DomItem &) const override;
177 DomItem containingObject(DomItem &) const override;
178 bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
179 template<typename T>
180 void setExtraOwningItem(QString fieldName, std::shared_ptr<T> item)
181 {
182 QMutexLocker l(mutex());
183 if (!item)
184 m_extraOwningItems.remove(key: fieldName);
185 else
186 m_extraOwningItems.insert(fieldName, item);
187 }
188
189 void clearExtraOwningItems();
190 QMap<QString, OwnerT> extraOwningItems() const;
191
192private:
193 QMap<QString, OwnerT> m_extraOwningItems;
194};
195
196class QMLDOM_EXPORT DomUniverse final : public DomTop
197{
198 Q_GADGET
199 Q_DECLARE_TR_FUNCTIONS(DomUniverse);
200protected:
201 std::shared_ptr<OwningItem> doCopy(DomItem &self) const override;
202
203public:
204 enum class Option{
205 Default,
206 SingleThreaded
207 };
208 Q_ENUM(Option)
209 Q_DECLARE_FLAGS(Options, Option);
210 constexpr static DomType kindValue = DomType::DomUniverse;
211 DomType kind() const override { return kindValue; }
212
213 static ErrorGroups myErrors();
214
215 DomUniverse(QString universeName, Options options = Option::SingleThreaded);
216 DomUniverse(const DomUniverse &) = delete;
217 static std::shared_ptr<DomUniverse> guaranteeUniverse(std::shared_ptr<DomUniverse> univ);
218 static DomItem create(QString universeName, Options options = Option::SingleThreaded);
219
220 Path canonicalPath() const override;
221 using DomTop::canonicalPath;
222 bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
223 std::shared_ptr<DomUniverse> makeCopy(DomItem &self) const
224 {
225 return std::static_pointer_cast<DomUniverse>(r: doCopy(self));
226 }
227
228 void loadFile(DomItem &self, const FileToLoad &file, Callback callback, LoadOptions loadOptions,
229 std::optional<DomType> fileType = std::optional<DomType>());
230 void execQueue();
231
232 void removePath(const QString &dir);
233
234 std::shared_ptr<ExternalItemPair<GlobalScope>> globalScopeWithName(QString name) const
235 {
236 QMutexLocker l(mutex());
237 return m_globalScopeWithName.value(key: name);
238 }
239
240 std::shared_ptr<ExternalItemPair<GlobalScope>> ensureGlobalScopeWithName(QString name)
241 {
242 if (auto current = globalScopeWithName(name))
243 return current;
244 auto newScope = std::make_shared<GlobalScope>(args&: name);
245 auto newValue = std::make_shared<ExternalItemPair<GlobalScope>>(
246 args&: newScope, args&: newScope);
247 QMutexLocker l(mutex());
248 if (auto current = m_globalScopeWithName.value(key: name))
249 return current;
250 m_globalScopeWithName.insert(key: name, value: newValue);
251 return newValue;
252 }
253
254 QSet<QString> globalScopeNames() const
255 {
256 QMap<QString, std::shared_ptr<ExternalItemPair<GlobalScope>>> map;
257 {
258 QMutexLocker l(mutex());
259 map = m_globalScopeWithName;
260 }
261 return QSet<QString>(map.keyBegin(), map.keyEnd());
262 }
263
264 std::shared_ptr<ExternalItemPair<QmlDirectory>> qmlDirectoryWithPath(QString path) const
265 {
266 QMutexLocker l(mutex());
267 return m_qmlDirectoryWithPath.value(key: path);
268 }
269 QSet<QString> qmlDirectoryPaths() const
270 {
271 QMap<QString, std::shared_ptr<ExternalItemPair<QmlDirectory>>> map;
272 {
273 QMutexLocker l(mutex());
274 map = m_qmlDirectoryWithPath;
275 }
276 return QSet<QString>(map.keyBegin(), map.keyEnd());
277 }
278
279 std::shared_ptr<ExternalItemPair<QmldirFile>> qmldirFileWithPath(QString path) const
280 {
281 QMutexLocker l(mutex());
282 return m_qmldirFileWithPath.value(key: path);
283 }
284 QSet<QString> qmldirFilePaths() const
285 {
286 QMap<QString, std::shared_ptr<ExternalItemPair<QmldirFile>>> map;
287 {
288 QMutexLocker l(mutex());
289 map = m_qmldirFileWithPath;
290 }
291 return QSet<QString>(map.keyBegin(), map.keyEnd());
292 }
293
294 std::shared_ptr<ExternalItemPair<QmlFile>> qmlFileWithPath(QString path) const
295 {
296 QMutexLocker l(mutex());
297 return m_qmlFileWithPath.value(key: path);
298 }
299 QSet<QString> qmlFilePaths() const
300 {
301 QMap<QString, std::shared_ptr<ExternalItemPair<QmlFile>>> map;
302 {
303 QMutexLocker l(mutex());
304 map = m_qmlFileWithPath;
305 }
306 return QSet<QString>(map.keyBegin(), map.keyEnd());
307 }
308
309 std::shared_ptr<ExternalItemPair<JsFile>> jsFileWithPath(QString path) const
310 {
311 QMutexLocker l(mutex());
312 return m_jsFileWithPath.value(key: path);
313 }
314 QSet<QString> jsFilePaths() const
315 {
316 QMap<QString, std::shared_ptr<ExternalItemPair<JsFile>>> map;
317 {
318 QMutexLocker l(mutex());
319 map = m_jsFileWithPath;
320 }
321 return QSet<QString>(map.keyBegin(), map.keyEnd());
322 }
323
324 std::shared_ptr<ExternalItemPair<QmltypesFile>> qmltypesFileWithPath(QString path) const
325 {
326 QMutexLocker l(mutex());
327 return m_qmltypesFileWithPath.value(key: path);
328 }
329 QSet<QString> qmltypesFilePaths() const
330 {
331 QMap<QString, std::shared_ptr<ExternalItemPair<QmltypesFile>>> map;
332 {
333 QMutexLocker l(mutex());
334 map = m_qmltypesFileWithPath;
335 }
336 return QSet<QString>(map.keyBegin(), map.keyEnd());
337 }
338
339 QString name() const {
340 return m_name;
341 }
342 Options options() const {
343 return m_options;
344 }
345 QQueue<ParsingTask> queue() const {
346 QMutexLocker l(mutex());
347 return m_queue;
348 }
349
350private:
351 QString m_name;
352 Options m_options;
353 QMap<QString, std::shared_ptr<ExternalItemPair<GlobalScope>>> m_globalScopeWithName;
354 QMap<QString, std::shared_ptr<ExternalItemPair<QmlDirectory>>> m_qmlDirectoryWithPath;
355 QMap<QString, std::shared_ptr<ExternalItemPair<QmldirFile>>> m_qmldirFileWithPath;
356 QMap<QString, std::shared_ptr<ExternalItemPair<QmlFile>>> m_qmlFileWithPath;
357 QMap<QString, std::shared_ptr<ExternalItemPair<JsFile>>> m_jsFileWithPath;
358 QMap<QString, std::shared_ptr<ExternalItemPair<QmltypesFile>>> m_qmltypesFileWithPath;
359 QQueue<ParsingTask> m_queue;
360};
361
362 Q_DECLARE_OPERATORS_FOR_FLAGS(DomUniverse::Options)
363
364class QMLDOM_EXPORT ExternalItemInfoBase: public OwningItem {
365 Q_DECLARE_TR_FUNCTIONS(ExternalItemInfoBase);
366public:
367 constexpr static DomType kindValue = DomType::ExternalItemInfo;
368 DomType kind() const final override { return kindValue; }
369 ExternalItemInfoBase(Path canonicalPath,
370 QDateTime currentExposedAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC),
371 int derivedFrom = 0,
372 QDateTime lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC))
373 : OwningItem(derivedFrom, lastDataUpdateAt),
374 m_canonicalPath(canonicalPath),
375 m_currentExposedAt(currentExposedAt)
376 {}
377 ExternalItemInfoBase(const ExternalItemInfoBase &o) = default;
378
379 virtual std::shared_ptr<ExternalOwningItem> currentItem() const = 0;
380 virtual DomItem currentItem(DomItem &) const = 0;
381
382 QString canonicalFilePath(DomItem &) const final override;
383 Path canonicalPath() const { return m_canonicalPath; }
384 Path canonicalPath(DomItem &) const final override { return canonicalPath(); }
385 bool iterateDirectSubpaths(DomItem &self, DirectVisitor) final override;
386 DomItem field(DomItem &self, QStringView name) const final override
387 {
388 return OwningItem::field(self, name);
389 }
390
391 int currentRevision(DomItem &self) const;
392 int lastRevision(DomItem &self) const;
393 int lastValidRevision(DomItem &self) const;
394
395 std::shared_ptr<ExternalItemInfoBase> makeCopy(DomItem &self) const
396 {
397 return std::static_pointer_cast<ExternalItemInfoBase>(r: doCopy(self));
398 }
399
400 QDateTime lastDataUpdateAt() const final override
401 {
402 if (currentItem())
403 return currentItem()->lastDataUpdateAt();
404 return OwningItem::lastDataUpdateAt();
405 }
406
407 void refreshedDataAt(QDateTime tNew) final override
408 {
409 return OwningItem::refreshedDataAt(tNew);
410 if (currentItem())
411 currentItem()->refreshedDataAt(tNew);
412 }
413
414 void ensureLogicalFilePath(QString path) {
415 QMutexLocker l(mutex());
416 if (!m_logicalFilePaths.contains(str: path))
417 m_logicalFilePaths.append(t: path);
418 }
419
420 QDateTime currentExposedAt() const {
421 QMutexLocker l(mutex()); // should not be needed, as it should not change...
422 return m_currentExposedAt;
423 }
424
425 void setCurrentExposedAt(QDateTime d) {
426 QMutexLocker l(mutex()); // should not be needed, as it should not change...
427 m_currentExposedAt = d;
428 }
429
430
431 QStringList logicalFilePaths() const {
432 QMutexLocker l(mutex());
433 return m_logicalFilePaths;
434 }
435
436 private:
437 friend class DomEnvironment;
438 Path m_canonicalPath;
439 QDateTime m_currentExposedAt;
440 QStringList m_logicalFilePaths;
441};
442
443template<typename T>
444class ExternalItemInfo final : public ExternalItemInfoBase
445{
446protected:
447 std::shared_ptr<OwningItem> doCopy(DomItem &) const override
448 {
449 return std::make_shared<ExternalItemInfo>(*this);
450 }
451
452public:
453 constexpr static DomType kindValue = DomType::ExternalItemInfo;
454 ExternalItemInfo(std::shared_ptr<T> current = std::shared_ptr<T>(),
455 QDateTime currentExposedAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC),
456 int derivedFrom = 0,
457 QDateTime lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC))
458 : ExternalItemInfoBase(current->canonicalPath().dropTail(), currentExposedAt, derivedFrom,
459 lastDataUpdateAt),
460 current(current)
461 {}
462 ExternalItemInfo(QString canonicalPath) : current(new T(canonicalPath)) { }
463 ExternalItemInfo(const ExternalItemInfo &o):
464 ExternalItemInfoBase(o), current(o.current)
465 {
466 }
467
468 std::shared_ptr<ExternalItemInfo> makeCopy(DomItem &self) const
469 {
470 return std::static_pointer_cast<ExternalItemInfo>(doCopy(self));
471 }
472
473 std::shared_ptr<ExternalOwningItem> currentItem() const override {
474 return current;
475 }
476 DomItem currentItem(DomItem &self) const override { return self.copy(current); }
477
478 std::shared_ptr<T> current;
479};
480
481class Dependency
482{ // internal, should be cleaned, but nobody should use this...
483public:
484 bool operator==(Dependency const &o) const
485 {
486 return uri == o.uri && version.majorVersion == o.version.majorVersion
487 && version.minorVersion == o.version.minorVersion && filePath == o.filePath;
488 }
489 QString uri; // either dotted uri or file:, http: https: uri
490 Version version;
491 QString filePath; // for file deps
492 DomType fileType;
493};
494
495class QMLDOM_EXPORT LoadInfo final : public OwningItem
496{
497 Q_DECLARE_TR_FUNCTIONS(LoadInfo);
498
499protected:
500 std::shared_ptr<OwningItem> doCopy(DomItem &self) const override;
501
502public:
503 constexpr static DomType kindValue = DomType::LoadInfo;
504 DomType kind() const override { return kindValue; }
505
506 enum class Status {
507 NotStarted, // dependencies non checked yet
508 Starting, // adding deps
509 InProgress, // waiting for all deps to be loaded
510 CallingCallbacks, // calling callbacks
511 Done // fully loaded
512 };
513
514 LoadInfo(Path elPath = Path(), Status status = Status::NotStarted, int nLoaded = 0,
515 int derivedFrom = 0,
516 QDateTime lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC))
517 : OwningItem(derivedFrom, lastDataUpdateAt),
518 m_elementCanonicalPath(elPath),
519 m_status(status),
520 m_nLoaded(nLoaded)
521 {
522 }
523 LoadInfo(const LoadInfo &o) : OwningItem(o), m_elementCanonicalPath(o.elementCanonicalPath())
524 {
525 {
526 QMutexLocker l(o.mutex());
527 m_status = o.m_status;
528 m_nLoaded = o.m_nLoaded;
529 m_toDo = o.m_toDo;
530 m_inProgress = o.m_inProgress;
531 m_endCallbacks = o.m_endCallbacks;
532 }
533 }
534
535 Path canonicalPath(DomItem &self) const override;
536
537 bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
538 std::shared_ptr<LoadInfo> makeCopy(DomItem &self) const
539 {
540 return std::static_pointer_cast<LoadInfo>(r: doCopy(self));
541 }
542 void addError(DomItem &self, ErrorMessage msg) override
543 {
544 self.path(p: elementCanonicalPath()).addError(msg);
545 }
546
547 void addEndCallback(DomItem &self, std::function<void(Path, DomItem &, DomItem &)> callback);
548
549 void advanceLoad(DomItem &self);
550 void finishedLoadingDep(DomItem &self, const Dependency &d);
551 void execEnd(DomItem &self);
552
553 Status status() const
554 {
555 QMutexLocker l(mutex());
556 return m_status;
557 }
558
559 int nLoaded() const
560 {
561 QMutexLocker l(mutex());
562 return m_nLoaded;
563 }
564
565 Path elementCanonicalPath() const
566 {
567 QMutexLocker l(mutex()); // we should never change this, remove lock?
568 return m_elementCanonicalPath;
569 }
570
571 int nNotDone() const
572 {
573 QMutexLocker l(mutex());
574 return m_toDo.size() + m_inProgress.size();
575 }
576
577 QList<Dependency> inProgress() const
578 {
579 QMutexLocker l(mutex());
580 return m_inProgress;
581 }
582
583 QList<Dependency> toDo() const
584 {
585 QMutexLocker l(mutex());
586 return m_toDo;
587 }
588
589 int nCallbacks() const
590 {
591 QMutexLocker l(mutex());
592 return m_endCallbacks.size();
593 }
594
595private:
596 void doAddDependencies(DomItem &self);
597 void addDependency(DomItem &self, const Dependency &dep);
598
599 Path m_elementCanonicalPath;
600 Status m_status;
601 int m_nLoaded;
602 QQueue<Dependency> m_toDo;
603 QList<Dependency> m_inProgress;
604 QList<std::function<void(Path, DomItem &, DomItem &)>> m_endCallbacks;
605};
606
607enum class EnvLookup { Normal, NoBase, BaseOnly };
608
609enum class Changeable { ReadOnly, Writable };
610
611class QMLDOM_EXPORT RefCacheEntry
612{
613 Q_GADGET
614public:
615 enum class Cached { None, First, All };
616 Q_ENUM(Cached)
617
618 static RefCacheEntry forPath(DomItem &el, Path canonicalPath);
619 static bool addForPath(DomItem &el, Path canonicalPath, const RefCacheEntry &entry,
620 AddOption addOption = AddOption::KeepExisting);
621
622 Cached cached = Cached::None;
623 QList<Path> canonicalPaths;
624};
625
626class QMLDOM_EXPORT DomEnvironment final : public DomTop
627{
628 Q_GADGET
629 Q_DECLARE_TR_FUNCTIONS(DomEnvironment);
630protected:
631 std::shared_ptr<OwningItem> doCopy(DomItem &self) const override;
632
633public:
634 enum class Option {
635 Default = 0x0,
636 KeepValid = 0x1, // if there is a previous valid version, use that instead of the latest
637 Exported = 0x2, // the current environment is accessible by multiple threads, one should only modify whole OwningItems, and in general load and do other operations in other (Child) environments
638 NoReload = 0x4, // never reload something that was already loaded by the parent environment
639 WeakLoad = 0x8, // load only the names of the available types, not the types (qml files) themselves
640 SingleThreaded = 0x10, // do all operations in a single thread
641 NoDependencies = 0x20 // will not load dependencies (useful when editing)
642 };
643 Q_ENUM(Option)
644 Q_DECLARE_FLAGS(Options, Option);
645
646 static ErrorGroups myErrors();
647 constexpr static DomType kindValue = DomType::DomEnvironment;
648 DomType kind() const override;
649
650 Path canonicalPath() const override;
651 using DomTop::canonicalPath;
652 bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
653 DomItem field(DomItem &self, QStringView name) const final override;
654
655 std::shared_ptr<DomEnvironment> makeCopy(DomItem &self) const;
656
657 void loadFile(DomItem &self, FileToLoad file, Callback loadCallback,
658 Callback directDepsCallback, Callback endCallback, LoadOptions loadOptions,
659 std::optional<DomType> fileType = std::optional<DomType>(),
660 ErrorHandler h = nullptr);
661 void loadModuleDependency(DomItem &self, QString uri, Version v,
662 Callback loadCallback = nullptr, Callback endCallback = nullptr,
663 ErrorHandler = nullptr);
664 void loadBuiltins(DomItem &self, Callback callback = nullptr, ErrorHandler h = nullptr);
665 void removePath(const QString &path);
666
667 std::shared_ptr<DomUniverse> universe() const;
668
669 QSet<QString> moduleIndexUris(DomItem &self, EnvLookup lookup = EnvLookup::Normal) const;
670 QSet<int> moduleIndexMajorVersions(DomItem &self, QString uri,
671 EnvLookup lookup = EnvLookup::Normal) const;
672 std::shared_ptr<ModuleIndex> moduleIndexWithUri(DomItem &self, QString uri, int majorVersion,
673 EnvLookup lookup, Changeable changeable,
674 ErrorHandler errorHandler = nullptr);
675 std::shared_ptr<ModuleIndex> moduleIndexWithUri(DomItem &self, QString uri, int majorVersion,
676 EnvLookup lookup = EnvLookup::Normal) const;
677 std::shared_ptr<ExternalItemInfo<QmlDirectory>>
678 qmlDirectoryWithPath(DomItem &self, QString path, EnvLookup options = EnvLookup::Normal) const;
679 QSet<QString> qmlDirectoryPaths(DomItem &self, EnvLookup options = EnvLookup::Normal) const;
680 std::shared_ptr<ExternalItemInfo<QmldirFile>>
681 qmldirFileWithPath(DomItem &self, QString path, EnvLookup options = EnvLookup::Normal) const;
682 QSet<QString> qmldirFilePaths(DomItem &self, EnvLookup options = EnvLookup::Normal) const;
683 std::shared_ptr<ExternalItemInfoBase>
684 qmlDirWithPath(DomItem &self, QString path, EnvLookup options = EnvLookup::Normal) const;
685 QSet<QString> qmlDirPaths(DomItem &self, EnvLookup options = EnvLookup::Normal) const;
686 std::shared_ptr<ExternalItemInfo<QmlFile>>
687 qmlFileWithPath(DomItem &self, QString path, EnvLookup options = EnvLookup::Normal) const;
688 QSet<QString> qmlFilePaths(DomItem &self, EnvLookup lookup = EnvLookup::Normal) const;
689 std::shared_ptr<ExternalItemInfo<JsFile>>
690 jsFileWithPath(DomItem &self, QString path, EnvLookup options = EnvLookup::Normal) const;
691 QSet<QString> jsFilePaths(DomItem &self, EnvLookup lookup = EnvLookup::Normal) const;
692 std::shared_ptr<ExternalItemInfo<QmltypesFile>>
693 qmltypesFileWithPath(DomItem &self, QString path, EnvLookup options = EnvLookup::Normal) const;
694 QSet<QString> qmltypesFilePaths(DomItem &self, EnvLookup lookup = EnvLookup::Normal) const;
695 std::shared_ptr<ExternalItemInfo<GlobalScope>>
696 globalScopeWithName(DomItem &self, QString name, EnvLookup lookup = EnvLookup::Normal) const;
697 std::shared_ptr<ExternalItemInfo<GlobalScope>>
698 ensureGlobalScopeWithName(DomItem &self, QString name, EnvLookup lookup = EnvLookup::Normal);
699 QSet<QString> globalScopeNames(DomItem &self, EnvLookup lookup = EnvLookup::Normal) const;
700
701 explicit DomEnvironment(QStringList loadPaths, Options options = Option::SingleThreaded,
702 std::shared_ptr<DomUniverse> universe = nullptr);
703 explicit DomEnvironment(std::shared_ptr<DomEnvironment> parent, QStringList loadPaths,
704 Options options = Option::SingleThreaded);
705 DomEnvironment(const DomEnvironment &o) = delete;
706 static DomItem create(QStringList loadPaths, Options options = Option::SingleThreaded,
707 DomItem &universe = DomItem::empty);
708
709 std::shared_ptr<ExternalItemInfo<QmlFile>>
710 addQmlFile(std::shared_ptr<QmlFile> file, AddOption option = AddOption::KeepExisting);
711 std::shared_ptr<ExternalItemInfo<QmlDirectory>>
712 addQmlDirectory(std::shared_ptr<QmlDirectory> file, AddOption option = AddOption::KeepExisting);
713 std::shared_ptr<ExternalItemInfo<QmldirFile>>
714 addQmldirFile(std::shared_ptr<QmldirFile> file, AddOption option = AddOption::KeepExisting);
715 std::shared_ptr<ExternalItemInfo<QmltypesFile>>
716 addQmltypesFile(std::shared_ptr<QmltypesFile> file, AddOption option = AddOption::KeepExisting);
717 std::shared_ptr<ExternalItemInfo<JsFile>> addJsFile(std::shared_ptr<JsFile> file,
718 AddOption option = AddOption::KeepExisting);
719 std::shared_ptr<ExternalItemInfo<GlobalScope>>
720 addGlobalScope(std::shared_ptr<GlobalScope> file, AddOption option = AddOption::KeepExisting);
721
722 bool commitToBase(DomItem &self, std::shared_ptr<DomEnvironment> validEnv = nullptr);
723
724 void addLoadInfo(DomItem &self, std::shared_ptr<LoadInfo> loadInfo);
725 std::shared_ptr<LoadInfo> loadInfo(Path path) const;
726 QList<Path> loadInfoPaths() const;
727 QHash<Path, std::shared_ptr<LoadInfo>> loadInfos() const;
728 void loadPendingDependencies(DomItem &self);
729 bool finishLoadingDependencies(DomItem &self, int waitMSec = 30000);
730 void addWorkForLoadInfo(Path elementCanonicalPath);
731
732 Options options() const;
733
734 std::shared_ptr<DomEnvironment> base() const;
735
736 QStringList loadPaths() const;
737 QStringList qmldirFiles() const;
738
739 QString globalScopeName() const;
740
741 static QList<Import> defaultImplicitImports();
742 QList<Import> implicitImports() const;
743
744 void addAllLoadedCallback(DomItem &self, Callback c);
745
746 void clearReferenceCache();
747 void setLoadPaths(const QStringList &v);
748
749private:
750 friend class RefCacheEntry;
751 template<typename T>
752 QSet<QString> getStrings(function_ref<QSet<QString>()> getBase, const QMap<QString, T> &selfMap,
753 EnvLookup lookup) const;
754
755 Callback callbackForQmlDirectory(DomItem &self, Callback loadCallback,
756 Callback directDepsCallback, Callback endCallback);
757 Callback callbackForQmlFile(DomItem &self, Callback loadCallback, Callback directDepsCallback,
758 Callback endCallback);
759 Callback callbackForQmltypesFile(DomItem &self, Callback loadCallback,
760 Callback directDepsCallback, Callback endCallback);
761 Callback callbackForQmldirFile(DomItem &self, Callback loadCallback,
762 Callback directDepsCallback, Callback endCallback);
763
764 std::shared_ptr<ModuleIndex> lookupModuleInEnv(const QString &uri, int majorVersion) const;
765 // ModuleLookupResult contains the ModuleIndex pointer, and an indicator whether it was found
766 // in m_base or in m_moduleIndexWithUri
767 struct ModuleLookupResult {
768 enum Origin : bool {FromBase, FromGlobal};
769 std::shared_ptr<ModuleIndex> module;
770 Origin fromBase = FromGlobal;
771 };
772 // helper function used by the moduleIndexWithUri methods
773 ModuleLookupResult moduleIndexWithUriHelper(DomItem &self, QString uri, int majorVersion,
774 EnvLookup lookup = EnvLookup::Normal) const;
775
776 const Options m_options;
777 const std::shared_ptr<DomEnvironment> m_base;
778 const std::shared_ptr<DomUniverse> m_universe;
779 QStringList m_loadPaths; // paths for qml
780 QString m_globalScopeName;
781 QMap<QString, QMap<int, std::shared_ptr<ModuleIndex>>> m_moduleIndexWithUri;
782 QMap<QString, std::shared_ptr<ExternalItemInfo<GlobalScope>>> m_globalScopeWithName;
783 QMap<QString, std::shared_ptr<ExternalItemInfo<QmlDirectory>>> m_qmlDirectoryWithPath;
784 QMap<QString, std::shared_ptr<ExternalItemInfo<QmldirFile>>> m_qmldirFileWithPath;
785 QMap<QString, std::shared_ptr<ExternalItemInfo<QmlFile>>> m_qmlFileWithPath;
786 QMap<QString, std::shared_ptr<ExternalItemInfo<JsFile>>> m_jsFileWithPath;
787 QMap<QString, std::shared_ptr<ExternalItemInfo<QmltypesFile>>> m_qmltypesFileWithPath;
788 QQueue<Path> m_loadsWithWork;
789 QQueue<Path> m_inProgress;
790 QHash<Path, std::shared_ptr<LoadInfo>> m_loadInfos;
791 QList<Import> m_implicitImports;
792 QList<Callback> m_allLoadedCallback;
793 QHash<Path, RefCacheEntry> m_referenceCache;
794};
795Q_DECLARE_OPERATORS_FOR_FLAGS(DomEnvironment::Options)
796
797} // end namespace Dom
798} // end namespace QQmlJS
799QT_END_NAMESPACE
800#endif // DOMTOP_H
801

source code of qtdeclarative/src/qmldom/qqmldomtop_p.h