Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmldomitem_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 QMLDOMITEM_H
5#define QMLDOMITEM_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 "qqmldom_global.h"
19#include "qqmldom_fwd_p.h"
23#include "qqmldompath_p.h"
29
30#include <QtCore/QMap>
31#include <QtCore/QMultiMap>
32#include <QtCore/QSet>
33#include <QtCore/QString>
34#include <QtCore/QStringView>
35#include <QtCore/QDebug>
36#include <QtCore/QDateTime>
37#include <QtCore/QMutex>
38#include <QtCore/QCborValue>
39#include <QtCore/QTimeZone>
40#include <QtQml/private/qqmljssourcelocation_p.h>
41#include <QtQmlCompiler/private/qqmljsscope_p.h>
42
43#include <memory>
44#include <typeinfo>
45#include <utility>
46#include <type_traits>
47#include <variant>
48#include <optional>
49#include <cstddef>
50
52
54
55namespace QQmlJS {
56// we didn't have enough 'O's to properly name everything...
57namespace Dom {
58
59class Path;
60
61constexpr bool domTypeIsObjWrap(DomType k);
62constexpr bool domTypeIsValueWrap(DomType k);
63constexpr bool domTypeIsDomElement(DomType);
64constexpr bool domTypeIsOwningItem(DomType);
66constexpr bool domTypeIsScriptElement(DomType);
70constexpr bool domTypeCanBeInline(DomType k)
71{
72 switch (k) {
73 case DomType::Empty:
74 case DomType::Map:
75 case DomType::List:
76 case DomType::ListP:
81 return true;
82 default:
83 return false;
84 }
85}
87
92
93inline bool noFilter(const DomItem &, const PathEls::PathComponent &, const DomItem &)
94{
95 return true;
96}
97
99// using DirectVisitor = function_ref<bool(Path, const DomItem &)>;
100
101namespace {
102template<typename T>
103struct IsMultiMap : std::false_type
104{
105};
106
107template<typename Key, typename T>
108struct IsMultiMap<QMultiMap<Key, T>> : std::true_type
109{
110};
111
112template<typename T>
113struct IsMap : std::false_type
114{
115};
116
117template<typename Key, typename T>
118struct IsMap<QMap<Key, T>> : std::true_type
119{
120};
121
122template<typename... Ts>
123using void_t = void;
124
125template<typename T, typename = void>
126struct IsDomObject : std::false_type
127{
128};
129
130template<typename T>
131struct IsDomObject<T, void_t<decltype(T::kindValue)>> : std::true_type
132{
133};
134
135template<typename T, typename = void>
136struct IsInlineDom : std::false_type
137{
138};
139
140template<typename T>
141struct IsInlineDom<T, void_t<decltype(T::kindValue)>>
142 : std::integral_constant<bool, domTypeCanBeInline(T::kindValue)>
143{
144};
145
146template<typename T>
147struct IsInlineDom<T *, void_t<decltype(T::kindValue)>> : std::true_type
148{
149};
150
151template<typename T>
152struct IsInlineDom<std::shared_ptr<T>, void_t<decltype(T::kindValue)>> : std::true_type
153{
154};
155
156template<typename T>
157struct IsSharedPointerToDomObject : std::false_type
158{
159};
160
161template<typename T>
162struct IsSharedPointerToDomObject<std::shared_ptr<T>> : IsDomObject<T>
163{
164};
165
166template<typename T, typename = void>
167struct IsList : std::false_type
168{
169};
170
171template<typename T>
172struct IsList<T, void_t<typename T::value_type>> : std::true_type
173{
174};
175
176}
177
178template<typename T>
180 int i;
181 T lp;
182
183 // TODO: these are extremely nasty. What is this int doing in here?
184 T *data() { return reinterpret_cast<T *>(this); }
185 const T *data() const { return reinterpret_cast<const T *>(this); }
186
188 SubclassStorage(T &&el) { el.moveTo(data()); }
189 SubclassStorage(const T *el) { el->copyTo(data()); }
193 {
194 data()->~T();
195 o.data()->copyTo(data());
196 return *this;
197 }
198 ~SubclassStorage() { data()->~T(); }
199};
200
202{
203public:
204 using FilterT = function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>;
205
206 virtual ~DomBase() = default;
207
208 DomBase *domBase() { return this; }
209 const DomBase *domBase() const { return this; }
210
211 // minimal overload set:
212 virtual DomType kind() const = 0;
213 virtual DomKind domKind() const;
214 virtual Path pathFromOwner() const = 0;
215 virtual Path canonicalPath(const DomItem &self) const = 0;
216 virtual bool
218 DirectVisitor visitor) const = 0; // iterates the *direct* subpaths, returns
219 // false if a quick end was requested
220
222 const DomItem &self) const; // the DomItem corresponding to the canonicalSource source
223 virtual void dump(const DomItem &, const Sink &sink, int indent, FilterT filter) const;
224 virtual quintptr id() const;
225 QString typeName() const;
226
227 virtual QList<QString> fields(const DomItem &self) const;
228 virtual DomItem field(const DomItem &self, QStringView name) const;
229
230 virtual index_type indexes(const DomItem &self) const;
231 virtual DomItem index(const DomItem &self, index_type index) const;
232
233 virtual QSet<QString> const keys(const DomItem &self) const;
234 virtual DomItem key(const DomItem &self, const QString &name) const;
235
236 virtual QString canonicalFilePath(const DomItem &self) const;
237
238 virtual void writeOut(const DomItem &self, OutWriter &lw) const;
239
240 virtual QCborValue value() const {
241 return QCborValue();
242 }
243};
244
246{
247 switch (k) {
248 case DomType::Empty:
249 return DomKind::Empty;
250 case DomType::List:
251 case DomType::ListP:
252 return DomKind::List;
253 case DomType::Map:
254 return DomKind::Map;
255 case DomType::ConstantData:
256 return DomKind::Value;
257 default:
258 return DomKind::Object;
259 }
260}
261
262class QMLDOM_EXPORT Empty final : public DomBase
263{
264public:
265 constexpr static DomType kindValue = DomType::Empty;
266 DomType kind() const override { return kindValue; }
267
268 Empty *operator->() { return this; }
269 const Empty *operator->() const { return this; }
270 Empty &operator*() { return *this; }
271 const Empty &operator*() const { return *this; }
272
273 Empty();
274 quintptr id() const override { return ~quintptr(0); }
275 Path pathFromOwner() const override;
276 Path canonicalPath(const DomItem &self) const override;
277 DomItem containingObject(const DomItem &self) const override;
278 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
279 void dump(const DomItem &, const Sink &s, int indent,
280 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter)
281 const override;
282};
283
285protected:
286 DomElement& operator=(const DomElement&) = default;
287public:
288 DomElement(const Path &pathFromOwner = Path());
289 DomElement(const DomElement &o) = default;
290 Path pathFromOwner() const override { return m_pathFromOwner; }
291 Path canonicalPath(const DomItem &self) const override;
292 DomItem containingObject(const DomItem &self) const override;
293 virtual void updatePathFromOwner(const Path &newPath);
294
295private:
296 Path m_pathFromOwner;
297};
298
299class QMLDOM_EXPORT Map final : public DomElement
300{
301public:
302 constexpr static DomType kindValue = DomType::Map;
303 DomType kind() const override { return kindValue; }
304
305 Map *operator->() { return this; }
306 const Map *operator->() const { return this; }
307 Map &operator*() { return *this; }
308 const Map &operator*() const { return *this; }
309
310 using LookupFunction = std::function<DomItem(const DomItem &, QString)>;
311 using Keys = std::function<QSet<QString>(const DomItem &)>;
312 Map(const Path &pathFromOwner, const LookupFunction &lookup,
313 const Keys &keys, const QString &targetType);
314 quintptr id() const override;
315 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
316 QSet<QString> const keys(const DomItem &self) const override;
317 DomItem key(const DomItem &self, const QString &name) const override;
318
319 template<typename T>
320 static Map fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
321 template<typename T>
322 static Map fromMultiMap(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
323 template<typename T>
324 static Map
326 const Path &pathFromOwner, const QMap<QString, T> &mmap,
327 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper);
328
329 template<typename T>
330 static Map fromFileRegionMap(
331 const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map);
332 template<typename T>
334 const Path &pathFromOwner, const QMap<FileLocationRegion, QList<T>> &map);
335
336private:
337 template<typename MapT>
338 static QSet<QString> fileRegionKeysFromMap(const MapT &map);
339 LookupFunction m_lookup;
340 Keys m_keys;
341 QString m_targetType;
342};
343
344class QMLDOM_EXPORT List final : public DomElement
345{
346public:
347 constexpr static DomType kindValue = DomType::List;
348 DomType kind() const override { return kindValue; }
349
350 List *operator->() { return this; }
351 const List *operator->() const { return this; }
352 List &operator*() { return *this; }
353 const List &operator*() const { return *this; }
354
355 using LookupFunction = std::function<DomItem(const DomItem &, index_type)>;
358 std::function<bool(const DomItem &, function_ref<bool(index_type, function_ref<DomItem()>)>)>;
359
360 List(const Path &pathFromOwner, const LookupFunction &lookup, const Length &length,
361 const IteratorFunction &iterator, const QString &elType);
362 quintptr id() const override;
363 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
364 void
365 dump(const DomItem &, const Sink &s, int indent,
366 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>) const override;
367 index_type indexes(const DomItem &self) const override;
368 DomItem index(const DomItem &self, index_type index) const override;
369
370 template<typename T>
371 static List
372 fromQList(const Path &pathFromOwner, const QList<T> &list,
373 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
375 template<typename T>
376 static List
377 fromQListRef(const Path &pathFromOwner, const QList<T> &list,
378 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
380 void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
381 void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
382
383private:
384 LookupFunction m_lookup;
385 Length m_length;
386 IteratorFunction m_iterator;
387 QString m_elType;
388};
389
391{
392public:
393 constexpr static DomType kindValue = DomType::ListP;
394 DomType kind() const override { return kindValue; }
395
396 ListPBase(const Path &pathFromOwner, const QList<const void *> &pList, const QString &elType)
397 : DomElement(pathFromOwner), m_pList(pList), m_elType(elType)
398 {
399 }
400 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
401 virtual void copyTo(ListPBase *) const { Q_ASSERT(false); };
402 virtual void moveTo(ListPBase *) const { Q_ASSERT(false); };
403 quintptr id() const override { return quintptr(0); }
404 index_type indexes(const DomItem &) const override { return index_type(m_pList.size()); }
405 void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
406 void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
407
408protected:
409 QList<const void *> m_pList;
411};
412
413template<typename T>
414class ListPT final : public ListPBase
415{
416public:
417 constexpr static DomType kindValue = DomType::ListP;
418
419 ListPT(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
421 : ListPBase(pathFromOwner, {},
422 (elType.isEmpty() ? QLatin1String(typeid(T).name()) : elType))
423 {
424 static_assert(sizeof(ListPBase) == sizeof(ListPT),
425 "ListPT does not have the same size as ListPBase");
426 static_assert(alignof(ListPBase) == alignof(ListPT),
427 "ListPT does not have the same size as ListPBase");
428 m_pList.reserve(pList.size());
429 if (options == ListOptions::Normal) {
430 for (const void *p : pList)
431 m_pList.append(p);
432 } else if (options == ListOptions::Reverse) {
433 for (qsizetype i = pList.size(); i-- != 0;)
434 // probably writing in reverse and reading sequentially would be better
435 m_pList.append(pList.at(i));
436 } else {
437 Q_ASSERT(false);
438 }
439 }
440 void copyTo(ListPBase *t) const override { new (t) ListPT(*this); }
441 void moveTo(ListPBase *t) const override { new (t) ListPT(std::move(*this)); }
442 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
443
444 DomItem index(const DomItem &self, index_type index) const override;
445};
446
448{
449public:
450 constexpr static DomType kindValue = DomType::ListP;
451 template<typename T>
452 ListP(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
455 {
456 }
457 ListP() = delete;
458
459 ListPBase *operator->() { return list.data(); }
460 const ListPBase *operator->() const { return list.data(); }
461 ListPBase &operator*() { return *list.data(); }
462 const ListPBase &operator*() const { return *list.data(); }
463
464private:
466};
467
468class QMLDOM_EXPORT ConstantData final : public DomElement
469{
470public:
472 DomType kind() const override { return kindValue; }
473
478
479 ConstantData *operator->() { return this; }
480 const ConstantData *operator->() const { return this; }
481 ConstantData &operator*() { return *this; }
482 const ConstantData &operator*() const { return *this; }
483
484 ConstantData(const Path &pathFromOwner, const QCborValue &value,
485 Options options = Options::MapIsMap);
486 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
487 quintptr id() const override;
488 DomKind domKind() const override;
489 QCborValue value() const override { return m_value; }
490 Options options() const { return m_options; }
491private:
492 QCborValue m_value;
493 Options m_options;
494};
495
497{
498public:
500 DomType kind() const final override { return m_kind; }
501
502 quintptr id() const final override { return m_id; }
503 DomKind domKind() const final override { return m_domKind; }
504
505 template <typename T>
506 T const *as() const
507 {
508 if (m_options & SimpleWrapOption::ValueType) {
509 if (m_value.metaType() == QMetaType::fromType<T>())
510 return static_cast<const T *>(m_value.constData());
511 return nullptr;
512 } else {
513 return m_value.value<const T *>();
514 }
515 }
516
518 virtual void copyTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
519 virtual void moveTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
520 bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
521 {
522 Q_ASSERT(false);
523 return true;
524 }
525
526protected:
527 friend class TestDomItem;
528 SimpleObjectWrapBase(const Path &pathFromOwner, const QVariant &value, quintptr idValue,
529 DomType kind = kindValue,
530 SimpleWrapOptions options = SimpleWrapOption::None)
531 : DomElement(pathFromOwner),
532 m_kind(kind),
534 m_value(value),
535 m_id(idValue),
537 {
538 }
539
545};
546
547template<typename T>
548class SimpleObjectWrapT final : public SimpleObjectWrapBase
549{
550public:
552
553 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
554 {
555 return asT()->iterateDirectSubpaths(self, visitor);
556 }
557
558 void writeOut(const DomItem &self, OutWriter &lw) const override;
559
560 const T *asT() const
561 {
562 if constexpr (domTypeIsValueWrap(T::kindValue)) {
563 if (m_value.metaType() == QMetaType::fromType<T>())
564 return static_cast<const T *>(m_value.constData());
565 return nullptr;
566 } else if constexpr (domTypeIsObjWrap(T::kindValue)) {
567 return m_value.value<const T *>();
568 } else {
569 // need dependent static assert to not unconditially trigger
570 static_assert(!std::is_same_v<T, T>, "wrapping of unexpected type");
571 return nullptr; // necessary to avoid warnings on INTEGRITY
572 }
573 }
574
575 void copyTo(SimpleObjectWrapBase *target) const override
576 {
577 static_assert(sizeof(SimpleObjectWrapBase) == sizeof(SimpleObjectWrapT),
578 "Size mismatch in SimpleObjectWrapT");
579 static_assert(alignof(SimpleObjectWrapBase) == alignof(SimpleObjectWrapT),
580 "Size mismatch in SimpleObjectWrapT");
581 new (target) SimpleObjectWrapT(*this);
582 }
583
584 void moveTo(SimpleObjectWrapBase *target) const override
585 {
586 static_assert(sizeof(SimpleObjectWrapBase) == sizeof(SimpleObjectWrapT),
587 "Size mismatch in SimpleObjectWrapT");
588 static_assert(alignof(SimpleObjectWrapBase) == alignof(SimpleObjectWrapT),
589 "Size mismatch in SimpleObjectWrapT");
590 new (target) SimpleObjectWrapT(std::move(*this));
591 }
592
593 SimpleObjectWrapT(const Path &pathFromOwner, const QVariant &v,
594 quintptr idValue, SimpleWrapOptions o)
595 : SimpleObjectWrapBase(pathFromOwner, v, idValue, T::kindValue, o)
596 {
597 Q_ASSERT(domTypeIsValueWrap(T::kindValue) == bool(o & SimpleWrapOption::ValueType));
598 }
599};
600
602{
603public:
605
606 SimpleObjectWrapBase *operator->() { return wrap.data(); }
607 const SimpleObjectWrapBase *operator->() const { return wrap.data(); }
608 SimpleObjectWrapBase &operator*() { return *wrap.data(); }
609 const SimpleObjectWrapBase &operator*() const { return *wrap.data(); }
610
611 template<typename T>
612 static SimpleObjectWrap fromObjectRef(const Path &pathFromOwner, T &value)
613 {
614 return SimpleObjectWrap(pathFromOwner, value);
615 }
617
618private:
619 template<typename T>
620 SimpleObjectWrap(const Path &pathFromOwner, T &value)
621 {
622 using BaseT = std::decay_t<T>;
623 if constexpr (domTypeIsObjWrap(BaseT::kindValue)) {
624 new (wrap.data()) SimpleObjectWrapT<BaseT>(pathFromOwner, QVariant::fromValue(&value),
625 quintptr(&value), SimpleWrapOption::None);
626 } else if constexpr (domTypeIsValueWrap(BaseT::kindValue)) {
627 new (wrap.data()) SimpleObjectWrapT<BaseT>(pathFromOwner, QVariant::fromValue(value),
628 quintptr(0), SimpleWrapOption::ValueType);
629 } else {
630 qCWarning(domLog) << "Unexpected object to wrap in SimpleObjectWrap: "
631 << domTypeToString(BaseT::kindValue);
632 Q_ASSERT_X(false, "SimpleObjectWrap",
633 "simple wrap of unexpected object"); // allow? (mocks for testing,...)
634 new (wrap.data())
635 SimpleObjectWrapT<BaseT>(pathFromOwner, nullptr, 0, SimpleWrapOption::None);
636 }
637 }
639};
640
642{
644public:
645 constexpr static DomType kindValue = DomType::Reference;
646 DomType kind() const override { return kindValue; }
647
648 Reference *operator->() { return this; }
649 const Reference *operator->() const { return this; }
650 Reference &operator*() { return *this; }
651 const Reference &operator*() const { return *this; }
652
653 bool shouldCache() const;
654 Reference(const Path &referredObject = Path(), const Path &pathFromOwner = Path(),
655 const SourceLocation &loc = SourceLocation());
656 quintptr id() const override;
657 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
658 DomItem field(const DomItem &self, QStringView name) const override;
659 QList<QString> fields(const DomItem &self) const override;
660 index_type indexes(const DomItem &) const override { return 0; }
661 DomItem index(const DomItem &, index_type) const override;
662 QSet<QString> const keys(const DomItem &) const override { return {}; }
663 DomItem key(const DomItem &, const QString &) const override;
664
665 DomItem get(const DomItem &self, const ErrorHandler &h = nullptr,
666 QList<Path> *visitedRefs = nullptr) const;
667 QList<DomItem> getAll(const DomItem &self, const ErrorHandler &h = nullptr,
668 QList<Path> *visitedRefs = nullptr) const;
669
671};
672
673namespace FileLocations {
674struct Info;
675}
676
677/*!
678 \internal
679 \brief A common base class for all the script elements.
680
681 This marker class allows to use all the script elements as a ScriptElement*, using virtual
682 dispatch. For now, it does not add any extra functionality, compared to a DomElement, but allows
683 to forbid DomElement* at the places where only script elements are required.
684 */
685// TODO: do we need another marker struct like this one to differentiate expressions from
686// statements? This would allow to avoid mismatchs between script expressions and script statements,
687// using type-safety.
689{
690 template<typename T>
691 using PointerType = std::shared_ptr<T>;
692
693 using DomElement::DomElement;
694 virtual void
695 createFileLocations(const std::shared_ptr<FileLocations::Node> &fileLocationOfOwner) = 0;
696
698 void setSemanticScope(const QQmlJSScope::ConstPtr &scope);
699
700private:
701 QQmlJSScope::ConstPtr m_scope;
702};
703
704/*!
705 \internal
706 \brief Use this to contain any script element.
707 */
709{
710private:
711 template<typename... T>
713
714 template<typename T, typename Variant>
715 struct TypeIsInVariant;
716
717 template<typename T, typename... Ts>
718 struct TypeIsInVariant<T, std::variant<Ts...>> : public std::disjunction<std::is_same<T, Ts>...>
719 {
720 };
721
722public:
729
730 template<typename T>
731 static ScriptElementVariant fromElement(const T &element)
732 {
733 static_assert(TypeIsInVariant<T, ScriptElementT>::value,
734 "Cannot construct ScriptElementVariant from T, as it is missing from the "
735 "ScriptElementT.");
737 p.m_data = element;
738 return p;
739 }
740
742
743 operator bool() const { return m_data.has_value(); }
744
745 template<typename F>
746 void visitConst(F &&visitor) const
747 {
748 if (m_data)
749 std::visit(std::forward<F>(visitor), *m_data);
750 }
751
752 template<typename F>
753 void visit(F &&visitor)
754 {
755 if (m_data)
756 std::visit(std::forward<F>(visitor), *m_data);
757 }
758 std::optional<ScriptElementT> data() { return m_data; }
759 void setData(const ScriptElementT &data) { m_data = data; }
760
761private:
762 std::optional<ScriptElementT> m_data;
763};
764
765/*!
766 \internal
767
768 To avoid cluttering the already unwieldy \l ElementT type below with all the types that the
769 different script elements can have, wrap them in an extra class. It will behave like an internal
770 Dom structure (e.g. like a List or a Map) and contain a pointer the the script element.
771 */
773{
774public:
776
778
779 DomBase *operator->() { return m_element.base().get(); }
780 const DomBase *operator->() const { return m_element.base().get(); }
781 DomBase &operator*() { return *m_element.base(); }
782 const DomBase &operator*() const { return *m_element.base(); }
783
784 ScriptElementVariant element() const { return m_element; }
785
786private:
787 ScriptElementVariant m_element;
788};
789
790// TODO: create more "groups" to simplify this variant? Maybe into Internal, ScriptExpression, ???
791using ElementT =
792 std::variant<ConstantData, Empty, List, ListP, Map, Reference, ScriptElementDomWrapper,
794 const DomEnvironment *, const DomUniverse *, const EnumDecl *,
796 const GlobalComponent *, const GlobalScope *, const JsFile *,
797 const JsResource *, const LoadInfo *, const MockObject *, const MockOwner *,
798 const ModuleIndex *, const ModuleScope *, const QmlComponent *,
799 const QmlDirectory *, const QmlFile *, const QmlObject *, const QmldirFile *,
800 const QmltypesComponent *, const QmltypesFile *, const ScriptExpression *>;
801
802using TopT = std::variant<
803 std::monostate,
804 std::shared_ptr<DomEnvironment>,
805 std::shared_ptr<DomUniverse>>;
806
807using OwnerT =
808 std::variant<std::monostate, std::shared_ptr<ModuleIndex>, std::shared_ptr<MockOwner>,
809 std::shared_ptr<ExternalItemInfoBase>, std::shared_ptr<ExternalItemPairBase>,
810 std::shared_ptr<QmlDirectory>, std::shared_ptr<QmldirFile>,
811 std::shared_ptr<JsFile>, std::shared_ptr<QmlFile>,
812 std::shared_ptr<QmltypesFile>, std::shared_ptr<GlobalScope>,
813 std::shared_ptr<ScriptExpression>, std::shared_ptr<AstComments>,
814 std::shared_ptr<LoadInfo>, std::shared_ptr<FileLocations::Node>,
815 std::shared_ptr<DomEnvironment>, std::shared_ptr<DomUniverse>>;
816
817inline bool emptyChildrenVisitor(Path, const DomItem &, bool)
818{
819 return true;
820}
821
822class MutableDomItem;
823
825{
826public:
832
833 FileToLoad(const std::weak_ptr<DomEnvironment> &environment, const QString &canonicalPath,
834 const QString &logicalPath, const std::optional<InMemoryContents> &content);
835 FileToLoad() = default;
836
837 static FileToLoad fromMemory(const std::weak_ptr<DomEnvironment> &environment,
838 const QString &path, const QString &data);
839 static FileToLoad fromFileSystem(const std::weak_ptr<DomEnvironment> &environment,
840 const QString &canonicalPath);
841
842 std::weak_ptr<DomEnvironment> environment() const { return m_environment; }
843 QString canonicalPath() const { return m_canonicalPath; }
844 QString logicalPath() const { return m_logicalPath; }
845 void setCanonicalPath(const QString &canonicalPath) { m_canonicalPath = canonicalPath; }
846 void setLogicalPath(const QString &logicalPath) { m_logicalPath = logicalPath; }
847 std::optional<InMemoryContents> content() const { return m_content; }
848
849private:
850 std::weak_ptr<DomEnvironment> m_environment;
851 QString m_canonicalPath;
852 QString m_logicalPath;
853 std::optional<InMemoryContents> m_content;
854};
855
858public:
859 using Callback = function<void(const Path &, const DomItem &, const DomItem &)>;
860
862 using Visitor = function_ref<bool(const Path &, const DomItem &)>;
863 using ChildrenVisitor = function_ref<bool(const Path &, const DomItem &, bool)>;
864
866 static ErrorGroups myErrors();
869
871
872 template<typename F>
873 auto visitEl(F f) const
874 {
875 return std::visit(f, this->m_element);
876 }
877
878 explicit operator bool() const { return m_kind != DomType::Empty; }
880 return m_kind;
881 }
882 QString internalKindStr() const { return domTypeToString(internalKind()); }
884 {
885 if (m_kind == DomType::ConstantData)
886 return std::get<ConstantData>(m_element).domKind();
887 else
888 return kind2domKind(m_kind);
889 }
890
891 Path canonicalPath() const;
892
893 DomItem filterUp(function_ref<bool(DomType k, const DomItem &)> filter, FilterUpOptions options) const;
895 DomItem container() const;
896 DomItem owner() const;
897 DomItem top() const;
898 DomItem environment() const;
899 DomItem universe() const;
900 DomItem containingFile() const;
902 DomItem goToFile(const QString &filePath) const;
903 DomItem goUp(int) const;
904 DomItem directParent() const;
905
906 DomItem qmlObject(GoTo option = GoTo::Strict,
908 DomItem fileObject(GoTo option = GoTo::Strict) const;
909 DomItem rootQmlObject(GoTo option = GoTo::Strict) const;
910 DomItem globalScope() const;
911 DomItem component(GoTo option = GoTo::Strict) const;
915
916 // convenience getters
917 DomItem get(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
918 QList<DomItem> getAll(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
924 bool isCanonicalChild(const DomItem &child) const;
925 bool hasAnnotations() const;
926 QString name() const { return field(Fields::name).value().toString(); }
927 DomItem pragmas() const { return field(Fields::pragmas); }
928 DomItem ids() const { return field(Fields::ids); }
929 QString idStr() const { return field(Fields::idStr).value().toString(); }
930 DomItem propertyInfos() const { return field(Fields::propertyInfos); }
931 PropertyInfo propertyInfoWithName(const QString &name) const;
933 DomItem propertyDefs() const { return field(Fields::propertyDefs); }
934 DomItem bindings() const { return field(Fields::bindings); }
935 DomItem methods() const { return field(Fields::methods); }
936 DomItem enumerations() const { return field(Fields::enumerations); }
937 DomItem children() const { return field(Fields::children); }
938 DomItem child(index_type i) const { return field(Fields::children).index(i); }
940 {
942 return field(Fields::annotations);
943 else
944 return DomItem();
945 }
946
947 bool resolve(const Path &path, Visitor visitor, const ErrorHandler &errorHandler,
948 ResolveOptions options = ResolveOption::None, const Path &fullPath = Path(),
949 QList<Path> *visitedRefs = nullptr) const;
950
951 DomItem operator[](const Path &path) const;
952 DomItem operator[](QStringView component) const;
953 DomItem operator[](const QString &component) const;
954 DomItem operator[](const char16_t *component) const
955 {
956 return (*this)[QStringView(component)];
957 } // to avoid clash with stupid builtin ptrdiff_t[DomItem&], coming from C
958 DomItem operator[](index_type i) const { return index(i); }
959 DomItem operator[](int i) const { return index(i); }
960 index_type size() const { return indexes() + keys().size(); }
961 index_type length() const { return size(); }
962
963 DomItem path(const Path &p, const ErrorHandler &h = &defaultErrorHandler) const;
964 DomItem path(const QString &p, const ErrorHandler &h = &defaultErrorHandler) const;
965 DomItem path(QStringView p, const ErrorHandler &h = &defaultErrorHandler) const;
966
967 QList<QString> fields() const;
968 DomItem field(QStringView name) const;
969
970 index_type indexes() const;
971 DomItem index(index_type) const;
972 bool visitIndexes(function_ref<bool(const DomItem &)> visitor) const;
973
974 QSet<QString> keys() const;
975 QStringList sortedKeys() const;
976 DomItem key(const QString &name) const;
977 DomItem key(QStringView name) const { return key(name.toString()); }
978 bool visitKeys(function_ref<bool(const QString &, const DomItem &)> visitor) const;
979
980 QList<DomItem> values() const;
981 void writeOutPre(OutWriter &lw) const;
982 void writeOut(OutWriter &lw) const;
983 void writeOutPost(OutWriter &lw) const;
984 bool writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks) const;
985 bool writeOut(const QString &path, int nBackups = 2,
986 const LineWriterOptions &opt = LineWriterOptions(), FileWriter *fw = nullptr,
987 WriteOutChecks extraChecks = WriteOutCheck::Default) const;
988
989 bool visitTree(const Path &basePath, ChildrenVisitor visitor,
990 VisitOptions options = VisitOption::Default,
991 ChildrenVisitor openingVisitor = emptyChildrenVisitor,
992 ChildrenVisitor closingVisitor = emptyChildrenVisitor,
993 const FieldFilter &filter = FieldFilter::noFilter()) const;
994 bool visitPrototypeChain(function_ref<bool(const DomItem &)> visitor,
995 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
996 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
997 QList<Path> *visitedRefs = nullptr) const;
998 bool visitDirectAccessibleScopes(function_ref<bool(const DomItem &)> visitor,
999 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
1000 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1001 QList<Path> *visitedRefs = nullptr) const;
1002 bool
1003 visitStaticTypePrototypeChains(function_ref<bool(const DomItem &)> visitor,
1004 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
1005 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1006 QList<Path> *visitedRefs = nullptr) const;
1007
1008 bool visitUp(function_ref<bool(const DomItem &)> visitor) const;
1009 bool visitScopeChain(
1010 function_ref<bool(const DomItem &)> visitor, LookupOptions = LookupOption::Normal,
1011 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1012 QList<Path> *visitedRefs = nullptr) const;
1014 const QString &name, function_ref<bool(const DomItem &)> visitor) const;
1015 bool visitLookup1(
1016 const QString &symbolName, function_ref<bool(const DomItem &)> visitor,
1017 LookupOptions = LookupOption::Normal, const ErrorHandler &h = nullptr,
1018 QSet<quintptr> *visited = nullptr, QList<Path> *visitedRefs = nullptr) const;
1019 bool visitLookup(
1020 const QString &symbolName, function_ref<bool(const DomItem &)> visitor,
1021 LookupType type = LookupType::Symbol, LookupOptions = LookupOption::Normal,
1022 const ErrorHandler &errorHandler = nullptr, QSet<quintptr> *visited = nullptr,
1023 QList<Path> *visitedRefs = nullptr) const;
1025 const QString &name, function_ref<bool(const DomItem &)> visitor) const;
1027 const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
1029 const QString &symbolName, LookupType type = LookupType::Symbol,
1030 LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
1032 const QString &symbolName, LookupType type = LookupType::Symbol,
1033 LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
1034
1035 quintptr id() const;
1036 Path pathFromOwner() const;
1037 QString canonicalFilePath() const;
1039 bool commitToBase(const std::shared_ptr<DomEnvironment> &validPtr = nullptr) const;
1041 QCborValue value() const;
1042
1043 void dumpPtr(const Sink &sink) const;
1044 void dump(const Sink &, int indent = 0,
1045 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter =
1046 noFilter) const;
1048 dump(const QString &path,
1049 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter,
1050 int nBackups = 2, int indent = 0, FileWriter *fw = nullptr) const;
1051 QString toString() const;
1052
1053 // OwnigItem elements
1054 int derivedFrom() const;
1055 int revision() const;
1056 QDateTime createdAt() const;
1057 QDateTime frozenAt() const;
1059
1060 void addError(ErrorMessage &&msg) const;
1061 ErrorHandler errorHandler() const;
1062 void clearErrors(const ErrorGroups &groups = ErrorGroups({}), bool iterate = true) const;
1063 // return false if a quick exit was requested
1064 bool iterateErrors(
1065 function_ref<bool (const DomItem &, const ErrorMessage &)> visitor, bool iterate,
1066 Path inPath = Path()) const;
1067
1068 bool iterateSubOwners(function_ref<bool(const DomItem &owner)> visitor) const;
1069 bool iterateDirectSubpaths(DirectVisitor v) const;
1070
1071 template<typename T>
1072 DomItem subDataItem(const PathEls::PathComponent &c, const T &value,
1073 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1074 template<typename T>
1075 DomItem subDataItemField(QStringView f, const T &value,
1076 ConstantData::Options options = ConstantData::Options::MapIsMap) const
1077 {
1078 return subDataItem(PathEls::Field(f), value, options);
1079 }
1080 template<typename T>
1081 DomItem subValueItem(const PathEls::PathComponent &c, const T &value,
1082 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1083 template<typename T>
1084 bool dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value,
1085 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1086 template<typename T>
1087 bool dvValueField(DirectVisitor visitor, QStringView f, const T &value,
1088 ConstantData::Options options = ConstantData::Options::MapIsMap) const
1089 {
1090 return this->dvValue<T>(std::move(visitor), PathEls::Field(f), value, options);
1091 }
1092 template<typename F>
1093 bool dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c, F valueF,
1094 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1095 template<typename F>
1096 bool dvValueLazyField(DirectVisitor visitor, QStringView f, F valueF,
1097 ConstantData::Options options = ConstantData::Options::MapIsMap) const
1098 {
1099 return this->dvValueLazy(std::move(visitor), PathEls::Field(f), valueF, options);
1100 }
1101 DomItem subLocationItem(const PathEls::PathComponent &c, SourceLocation loc) const
1102 {
1103 return this->subDataItem(c, sourceLocationToQCborValue(loc));
1104 }
1105 // bool dvSubReference(DirectVisitor visitor, const PathEls::PathComponent &c, Path
1106 // referencedObject);
1107 DomItem subReferencesItem(const PathEls::PathComponent &c, const QList<Path> &paths) const;
1108 DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const;
1109 bool dvReference(DirectVisitor visitor, const PathEls::PathComponent &c, const Path &referencedObject) const
1110 {
1111 return dvItem(std::move(visitor), c, [c, this, referencedObject]() {
1112 return this->subReferenceItem(c, referencedObject);
1113 });
1114 }
1116 DirectVisitor visitor, const PathEls::PathComponent &c, const QList<Path> &paths) const
1117 {
1118 return dvItem(std::move(visitor), c, [c, this, paths]() {
1119 return this->subReferencesItem(c, paths);
1120 });
1121 }
1122 bool dvReferenceField(DirectVisitor visitor, QStringView f, const Path &referencedObject) const
1123 {
1124 return dvReference(std::move(visitor), PathEls::Field(f), referencedObject);
1125 }
1126 bool dvReferencesField(DirectVisitor visitor, QStringView f, const QList<Path> &paths) const
1127 {
1128 return dvReferences(std::move(visitor), PathEls::Field(f), paths);
1129 }
1130 bool dvItem(DirectVisitor visitor, const PathEls::PathComponent &c, function_ref<DomItem()> it) const
1131 {
1132 return visitor(c, it);
1133 }
1134 bool dvItemField(DirectVisitor visitor, QStringView f, function_ref<DomItem()> it) const
1135 {
1136 return dvItem(std::move(visitor), PathEls::Field(f), it);
1137 }
1138 DomItem subListItem(const List &list) const;
1139 DomItem subMapItem(const Map &map) const;
1141 {
1142 return DomItem(m_top, m_owner, m_ownerPath, obj);
1143 }
1144
1146 {
1147 Q_ASSERT(obj);
1148 return DomItem(m_top, m_owner, m_ownerPath, ScriptElementDomWrapper(obj));
1149 }
1150
1151 template<typename Owner>
1152 DomItem subOwnerItem(const PathEls::PathComponent &c, Owner o) const
1153 {
1154 if constexpr (domTypeIsUnattachedOwningItem(Owner::element_type::kindValue))
1155 return DomItem(m_top, o, canonicalPath().withComponent(c), o.get());
1156 else
1157 return DomItem(m_top, o, Path(), o.get());
1158 }
1159 template<typename T>
1160 DomItem wrap(const PathEls::PathComponent &c, const T &obj) const;
1161 template<typename T>
1162 DomItem wrapField(QStringView f, const T &obj) const
1163 {
1164 return wrap<T>(PathEls::Field(f), obj);
1165 }
1166 template<typename T>
1167 bool dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj) const;
1168 template<typename T>
1169 bool dvWrapField(DirectVisitor visitor, QStringView f, T &obj) const
1170 {
1171 return dvWrap<T>(std::move(visitor), PathEls::Field(f), obj);
1172 }
1173
1174 DomItem() = default;
1175 DomItem(const std::shared_ptr<DomEnvironment> &);
1176 DomItem(const std::shared_ptr<DomUniverse> &);
1177
1178 // TODO move to DomEnvironment?
1179 static DomItem fromCode(const QString &code, DomType fileType = DomType::QmlFile);
1180
1181 // --- start of potentially dangerous stuff, make private? ---
1182
1183 std::shared_ptr<DomTop> topPtr() const;
1184 std::shared_ptr<OwningItem> owningItemPtr() const;
1185
1186 // keep the DomItem around to ensure that it doesn't get deleted
1187 template<typename T, typename std::enable_if<std::is_base_of_v<DomBase, T>, bool>::type = true>
1188 T const *as() const
1189 {
1190 if (m_kind == T::kindValue) {
1191 if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
1192 return std::get<SimpleObjectWrap>(m_element)->as<T>();
1193 else
1194 return static_cast<T const *>(base());
1195 }
1196 return nullptr;
1197 }
1198
1199 template<typename T, typename std::enable_if<!std::is_base_of_v<DomBase, T>, bool>::type = true>
1200 T const *as() const
1201 {
1202 if (m_kind == T::kindValue) {
1203 Q_ASSERT(domTypeIsObjWrap(m_kind) || domTypeIsValueWrap(m_kind));
1204 return std::get<SimpleObjectWrap>(m_element)->as<T>();
1205 }
1206 return nullptr;
1207 }
1208
1209 template<typename T>
1210 std::shared_ptr<T> ownerAs() const;
1211
1212 template<typename Owner, typename T>
1213 DomItem copy(const Owner &owner, const Path &ownerPath, const T &base) const
1214 {
1215 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1216 static_assert(IsInlineDom<std::decay_t<T>>::value, "Expected an inline item or pointer");
1217 return DomItem(m_top, owner, ownerPath, base);
1218 }
1219
1220 template<typename Owner>
1221 DomItem copy(const Owner &owner, const Path &ownerPath) const
1222 {
1223 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1224 return DomItem(m_top, owner, ownerPath, owner.get());
1225 }
1226
1227 template<typename T>
1228 DomItem copy(const T &base) const
1229 {
1230 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1231 using BaseT = std::decay_t<T>;
1232 static_assert(!std::is_same_v<BaseT, ElementT>,
1233 "variant not supported, pass in the stored types");
1234 static_assert(IsInlineDom<BaseT>::value || std::is_same_v<BaseT, std::monostate>,
1235 "expected either a pointer or an inline item");
1236
1237 if constexpr (IsSharedPointerToDomObject<BaseT>::value)
1238 return DomItem(m_top, base, Path(), base.get());
1239 else if constexpr (IsInlineDom<BaseT>::value)
1240 return DomItem(m_top, m_owner, m_ownerPath, base);
1241
1242 Q_UNREACHABLE_RETURN(DomItem(m_top, m_owner, m_ownerPath, nullptr));
1243 }
1244
1245private:
1246 enum class WriteOutCheckResult { Success, Failed };
1247 WriteOutCheckResult performWriteOutChecks(const DomItem &, OutWriter &, WriteOutChecks) const;
1248 const DomBase *base() const;
1249
1250 template<typename Env, typename Owner>
1251 DomItem(Env, Owner, Path, std::nullptr_t) : DomItem()
1252 {
1253 }
1254
1255 template<typename Env, typename Owner, typename T,
1256 typename = std::enable_if_t<IsInlineDom<std::decay_t<T>>::value>>
1257 DomItem(Env env, Owner owner, const Path &ownerPath, const T &el)
1258 : m_top(env), m_owner(owner), m_ownerPath(ownerPath), m_element(el)
1259 {
1260 using BaseT = std::decay_t<T>;
1261 if constexpr (std::is_pointer_v<BaseT>) {
1262 if (!el || el->kind() == DomType::Empty) { // avoid null ptr, and allow only a
1263 // single kind of Empty
1264 m_kind = DomType::Empty;
1265 m_top = std::monostate();
1266 m_owner = std::monostate();
1267 m_ownerPath = Path();
1268 m_element = Empty();
1269 } else {
1270 using DomT = std::remove_pointer_t<BaseT>;
1271 m_element = el;
1272 m_kind = DomT::kindValue;
1273 }
1274 } else {
1275 static_assert(!std::is_same_v<BaseT, ElementT>,
1276 "variant not supported, pass in the internal type");
1277 m_kind = el->kind();
1278 }
1279 }
1280 friend class DomBase;
1281 friend class DomElement;
1282 friend class Map;
1283 friend class List;
1284 friend class QmlObject;
1285 friend class DomUniverse;
1286 friend class DomEnvironment;
1288 friend class ConstantData;
1289 friend class MutableDomItem;
1290 friend class ScriptExpression;
1291 friend class AstComments;
1292 friend class FileLocations::Node;
1293 friend class TestDomItem;
1294 friend QMLDOM_EXPORT bool operator==(const DomItem &, const DomItem &);
1295 DomType m_kind = DomType::Empty;
1296 TopT m_top;
1297 OwnerT m_owner;
1298 Path m_ownerPath;
1299 ElementT m_element = Empty();
1300};
1301
1302QMLDOM_EXPORT bool operator==(const DomItem &o1, const DomItem &o2);
1303
1304inline bool operator!=(const DomItem &o1, const DomItem &o2)
1305{
1306 return !(o1 == o2);
1307}
1308
1309template<typename T>
1310static DomItem keyMultiMapHelper(const DomItem &self, const QString &key,
1311 const QMultiMap<QString, T> &mmap)
1312{
1313 auto it = mmap.find(key);
1314 auto end = mmap.cend();
1315 if (it == end)
1316 return DomItem();
1317 else {
1318 // special case single element (++it == end || it.key() != key)?
1319 QList<const T *> values;
1320 while (it != end && it.key() == key)
1321 values.append(&(*it++));
1322 ListP ll(self.pathFromOwner().withComponent(PathEls::Key(key)), values, QString(),
1324 return self.copy(ll);
1325 }
1326}
1327
1328template<typename T>
1329Map Map::fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap)
1330{
1331 return Map(
1332 pathFromOwner,
1333 [&mmap](const DomItem &self, const QString &key) {
1334 return keyMultiMapHelper(self, key, mmap);
1335 },
1336 [&mmap](const DomItem &) { return QSet<QString>(mmap.keyBegin(), mmap.keyEnd()); },
1337 QLatin1String(typeid(T).name()));
1338}
1339
1340template<typename T>
1341Map Map::fromMapRef(
1342 const Path &pathFromOwner, const QMap<QString, T> &map,
1343 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper)
1344{
1345 return Map(
1346 pathFromOwner,
1347 [&map, elWrapper](const DomItem &self, const QString &key) {
1348 const auto it = map.constFind(key);
1349 if (it == map.constEnd())
1350 return DomItem();
1351 return elWrapper(self, PathEls::Key(key), it.value());
1352 },
1353 [&map](const DomItem &) { return QSet<QString>(map.keyBegin(), map.keyEnd()); },
1354 QLatin1String(typeid(T).name()));
1355}
1356
1357template<typename MapT>
1358QSet<QString> Map::fileRegionKeysFromMap(const MapT &map)
1359{
1360 QSet<QString> keys;
1361 std::transform(map.keyBegin(), map.keyEnd(), std::inserter(keys, keys.begin()), fileLocationRegionName);
1362 return keys;
1363}
1364
1365template<typename T>
1366Map Map::fromFileRegionMap(const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map)
1367{
1368 auto result = Map(
1369 pathFromOwner,
1370 [&map](const DomItem &mapItem, const QString &key) -> DomItem {
1371 auto it = map.constFind(fileLocationRegionValue(key));
1372 if (it == map.constEnd())
1373 return {};
1374
1375 return mapItem.wrap(PathEls::Key(key), *it);
1376 },
1377 [&map](const DomItem &) { return fileRegionKeysFromMap(map); },
1378 QString::fromLatin1(typeid(T).name()));
1379 return result;
1380}
1381
1382template<typename T>
1383Map Map::fromFileRegionListMap(const Path &pathFromOwner,
1384 const QMap<FileLocationRegion, QList<T>> &map)
1385{
1386 using namespace Qt::StringLiterals;
1387 auto result = Map(
1388 pathFromOwner,
1389 [&map](const DomItem &mapItem, const QString &key) -> DomItem {
1390 const QList<SourceLocation> locations = map.value(fileLocationRegionValue(key));
1391 if (locations.empty())
1392 return {};
1393
1394 auto list = List::fromQList<SourceLocation>(
1395 mapItem.pathFromOwner(), locations,
1396 [](const DomItem &self, const PathEls::PathComponent &path,
1397 const SourceLocation &location) {
1398 return self.subLocationItem(path, location);
1399 });
1400 return mapItem.subListItem(list);
1401 },
1402 [&map](const DomItem &) { return fileRegionKeysFromMap(map); },
1403 u"QList<%1>"_s.arg(QString::fromLatin1(typeid(T).name())));
1404 return result;
1405}
1406
1407template<typename T>
1408List List::fromQList(
1409 const Path &pathFromOwner, const QList<T> &list,
1410 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
1411 ListOptions options)
1412{
1413 index_type len = list.size();
1414 if (options == ListOptions::Reverse) {
1415 return List(
1416 pathFromOwner,
1417 [list, elWrapper](const DomItem &self, index_type i) mutable {
1418 if (i < 0 || i >= list.size())
1419 return DomItem();
1420 return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
1421 },
1422 [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
1423 } else {
1424 return List(
1425 pathFromOwner,
1426 [list, elWrapper](const DomItem &self, index_type i) mutable {
1427 if (i < 0 || i >= list.size())
1428 return DomItem();
1429 return elWrapper(self, PathEls::Index(i), list[i]);
1430 },
1431 [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
1432 }
1433}
1434
1435template<typename T>
1436List List::fromQListRef(
1437 const Path &pathFromOwner, const QList<T> &list,
1438 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
1439 ListOptions options)
1440{
1441 if (options == ListOptions::Reverse) {
1442 return List(
1443 pathFromOwner,
1444 [&list, elWrapper](const DomItem &self, index_type i) {
1445 if (i < 0 || i >= list.size())
1446 return DomItem();
1447 return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
1448 },
1449 [&list](const DomItem &) { return list.size(); }, nullptr,
1450 QLatin1String(typeid(T).name()));
1451 } else {
1452 return List(
1453 pathFromOwner,
1454 [&list, elWrapper](const DomItem &self, index_type i) {
1455 if (i < 0 || i >= list.size())
1456 return DomItem();
1457 return elWrapper(self, PathEls::Index(i), list[i]);
1458 },
1459 [&list](const DomItem &) { return list.size(); }, nullptr,
1460 QLatin1String(typeid(T).name()));
1461 }
1462}
1463
1465protected:
1466 virtual std::shared_ptr<OwningItem> doCopy(const DomItem &self) const = 0;
1467
1468public:
1469 OwningItem(const OwningItem &o);
1470 OwningItem(int derivedFrom=0);
1471 OwningItem(int derivedFrom, const QDateTime &lastDataUpdateAt);
1472 OwningItem(const OwningItem &&) = delete;
1473 OwningItem &operator=(const OwningItem &&) = delete;
1474 static int nextRevision();
1475
1476 Path canonicalPath(const DomItem &self) const override = 0;
1477
1478 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
1479 std::shared_ptr<OwningItem> makeCopy(const DomItem &self) const { return doCopy(self); }
1480 Path pathFromOwner() const override final { return Path(); }
1481 DomItem containingObject(const DomItem &self) const override;
1482 int derivedFrom() const;
1483 virtual int revision() const;
1484
1485 QDateTime createdAt() const;
1486 virtual QDateTime lastDataUpdateAt() const;
1487 virtual void refreshedDataAt(QDateTime tNew);
1488
1489 // explicit freeze handling needed?
1490 virtual bool frozen() const;
1491 virtual bool freeze();
1492 QDateTime frozenAt() const;
1493
1494 virtual void addError(const DomItem &self, ErrorMessage &&msg);
1495 void addErrorLocal(ErrorMessage &&msg);
1496 void clearErrors(const ErrorGroups &groups = ErrorGroups({}));
1497 // return false if a quick exit was requested
1498 bool iterateErrors(
1499 const DomItem &self,
1500 function_ref<bool(const DomItem &source, const ErrorMessage &msg)> visitor,
1501 const Path &inPath = Path());
1503 QMutexLocker l(mutex());
1504 return m_errors;
1505 }
1506
1507 virtual bool iterateSubOwners(const DomItem &self, function_ref<bool(const DomItem &owner)> visitor);
1508
1509 QBasicMutex *mutex() const { return &m_mutex; }
1510private:
1511 mutable QBasicMutex m_mutex;
1512 int m_derivedFrom;
1513 int m_revision;
1514 QDateTime m_createdAt;
1515 QDateTime m_lastDataUpdateAt;
1516 QDateTime m_frozenAt;
1517 QMultiMap<Path, ErrorMessage> m_errors;
1518 QMap<ErrorMessage, quint32> m_errorsCounts;
1519};
1520
1521template<typename T>
1522std::shared_ptr<T> DomItem::ownerAs() const
1523{
1524 if constexpr (domTypeIsOwningItem(T::kindValue)) {
1525 if (!std::holds_alternative<std::monostate>(m_owner)) {
1526 if constexpr (T::kindValue == DomType::FileLocationsNode) {
1527 if (std::holds_alternative<std::shared_ptr<FileLocations::Node>>(m_owner))
1528 return std::static_pointer_cast<T>(
1529 std::get<std::shared_ptr<FileLocations::Node>>(m_owner));
1530 } else if constexpr (T::kindValue == DomType::ExternalItemInfo) {
1531 if (std::holds_alternative<std::shared_ptr<ExternalItemInfoBase>>(m_owner))
1532 return std::static_pointer_cast<T>(
1533 std::get<std::shared_ptr<ExternalItemInfoBase>>(m_owner));
1534 } else if constexpr (T::kindValue == DomType::ExternalItemPair) {
1535 if (std::holds_alternative<std::shared_ptr<ExternalItemPairBase>>(m_owner))
1536 return std::static_pointer_cast<T>(
1537 std::get<std::shared_ptr<ExternalItemPairBase>>(m_owner));
1538 } else {
1539 if (std::holds_alternative<std::shared_ptr<T>>(m_owner)) {
1540 return std::get<std::shared_ptr<T>>(m_owner);
1541 }
1542 }
1543 }
1544 } else {
1545 Q_ASSERT_X(false, "DomItem::ownerAs", "unexpected non owning value in ownerAs");
1546 }
1547 return std::shared_ptr<T> {};
1548}
1549
1550template<int I>
1551struct rank : rank<I - 1>
1552{
1553 static_assert(I > 0, "");
1554};
1555template<>
1556struct rank<0>
1557{
1558};
1559
1560template<typename T>
1561auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw, rank<1>)
1562 -> decltype(t.writeOut(self, lw))
1563{
1564 t.writeOut(self, lw);
1565}
1566
1567template<typename T>
1568auto writeOutWrap(const T &, const DomItem &, OutWriter &, rank<0>) -> void
1569{
1570 qCWarning(writeOutLog) << "Ignoring writeout to wrapped object not supporting it ("
1571 << typeid(T).name();
1572}
1573template<typename T>
1574auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw) -> void
1575{
1576 writeOutWrap(t, self, lw, rank<1>());
1577}
1578
1579template<typename T>
1580void SimpleObjectWrapT<T>::writeOut(const DomItem &self, OutWriter &lw) const
1581{
1582 writeOutWrap<T>(*asT(), self, lw);
1583}
1584
1585QMLDOM_EXPORT QDebug operator<<(QDebug debug, const DomItem &c);
1586
1587// TODO QTBUG-121518 quite some methods are used only in the "examples"
1588// Even though MutableDomItem provides some API for modifying internal data,
1589// de-facto it's not very helpful / convinient / intuitive to use
1590// Moreover it just amplifies and repeats issues of DomItem interface,
1591// a.k.a. abuse or misuse of type erasure technique
1593public:
1595
1596 explicit operator bool() const
1597 {
1598 return bool(m_owner);
1599 } // this is weaker than item(), but normally correct
1601 QString internalKindStr() { return domTypeToString(internalKind()); }
1602 DomKind domKind() { return kind2domKind(internalKind()); }
1603
1604 Path canonicalPath() const { return m_owner.canonicalPath().withPath(m_pathFromOwner); }
1606 {
1607 if (m_pathFromOwner)
1608 return MutableDomItem(m_owner, m_pathFromOwner.split().pathToSource);
1609 else {
1610 DomItem cObj = m_owner.containingObject();
1612 }
1613 }
1614
1616 {
1617 if (m_pathFromOwner)
1618 return MutableDomItem(m_owner, m_pathFromOwner.dropTail());
1619 else {
1621 }
1622 }
1623
1626 {
1627 return MutableDomItem(item().qmlObject(option, fOptions));
1628 }
1630 {
1631 return MutableDomItem(item().fileObject(option));
1632 }
1634 {
1635 return MutableDomItem(item().rootQmlObject(option));
1636 }
1639
1641 {
1642 return MutableDomItem { item().component(option) };
1643 }
1644 MutableDomItem owner() { return MutableDomItem(m_owner); }
1648 Path pathFromOwner() { return m_pathFromOwner; }
1650 MutableDomItem operator[](QStringView component) { return MutableDomItem(item()[component]); }
1651 MutableDomItem operator[](const QString &component)
1652 {
1653 return MutableDomItem(item()[component]);
1654 }
1655 MutableDomItem operator[](const char16_t *component)
1656 {
1657 // to avoid clash with stupid builtin ptrdiff_t[MutableDomItem&], coming from C
1658 return MutableDomItem(item()[QStringView(component)]);
1659 }
1660 MutableDomItem operator[](index_type i) { return MutableDomItem(item().index(i)); }
1661
1663 MutableDomItem path(const QString &p) { return path(Path::fromString(p)); }
1664 MutableDomItem path(QStringView p) { return path(Path::fromString(p)); }
1665
1666 QList<QString> const fields() { return item().fields(); }
1667 MutableDomItem field(QStringView name) { return MutableDomItem(item().field(name)); }
1668 index_type indexes() { return item().indexes(); }
1669 MutableDomItem index(index_type i) { return MutableDomItem(item().index(i)); }
1670
1671 QSet<QString> const keys() { return item().keys(); }
1672 MutableDomItem key(const QString &name) { return MutableDomItem(item().key(name)); }
1673 MutableDomItem key(QStringView name) { return key(name.toString()); }
1674
1675 void
1676 dump(const Sink &s, int indent = 0,
1677 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter)
1678 {
1679 item().dump(s, indent, filter);
1680 }
1682 dump(const QString &path,
1683 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter,
1684 int nBackups = 2, int indent = 0, FileWriter *fw = nullptr)
1685 {
1686 return item().dump(path, filter, nBackups, indent, fw);
1687 }
1688 void writeOut(OutWriter &lw) { return item().writeOut(lw); }
1689 bool writeOut(const QString &path, int nBackups = 2,
1690 const LineWriterOptions &opt = LineWriterOptions(), FileWriter *fw = nullptr)
1691 {
1692 return item().writeOut(path, nBackups, opt, fw);
1693 }
1694
1699 bool commitToBase(const std::shared_ptr<DomEnvironment> &validEnvPtr = nullptr)
1700 {
1701 return item().commitToBase(validEnvPtr);
1702 }
1703 QString canonicalFilePath() const { return item().canonicalFilePath(); }
1704
1706
1707 QCborValue value() { return item().value(); }
1708
1709 QString toString() { return item().toString(); }
1710
1711 // convenience getters
1712 QString name() { return item().name(); }
1715 QString idStr() { return item().idStr(); }
1720 MutableDomItem child(index_type i) { return MutableDomItem(item().child(i)); }
1722
1723 // // OwnigItem elements
1724 int derivedFrom() { return m_owner.derivedFrom(); }
1725 int revision() { return m_owner.revision(); }
1726 QDateTime createdAt() { return m_owner.createdAt(); }
1727 QDateTime frozenAt() { return m_owner.frozenAt(); }
1728 QDateTime lastDataUpdateAt() { return m_owner.lastDataUpdateAt(); }
1729
1730 void addError(ErrorMessage &&msg) { item().addError(std::move(msg)); }
1732
1733 // convenience setters
1738 const MethodInfo &functionDef, AddOption option = AddOption::Overwrite);
1740
1741 MutableDomItem() = default;
1742 MutableDomItem(const DomItem &owner, const Path &pathFromOwner):
1744 {}
1748
1749 std::shared_ptr<DomTop> topPtr() { return m_owner.topPtr(); }
1750 std::shared_ptr<OwningItem> owningItemPtr() { return m_owner.owningItemPtr(); }
1751
1752 template<typename T>
1753 T const *as()
1754 {
1755 return item().as<T>();
1756 }
1757
1758 template <typename T>
1760 Q_ASSERT(!m_owner || !m_owner.owningItemPtr()->frozen());
1761
1762 DomItem self = item();
1763 if (self.m_kind != T::kindValue)
1764 return nullptr;
1765
1766 const T *t = nullptr;
1767 if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
1768 t = static_cast<const SimpleObjectWrapBase *>(self.base())->as<T>();
1769 else if constexpr (std::is_base_of<DomBase, T>::value)
1770 t = static_cast<const T *>(self.base());
1771 else
1772 Q_UNREACHABLE_RETURN(nullptr);
1773
1774 // Nasty. But since ElementT has to store the const pointers, we allow it in this one place.
1775 return const_cast<T *>(t);
1776 }
1777
1778 template<typename T>
1779 std::shared_ptr<T> ownerAs() const
1780 {
1781 return m_owner.ownerAs<T>();
1782 }
1783 // it is dangerous to assume it stays valid when updates are preformed...
1784 DomItem item() const { return m_owner.path(m_pathFromOwner); }
1785
1786 friend bool operator==(const MutableDomItem &o1, const MutableDomItem &o2)
1787 {
1788 return o1.m_owner == o2.m_owner && o1.m_pathFromOwner == o2.m_pathFromOwner;
1789 }
1790 friend bool operator!=(const MutableDomItem &o1, const MutableDomItem &o2)
1791 {
1792 return !(o1 == o2);
1793 }
1794
1795private:
1796 DomItem m_owner;
1797 Path m_pathFromOwner;
1798};
1799
1800QMLDOM_EXPORT QDebug operator<<(QDebug debug, const MutableDomItem &c);
1801
1802template<typename K, typename T>
1803Path insertUpdatableElementInMultiMap(const Path &mapPathFromOwner, QMultiMap<K, T> &mmap, K key,
1804 const T &value, AddOption option = AddOption::KeepExisting,
1805 T **valuePtr = nullptr)
1806{
1807 if (option == AddOption::Overwrite) {
1808 auto it = mmap.find(key);
1809 if (it != mmap.end()) {
1810 T &v = *it;
1811 v = value;
1812 if (++it != mmap.end() && it.key() == key) {
1813 qWarning() << " requested overwrite of " << key
1814 << " that contains aleready multiple entries in" << mapPathFromOwner;
1815 }
1816 Path newPath = mapPathFromOwner.withKey(key).withIndex(0);
1817 v.updatePathFromOwner(newPath);
1818 if (valuePtr)
1819 *valuePtr = &v;
1820 return newPath;
1821 }
1822 }
1823 mmap.insert(key, value);
1824 auto it = mmap.find(key);
1825 auto it2 = it;
1826 int nVal = 0;
1827 while (it2 != mmap.end() && it2.key() == key) {
1828 ++nVal;
1829 ++it2;
1830 }
1831 Path newPath = mapPathFromOwner.withKey(key).withIndex(nVal-1);
1832 T &v = *it;
1833 v.updatePathFromOwner(newPath);
1834 if (valuePtr)
1835 *valuePtr = &v;
1836 return newPath;
1837}
1838
1839template<typename T>
1840Path appendUpdatableElementInQList(const Path &listPathFromOwner, QList<T> &list, const T &value,
1841 T **vPtr = nullptr)
1842{
1843 int idx = list.size();
1844 list.append(value);
1845 Path newPath = listPathFromOwner.withIndex(idx);
1846 T &targetV = list[idx];
1847 targetV.updatePathFromOwner(newPath);
1848 if (vPtr)
1849 *vPtr = &targetV;
1850 return newPath;
1851}
1852
1853template <typename T, typename K = QString>
1854void updatePathFromOwnerMultiMap(QMultiMap<K, T> &mmap, const Path &newPath)
1855{
1856 auto it = mmap.begin();
1857 auto end = mmap.end();
1858 index_type i = 0;
1859 K name;
1860 QList<T*> els;
1861 while (it != end) {
1862 if (i > 0 && name != it.key()) {
1863 Path pName = newPath.withKey(QString(name));
1864 for (T *el : els)
1865 el->updatePathFromOwner(pName.withIndex(--i));
1866 els.clear();
1867 els.append(&(*it));
1868 name = it.key();
1869 i = 1;
1870 } else {
1871 els.append(&(*it));
1872 name = it.key();
1873 ++i;
1874 }
1875 ++it;
1876 }
1877 Path pName = newPath.withKey(name);
1878 for (T *el : els)
1879 el->updatePathFromOwner(pName.withIndex(--i));
1880}
1881
1882template <typename T>
1883void updatePathFromOwnerQList(QList<T> &list, const Path &newPath)
1884{
1885 auto it = list.begin();
1886 auto end = list.end();
1887 index_type i = 0;
1888 while (it != end)
1889 (it++)->updatePathFromOwner(newPath.withIndex(i++));
1890}
1891
1892constexpr bool domTypeIsObjWrap(DomType k)
1893{
1894 switch (k) {
1895 case DomType::Binding:
1896 case DomType::EnumItem:
1898 case DomType::Export:
1899 case DomType::Id:
1900 case DomType::Import:
1905 case DomType::Pragma:
1907 case DomType::Version:
1908 case DomType::Comment:
1912 return true;
1913 default:
1914 return false;
1915 }
1916}
1917
1919{
1920 switch (k) {
1922 return true;
1923 default:
1924 return false;
1925 }
1926}
1927
1929{
1930 switch (k) {
1932 case DomType::QmlObject:
1935 case DomType::Reference:
1936 case DomType::Map:
1937 case DomType::List:
1938 case DomType::ListP:
1939 case DomType::EnumDecl:
1945 return true;
1946 default:
1947 return false;
1948 }
1949}
1950
1952{
1953 switch (k) {
1955
1956 case DomType::MockOwner:
1957
1960
1963 case DomType::JsFile:
1964 case DomType::QmlFile:
1967
1970
1971 case DomType::LoadInfo:
1973
1976 return true;
1977 default:
1978 return false;
1979 }
1980}
1981
1983{
1984 switch (k) {
1988 return true;
1989 default:
1990 return false;
1991 }
1992}
1993
1995{
1997}
1998
1999template<typename T>
2001 ConstantData::Options options) const
2002{
2003 using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
2004 if constexpr (
2005 std::is_base_of_v<
2006 QCborValue,
2007 BaseT> || std::is_base_of_v<QCborArray, BaseT> || std::is_base_of_v<QCborMap, BaseT>) {
2008 return DomItem(m_top, m_owner, m_ownerPath,
2009 ConstantData(pathFromOwner().withComponent(c), value, options));
2010 } else if constexpr (std::is_same_v<DomItem, BaseT>) {
2011 Q_UNUSED(options);
2012 return value;
2013 } else if constexpr (IsList<T>::value && !std::is_convertible_v<BaseT, QStringView>) {
2014 return subListItem(List::fromQList<typename BaseT::value_type>(
2015 pathFromOwner().withComponent(c), value,
2016 [options](const DomItem &list, const PathEls::PathComponent &p,
2017 const typename T::value_type &v) { return list.subValueItem(p, v, options); }));
2018 } else if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
2019 Q_UNUSED(options);
2020 return subOwnerItem(c, value);
2021 } else {
2022 return subDataItem(c, value, options);
2023 }
2024}
2025
2026template<typename T>
2028 ConstantData::Options options) const
2029{
2030 using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
2031 if constexpr (std::is_same_v<BaseT, ConstantData>) {
2032 return this->copy(value);
2033 } else if constexpr (std::is_base_of_v<QCborValue, BaseT>) {
2034 return DomItem(m_top, m_owner, m_ownerPath,
2035 ConstantData(pathFromOwner().withComponent(c), value, options));
2036 } else {
2037 return DomItem(
2038 m_top, m_owner, m_ownerPath,
2039 ConstantData(pathFromOwner().withComponent(c), QCborValue(value), options));
2040 }
2041}
2042
2043template<typename T>
2044bool DomItem::dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value,
2045 ConstantData::Options options) const
2046{
2047 auto lazyWrap = [this, &c, &value, options]() {
2048 return this->subValueItem<T>(c, value, options);
2049 };
2050 return visitor(c, lazyWrap);
2051}
2052
2053template<typename F>
2054bool DomItem::dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c, F valueF,
2055 ConstantData::Options options) const
2056{
2057 auto lazyWrap = [this, &c, &valueF, options]() {
2058 return this->subValueItem<decltype(valueF())>(c, valueF(), options);
2059 };
2060 return visitor(c, lazyWrap);
2061}
2062
2063template<typename T>
2064DomItem DomItem::wrap(const PathEls::PathComponent &c, const T &obj) const
2065{
2066 using BaseT = std::decay_t<T>;
2067 if constexpr (std::is_same_v<QString, BaseT> || std::is_arithmetic_v<BaseT>) {
2068 return this->subDataItem(c, QCborValue(obj));
2069 } else if constexpr (std::is_same_v<SourceLocation, BaseT>) {
2070 return this->subLocationItem(c, obj);
2071 } else if constexpr (std::is_same_v<BaseT, Reference>) {
2072 Q_ASSERT_X(false, "DomItem::wrap",
2073 "wrapping a reference object, probably an error (wrap the target path instead)");
2074 return this->copy(obj);
2075 } else if constexpr (std::is_same_v<BaseT, ConstantData>) {
2076 return this->subDataItem(c, obj);
2077 } else if constexpr (std::is_same_v<BaseT, Map>) {
2078 return this->subMapItem(obj);
2079 } else if constexpr (std::is_same_v<BaseT, List>) {
2080 return this->subListItem(obj);
2081 } else if constexpr (std::is_base_of_v<ListPBase, BaseT>) {
2082 return this->subListItem(obj);
2083 } else if constexpr (std::is_same_v<BaseT, SimpleObjectWrap>) {
2084 return this->subObjectWrapItem(obj);
2085 } else if constexpr (IsDomObject<BaseT>::value) {
2086 if constexpr (domTypeIsObjWrap(BaseT::kindValue) || domTypeIsValueWrap(BaseT::kindValue)) {
2087 return this->subObjectWrapItem(
2088 SimpleObjectWrap::fromObjectRef(this->pathFromOwner().withComponent(c), obj));
2089 } else if constexpr (domTypeIsDomElement(BaseT::kindValue)) {
2090 return this->copy(&obj);
2091 } else {
2092 qCWarning(domLog) << "Unhandled object of type " << domTypeToString(BaseT::kindValue)
2093 << " in DomItem::wrap, not using a shared_ptr for an "
2094 << "OwningItem, or unexpected wrapped object?";
2095 return DomItem();
2096 }
2097 } else if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
2098 if constexpr (domTypeIsOwningItem(BaseT::element_type::kindValue)) {
2099 return this->subOwnerItem(c, obj);
2100 } else {
2101 Q_ASSERT_X(false, "DomItem::wrap", "shared_ptr with non owning item");
2102 return DomItem();
2103 }
2104 } else if constexpr (IsMultiMap<BaseT>::value) {
2105 if constexpr (std::is_same_v<typename BaseT::key_type, QString>) {
2106 return subMapItem(Map::fromMultiMapRef<typename BaseT::mapped_type>(
2107 pathFromOwner().withComponent(c), obj));
2108 } else {
2109 Q_ASSERT_X(false, "DomItem::wrap", "non string keys not supported (try .toString()?)");
2110 }
2111 } else if constexpr (IsMap<BaseT>::value) {
2112 if constexpr (std::is_same_v<typename BaseT::key_type, QString>) {
2113 return subMapItem(Map::fromMapRef<typename BaseT::mapped_type>(
2114 pathFromOwner().withComponent(c), obj,
2115 [](const DomItem &map, const PathEls::PathComponent &p,
2116 const typename BaseT::mapped_type &el) { return map.wrap(p, el); }));
2117 } else {
2118 Q_ASSERT_X(false, "DomItem::wrap", "non string keys not supported (try .toString()?)");
2119 }
2120 } else if constexpr (IsList<BaseT>::value) {
2121 if constexpr (IsDomObject<typename BaseT::value_type>::value) {
2122 return subListItem(List::fromQListRef<typename BaseT::value_type>(
2123 pathFromOwner().withComponent(c), obj,
2124 [](const DomItem &list, const PathEls::PathComponent &p,
2125 const typename BaseT::value_type &el) { return list.wrap(p, el); }));
2126 } else {
2127 Q_ASSERT_X(false, "DomItem::wrap", "Unsupported list type T");
2128 return DomItem();
2129 }
2130 } else {
2131 qCWarning(domLog) << "Cannot wrap " << typeid(BaseT).name();
2132 Q_ASSERT_X(false, "DomItem::wrap", "Do not know how to wrap type T");
2133 return DomItem();
2134 }
2135}
2136
2137template<typename T>
2138bool DomItem::dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj) const
2139{
2140 auto lazyWrap = [this, &c, &obj]() { return this->wrap<T>(c, obj); };
2141 return visitor(c, lazyWrap);
2142}
2143
2144template<typename T>
2145bool ListPT<T>::iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const
2146{
2147 index_type len = index_type(m_pList.size());
2148 for (index_type i = 0; i < len; ++i) {
2149 if (!v(PathEls::Index(i), [this, &self, i] { return this->index(self, i); }))
2150 return false;
2151 }
2152 return true;
2153}
2154
2155template<typename T>
2156DomItem ListPT<T>::index(const DomItem &self, index_type index) const
2157{
2158 if (index >= 0 && index < m_pList.size())
2159 return self.wrap(PathEls::Index(index), *static_cast<const T *>(m_pList.value(index)));
2160 return DomItem();
2161}
2162
2163// allow inlining of DomBase
2164inline DomKind DomBase::domKind() const
2165{
2166 return kind2domKind(kind());
2167}
2168
2169inline DomItem DomBase::containingObject(const DomItem &self) const
2170{
2171 Path path = pathFromOwner();
2172 DomItem base = self.owner();
2173 if (!path) {
2174 path = canonicalPath(self);
2175 base = self;
2176 }
2177 Source source = path.split();
2178 return base.path(source.pathToSource);
2179}
2180
2181inline quintptr DomBase::id() const
2182{
2183 return quintptr(this);
2184}
2185
2186inline QString DomBase::typeName() const
2187{
2188 return domTypeToString(kind());
2189}
2190
2191inline QList<QString> DomBase::fields(const DomItem &self) const
2192{
2193 QList<QString> res;
2194 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2195 if (c.kind() == Path::Kind::Field)
2196 res.append(c.name());
2197 return true;
2198 });
2199 return res;
2200}
2201
2202inline DomItem DomBase::field(const DomItem &self, QStringView name) const
2203{
2204 DomItem res;
2205 self.iterateDirectSubpaths(
2206 [&res, name](const PathEls::PathComponent &c, function_ref<DomItem()> obj) {
2207 if (c.kind() == Path::Kind::Field && c.checkName(name)) {
2208 res = obj();
2209 return false;
2210 }
2211 return true;
2212 });
2213 return res;
2214}
2215
2216inline index_type DomBase::indexes(const DomItem &self) const
2217{
2218 index_type res = 0;
2219 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2220 if (c.kind() == Path::Kind::Index) {
2221 index_type i = c.index() + 1;
2222 if (res < i)
2223 res = i;
2224 }
2225 return true;
2226 });
2227 return res;
2228}
2229
2230inline DomItem DomBase::index(const DomItem &self, qint64 index) const
2231{
2232 DomItem res;
2233 self.iterateDirectSubpaths(
2234 [&res, index](const PathEls::PathComponent &c, function_ref<DomItem()> obj) {
2235 if (c.kind() == Path::Kind::Index && c.index() == index) {
2236 res = obj();
2237 return false;
2238 }
2239 return true;
2240 });
2241 return res;
2242}
2243
2244inline QSet<QString> const DomBase::keys(const DomItem &self) const
2245{
2246 QSet<QString> res;
2247 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2248 if (c.kind() == Path::Kind::Key)
2249 res.insert(c.name());
2250 return true;
2251 });
2252 return res;
2253}
2254
2255inline DomItem DomBase::key(const DomItem &self, const QString &name) const
2256{
2257 DomItem res;
2258 self.iterateDirectSubpaths(
2259 [&res, name](const PathEls::PathComponent &c, function_ref<DomItem()> obj) {
2260 if (c.kind() == Path::Kind::Key && c.checkName(name)) {
2261 res = obj();
2262 return false;
2263 }
2264 return true;
2265 });
2266 return res;
2267}
2268
2269inline DomItem DomItem::subListItem(const List &list) const
2270{
2271 return DomItem(m_top, m_owner, m_ownerPath, list);
2272}
2273
2274inline DomItem DomItem::subMapItem(const Map &map) const
2275{
2276 return DomItem(m_top, m_owner, m_ownerPath, map);
2277}
2278
2279// TODO
2280// refactor this workaround. ExternalOWningItem is not recognized as an owning type
2281// in ownerAs.
2282std::shared_ptr<ExternalOwningItem> getFileItemOwner(const DomItem &fileItem);
2283
2284} // end namespace Dom
2285} // end namespace QQmlJS
2286
2287QT_END_NAMESPACE
2288#endif // QMLDOMITEM_H
std::pair< AST::Node *, CommentAnchor > CommentKey
void setSemanticScope(const QQmlJSScope::ConstPtr &scope)
QQmlJSScope::ConstPtr m_semanticScope
void updatePathFromOwner(const Path &newPath)
QQmlJSScope::ConstPtr semanticScope() const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &annotation, QmlObject **aPtr=nullptr)
BindingValue(const QList< QmlObject > &l)
void updatePathFromOwner(const Path &newPath)
BindingValue(const std::shared_ptr< ScriptExpression > &o)
BindingValue(const BindingValue &o)
DomItem value(const DomItem &binding) const
BindingValue & operator=(const BindingValue &o)
std::shared_ptr< ScriptExpression > scriptExpression
BindingValue(const QmlObject &o)
void setValue(std::unique_ptr< BindingValue > &&value)
BindingType bindingType() const
std::shared_ptr< ScriptExpression > scriptExpressionValue() const
RegionComments & comments()
Binding & operator=(const Binding &)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
void setBindingIdentifiers(const ScriptElementVariant &bindingIdentifiers)
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &a, QmlObject **aPtr=nullptr)
QList< QmlObject > annotations() const
void updatePathFromOwner(const Path &newPath)
static QString preCodeForName(QStringView n)
QmlObject const * objectValue() const
DomItem valueItem(const DomItem &self) const
QList< QmlObject > * arrayValue()
Binding(const Binding &o)
QList< QmlObject > const * arrayValue() const
static QString postCodeForName(QStringView)
void setAnnotations(const QList< QmlObject > &annotations)
Binding & operator=(Binding &&)=default
void writeOut(const DomItem &self, OutWriter &lw) const
Binding(const QString &m_name, const QString &scriptCode, BindingType bindingType=BindingType::Normal)
const RegionComments & comments() const
Binding(const QString &m_name, std::unique_ptr< BindingValue > &&value, BindingType bindingType=BindingType::Normal)
void writeOutValue(const DomItem &self, OutWriter &lw) const
Binding(const QString &m_name=QString())
static constexpr DomType kindValue
Binding(const QString &m_name, const QmlObject &value, BindingType bindingType=BindingType::Normal)
Binding(Binding &&o)=default
std::shared_ptr< ScriptExpression > scriptExpressionValue()
ScriptElementVariant bindingIdentifiers() const
BindingValueKind valueKind() const
Binding(const QString &m_name, const std::shared_ptr< ScriptExpression > &value, BindingType bindingType=BindingType::Normal)
const RegionComments & comments() const
CommentableDomElement & operator=(const CommentableDomElement &o)=default
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
CommentableDomElement(const CommentableDomElement &o)
CommentableDomElement(const Path &pathFromOwner=Path())
void setIsSingleton(bool isSingleton)
void updatePathFromOwner(const Path &newPath) override
Component(const Path &pathFromOwner=Path())
void setIsComposite(bool isComposite)
Component & operator=(const Component &)=default
void setIsCreatable(bool isCreatable)
void setObjects(const QList< QmlObject > &objects)
const QMultiMap< QString, EnumDecl > & enumerations() const &
Component(const Component &o)=default
Path addObject(const QmlObject &object, QmlObject **oPtr=nullptr)
void setName(const QString &name)
Path attachedTypePath(const DomItem &) const
void setEnumerations(const QMultiMap< QString, EnumDecl > &enumerations)
DomItem field(const DomItem &self, QStringView name) const override
Path addEnumeration(const EnumDecl &enumeration, AddOption option=AddOption::Overwrite, EnumDecl **ePtr=nullptr)
void setAttachedTypeName(const QString &name)
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
QString attachedTypeName() const
Component(const QString &name)
void setAttachedTypePath(const Path &p)
const QList< QmlObject > & objects() const &
DomKind domKind() const override
ConstantData(const Path &pathFromOwner, const QCborValue &value, Options options=Options::MapIsMap)
QCborValue value() const override
quintptr id() const override
static constexpr DomType kindValue
DomType kind() const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
ConstantData & operator*()
const ConstantData & operator*() const
const ConstantData * operator->() const
ConstantData * operator->()
QString typeName() const
virtual DomType kind() const =0
virtual DomKind domKind() const
virtual Path canonicalPath(const DomItem &self) const =0
virtual Path pathFromOwner() const =0
virtual QList< QString > fields(const DomItem &self) const
virtual bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const =0
virtual index_type indexes(const DomItem &self) const
const DomBase * domBase() const
virtual DomItem containingObject(const DomItem &self) const
virtual void writeOut(const DomItem &self, OutWriter &lw) const
virtual QSet< QString > const keys(const DomItem &self) const
virtual DomItem field(const DomItem &self, QStringView name) const
virtual quintptr id() const
virtual QCborValue value() const
virtual QString canonicalFilePath(const DomItem &self) const
virtual ~DomBase()=default
virtual void dump(const DomItem &, const Sink &sink, int indent, FilterT filter) const
virtual DomItem key(const DomItem &self, const QString &name) const
virtual DomItem index(const DomItem &self, index_type index) const
DomElement & operator=(const DomElement &)=default
virtual void updatePathFromOwner(const Path &newPath)
Path canonicalPath(const DomItem &self) const override
Path pathFromOwner() const override
DomElement(const DomElement &o)=default
DomElement(const Path &pathFromOwner=Path())
DomItem containingObject(const DomItem &self) const override
A value type that references any element of the Dom.
DomItem bindings() const
DomItem top() const
bool dvReferences(DirectVisitor visitor, const PathEls::PathComponent &c, const QList< Path > &paths) const
DomItem goUp(int) const
QDateTime createdAt() const
T const * as() const
bool resolve(const Path &path, Visitor visitor, const ErrorHandler &errorHandler, ResolveOptions options=ResolveOption::None, const Path &fullPath=Path(), QList< Path > *visitedRefs=nullptr) const
std::shared_ptr< OwningItem > owningItemPtr() const
DomItem operator[](const QString &component) const
QString toString() const
void writeOutPost(OutWriter &lw) const
bool visitTree(const Path &basePath, ChildrenVisitor visitor, VisitOptions options=VisitOption::Default, ChildrenVisitor openingVisitor=emptyChildrenVisitor, ChildrenVisitor closingVisitor=emptyChildrenVisitor, const FieldFilter &filter=FieldFilter::noFilter()) const
Visits recursively all the children of this item using the given visitors.
DomItem path(const Path &p, const ErrorHandler &h=&defaultErrorHandler) const
DomItem containingFile() const
DomItem filterUp(function_ref< bool(DomType k, const DomItem &)> filter, FilterUpOptions options) const
DomItem methods() const
QString internalKindStr() const
DomItem scope(FilterUpOptions options=FilterUpOptions::ReturnOuter) const
DomItem enumerations() const
DomItem subOwnerItem(const PathEls::PathComponent &c, Owner o) const
bool visitLookup1(const QString &symbolName, function_ref< bool(const DomItem &)> visitor, LookupOptions=LookupOption::Normal, const ErrorHandler &h=nullptr, QSet< quintptr > *visited=nullptr, QList< Path > *visitedRefs=nullptr) const
DomItem child(index_type i) const
bool dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem key(QStringView name) const
std::shared_ptr< T > ownerAs() const
DomItem get(const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
static ErrorGroups myErrors()
DomItem operator[](const char16_t *component) const
bool visitUp(function_ref< bool(const DomItem &)> visitor) const
Let the visitor visit the Dom Tree hierarchy of this DomItem.
index_type indexes() const
bool hasAnnotations() const
bool iterateSubOwners(function_ref< bool(const DomItem &owner)> visitor) const
MutableDomItem makeCopy(CopyOption option=CopyOption::EnvConnected) const
DomItem refreshed() const
function< void(const Path &, const DomItem &, const DomItem &)> Callback
bool iterateErrors(function_ref< bool(const DomItem &, const ErrorMessage &)> visitor, bool iterate, Path inPath=Path()) const
DomItem pragmas() const
bool dvItem(DirectVisitor visitor, const PathEls::PathComponent &c, function_ref< DomItem()> it) const
DomItem proceedToScope(const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
Dereference DomItems pointing to other DomItems.
QList< DomItem > values() const
DomItem universe() const
bool iterateDirectSubpaths(DirectVisitor v) const
DomItem container() const
void clearErrors(const ErrorGroups &groups=ErrorGroups({}), bool iterate=true) const
quintptr id() const
QList< QString > fields() const
DomItem globalScope() const
static DomItem fromCode(const QString &code, DomType fileType=DomType::QmlFile)
Creates a new document with the given code.
QString idStr() const
DomItem(const std::shared_ptr< DomEnvironment > &)
bool dvReferenceField(DirectVisitor visitor, QStringView f, const Path &referencedObject) const
bool dvWrapField(DirectVisitor visitor, QStringView f, T &obj) const
DomItem subDataItemField(QStringView f, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem copy(const T &base) const
bool visitScopeChain(function_ref< bool(const DomItem &)> visitor, LookupOptions=LookupOption::Normal, const ErrorHandler &h=nullptr, QSet< quintptr > *visited=nullptr, QList< Path > *visitedRefs=nullptr) const
Let the visitor visit the QML scope hierarchy of this DomItem.
std::shared_ptr< DomTop > topPtr() const
QCborValue value() const
index_type size() const
bool dvReferencesField(DirectVisitor visitor, QStringView f, const QList< Path > &paths) const
QDateTime frozenAt() const
DomItem subListItem(const List &list) const
DomItem component(GoTo option=GoTo::Strict) const
bool visitLookup(const QString &symbolName, function_ref< bool(const DomItem &)> visitor, LookupType type=LookupType::Symbol, LookupOptions=LookupOption::Normal, const ErrorHandler &errorHandler=nullptr, QSet< quintptr > *visited=nullptr, QList< Path > *visitedRefs=nullptr) const
void writeOutPre(OutWriter &lw) const
DomItem lookupFirst(const QString &symbolName, LookupType type=LookupType::Symbol, LookupOptions=LookupOption::Normal, const ErrorHandler &errorHandler=nullptr) const
bool visitIndexes(function_ref< bool(const DomItem &)> visitor) const
DomItem fileObject(GoTo option=GoTo::Strict) const
bool dvReference(DirectVisitor visitor, const PathEls::PathComponent &c, const Path &referencedObject) const
bool visitKeys(function_ref< bool(const QString &, const DomItem &)> visitor) const
bool visitStaticTypePrototypeChains(function_ref< bool(const DomItem &)> visitor, VisitPrototypesOptions options=VisitPrototypesOption::Normal, const ErrorHandler &h=nullptr, QSet< quintptr > *visited=nullptr, QList< Path > *visitedRefs=nullptr) const
DomItem::visitStaticTypePrototypeChains.
QQmlJSScope::ConstPtr semanticScope() const
bool writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks) const
bool commitToBase(const std::shared_ptr< DomEnvironment > &validPtr=nullptr) const
DomItem ids() const
DomItem copy(const Owner &owner, const Path &ownerPath) const
bool dvItemField(DirectVisitor visitor, QStringView f, function_ref< DomItem()> it) const
FileWriter::Status dump(const QString &path, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter, int nBackups=2, int indent=0, FileWriter *fw=nullptr) const
bool visitSubSymbolsNamed(const QString &name, function_ref< bool(const DomItem &)> visitor) const
bool dvValueLazyField(DirectVisitor visitor, QStringView f, F valueF, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem wrap(const PathEls::PathComponent &c, const T &obj) const
bool dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj) const
QList< DomItem > lookup(const QString &symbolName, LookupType type=LookupType::Symbol, LookupOptions=LookupOption::Normal, const ErrorHandler &errorHandler=nullptr) const
void dump(const Sink &, int indent=0, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter) const
bool dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c, F valueF, ConstantData::Options options=ConstantData::Options::MapIsMap) const
friend QMLDOM_EXPORT bool operator==(const DomItem &, const DomItem &)
DomItem wrapField(QStringView f, const T &obj) const
QSet< QString > propertyInfoNames() const
static ErrorGroups myResolveErrors()
bool visitDirectAccessibleScopes(function_ref< bool(const DomItem &)> visitor, VisitPrototypesOptions options=VisitPrototypesOption::Normal, const ErrorHandler &h=nullptr, QSet< quintptr > *visited=nullptr, QList< Path > *visitedRefs=nullptr) const
DomItem environment() const
bool isCanonicalChild(const DomItem &child) const
index_type length() const
DomItem operator[](QStringView component) const
DomItem rootQmlObject(GoTo option=GoTo::Strict) const
DomItem subValueItem(const PathEls::PathComponent &c, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem directParent() const
DomItem annotations() const
Path canonicalPath() const
QStringList sortedKeys() const
void addError(ErrorMessage &&msg) const
DomItem containingObject() const
DomItem containingScriptExpression() const
QList< DomItem > getAll(const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
bool visitPrototypeChain(function_ref< bool(const DomItem &)> visitor, VisitPrototypesOptions options=VisitPrototypesOption::Normal, const ErrorHandler &h=nullptr, QSet< quintptr > *visited=nullptr, QList< Path > *visitedRefs=nullptr) const
DomKind domKind() const
bool isContainer() const
DomItem index(index_type) const
DomItem subReferencesItem(const PathEls::PathComponent &c, const QList< Path > &paths) const
bool dvValueField(DirectVisitor visitor, QStringView f, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem subMapItem(const Map &map) const
bool visitLocalSymbolsNamed(const QString &name, function_ref< bool(const DomItem &)> visitor) const
bool isExternalItem() const
DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const
void dumpPtr(const Sink &sink) const
auto visitEl(F f) const
InternalKind internalKind() const
DomItem path(const QString &p, const ErrorHandler &h=&defaultErrorHandler) const
bool isOwningItem() const
DomItem owner() const
The owner of an element, for an qmlObject this is the containing qml file.
ErrorHandler errorHandler() const
DomItem operator[](const Path &path) const
DomItem subObjectWrapItem(SimpleObjectWrap obj) const
static DomItem empty
DomItem subDataItem(const PathEls::PathComponent &c, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
QQmlJSScope::ConstPtr nearestSemanticScope() const
QString canonicalFilePath() const
void writeOut(OutWriter &lw) const
bool writeOut(const QString &path, int nBackups=2, const LineWriterOptions &opt=LineWriterOptions(), FileWriter *fw=nullptr, WriteOutChecks extraChecks=WriteOutCheck::Default) const
Path pathFromOwner() const
DomItem qmlObject(GoTo option=GoTo::Strict, FilterUpOptions options=FilterUpOptions::ReturnOuter) const
Returns the QmlObject that this belongs to.
DomItem subScriptElementWrapperItem(const ScriptElementVariant &obj) const
DomItem path(QStringView p, const ErrorHandler &h=&defaultErrorHandler) const
DomItem copy(const Owner &owner, const Path &ownerPath, const T &base) const
DomItem key(const QString &name) const
PropertyInfo propertyInfoWithName(const QString &name) const
QSet< QString > keys() const
QString name() const
DomItem children() const
DomItem field(QStringView name) const
DomItem propertyDefs() const
DomItem subLocationItem(const PathEls::PathComponent &c, SourceLocation loc) const
DomItem goToFile(const QString &filePath) const
QDateTime lastDataUpdateAt() const
DomItem(const std::shared_ptr< DomUniverse > &)
static ErrorGroup domErrorGroup
DomItem propertyInfos() const
void dump(const DomItem &, const Sink &s, int indent, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter) const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
static constexpr DomType kindValue
Path pathFromOwner() const override
Path canonicalPath(const DomItem &self) const override
const Empty & operator*() const
const Empty * operator->() const
DomType kind() const override
DomItem containingObject(const DomItem &self) const override
quintptr id() const override
const QList< QmlObject > & annotations() const &
const QList< EnumItem > & values() const &
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
void setAlias(const QString &aliasName)
void setAnnotations(const QList< QmlObject > &annotations)
EnumDecl(const QString &name=QString(), const QList< EnumItem > &values=QList< EnumItem >(), const Path &pathFromOwner=Path())
void writeOut(const DomItem &self, OutWriter &lw) const override
void updatePathFromOwner(const Path &newP) override
void setName(const QString &name)
Path addAnnotation(const QmlObject &child, QmlObject **cPtr=nullptr)
Path addValue(const EnumItem &value)
static constexpr DomType kindValue
void setValues(const QList< EnumItem > &values)
DomType kind() const override
EnumItem(const QString &name=QString(), int value=0, ValueKind valueKind=ValueKind::ImplicitValue)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
const RegionComments & comments() const
RegionComments & comments()
void writeOut(const DomItem &self, OutWriter &lw) const
static constexpr DomType kindValue
convenience macro creating a new ErrorGroup and registering its groupId as translatable string
Represents a set of tags grouping a set of related error messages.
Represents an error message connected to the dom.
static Export fromString(const Path &source, QStringView exp, const Path &typePath, const ErrorHandler &h)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
static FieldFilter noFilter()
Represents a Node of FileLocations tree.
QString logicalPath() const
QString canonicalPath() const
void setCanonicalPath(const QString &canonicalPath)
void setLogicalPath(const QString &logicalPath)
std::optional< InMemoryContents > content() const
static FileToLoad fromFileSystem(const std::weak_ptr< DomEnvironment > &environment, const QString &canonicalPath)
static FileToLoad fromMemory(const std::weak_ptr< DomEnvironment > &environment, const QString &path, const QString &data)
FileToLoad(const std::weak_ptr< DomEnvironment > &environment, const QString &canonicalPath, const QString &logicalPath, const std::optional< InMemoryContents > &content)
std::weak_ptr< DomEnvironment > environment() const
GlobalComponent(const Path &pathFromOwner=Path())
DomType kind() const override
static constexpr DomType kindValue
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &ann, QmlObject **aPtr=nullptr)
RegionComments comments
std::shared_ptr< ScriptExpression > value
static constexpr DomType kindValue
Id(const QString &idName=QString(), const Path &referredObject=Path())
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
void updatePathFromOwner(const Path &pathFromOwner)
QList< QmlObject > annotations
const QList< Path > & importSourcePaths() const &
const QMap< QString, ImportScope > & subImports() const &
QList< DomItem > importedItemsWithName(const DomItem &self, const QString &name) const
QList< Export > importedExportsWithName(const DomItem &self, const QString &name) const
QSet< QString > importedNames(const DomItem &self) const
void addImport(const QStringList &p, const Path &targetExports)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
QList< Path > allSources(const DomItem &self) const
Import(const QmlUri &uri=QmlUri(), Version version=Version(), const QString &importId=QString())
Import baseImport() const
friend bool operator==(const Import &i1, const Import &i2)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
static QRegularExpression importRe()
void writeOut(const DomItem &self, OutWriter &ow) const
static Import fromFileString(const QString &importStr, const QString &importId=QString(), const ErrorHandler &handler=nullptr)
friend bool operator!=(const Import &i1, const Import &i2)
static Import fromUriString(const QString &importStr, Version v=Version(), const QString &importId=QString(), const ErrorHandler &handler=nullptr)
JsResource(const Path &pathFromOwner=Path())
DomType kind() const override
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
static constexpr DomType kindValue
quintptr id() const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override
void writeOut(const DomItem &self, OutWriter &ow, bool compact) const
static constexpr DomType kindValue
index_type indexes(const DomItem &) const override
virtual void copyTo(ListPBase *) const
virtual void moveTo(ListPBase *) const
void writeOut(const DomItem &self, OutWriter &ow) const override
DomType kind() const override
QList< const void * > m_pList
ListPBase(const Path &pathFromOwner, const QList< const void * > &pList, const QString &elType)
void moveTo(ListPBase *t) const override
ListPT(const Path &pathFromOwner, const QList< T * > &pList, const QString &elType=QString(), ListOptions options=ListOptions::Normal)
DomItem index(const DomItem &self, index_type index) const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override
void copyTo(ListPBase *t) const override
static constexpr DomType kindValue
static constexpr DomType kindValue
ListPBase & operator*()
ListPBase * operator->()
const ListPBase * operator->() const
ListP(const Path &pathFromOwner, const QList< T * > &pList, const QString &elType=QString(), ListOptions options=ListOptions::Normal)
const ListPBase & operator*() const
void writeOut(const DomItem &self, OutWriter &ow, bool compact) const
List(const Path &pathFromOwner, const LookupFunction &lookup, const Length &length, const IteratorFunction &iterator, const QString &elType)
DomType kind() const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
const List & operator*() const
static List fromQList(const Path &pathFromOwner, const QList< T > &list, const std::function< DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper, ListOptions options=ListOptions::Normal)
std::function< bool(const DomItem &, function_ref< bool(index_type, function_ref< DomItem()>)>)> IteratorFunction
static List fromQListRef(const Path &pathFromOwner, const QList< T > &list, const std::function< DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper, ListOptions options=ListOptions::Normal)
void dump(const DomItem &, const Sink &s, int indent, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>) const override
std::function< DomItem(const DomItem &, index_type)> LookupFunction
void writeOut(const DomItem &self, OutWriter &ow) const override
quintptr id() const override
static constexpr DomType kindValue
const List * operator->() const
index_type indexes(const DomItem &self) const override
DomItem index(const DomItem &self, index_type index) const override
std::function< index_type(const DomItem &)> Length
std::function< DomItem(const DomItem &, QString)> LookupFunction
static Map fromMultiMapRef(const Path &pathFromOwner, const QMultiMap< QString, T > &mmap)
const Map * operator->() const
static Map fromFileRegionMap(const Path &pathFromOwner, const QMap< FileLocationRegion, T > &map)
static Map fromFileRegionListMap(const Path &pathFromOwner, const QMap< FileLocationRegion, QList< T > > &map)
Map(const Path &pathFromOwner, const LookupFunction &lookup, const Keys &keys, const QString &targetType)
const Map & operator*() const
static Map fromMapRef(const Path &pathFromOwner, const QMap< QString, T > &mmap, const std::function< DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper)
static Map fromMultiMap(const Path &pathFromOwner, const QMultiMap< QString, T > &mmap)
std::function< QSet< QString >(const DomItem &)> Keys
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
QSet< QString > const keys(const DomItem &self) const override
quintptr id() const override
DomItem key(const DomItem &self, const QString &name) const override
static constexpr DomType kindValue
DomType kind() const override
std::shared_ptr< ScriptExpression > body
Path typePath(const DomItem &) const
QList< MethodParameter > parameters
std::shared_ptr< ScriptExpression > returnType
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOut(const DomItem &self, OutWriter &ow) const
void writePre(const DomItem &self, OutWriter &ow) const
QString signature(const DomItem &self) const
std::shared_ptr< ScriptExpression > defaultValue
void writeOut(const DomItem &self, OutWriter &ow) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOutSignal(const DomItem &self, OutWriter &ow) const
TypeAnnotationStyle typeAnnotationStyle
static constexpr DomType kindValue
std::shared_ptr< ScriptExpression > value
QMap< QString, QMap< QString, MockObject > > subMaps
friend bool operator==(const ModuleAutoExport &i1, const ModuleAutoExport &i2)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
friend bool operator!=(const ModuleAutoExport &i1, const ModuleAutoExport &i2)
static constexpr DomType kindValue
std::shared_ptr< T > ownerAs() const
MutableDomItem addChild(QmlObject child)
FileWriter::Status dump(const QString &path, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter, int nBackups=2, int indent=0, FileWriter *fw=nullptr)
bool writeOut(const QString &path, int nBackups=2, const LineWriterOptions &opt=LineWriterOptions(), FileWriter *fw=nullptr)
friend bool operator==(const MutableDomItem &o1, const MutableDomItem &o2)
MutableDomItem addPropertyDef(const PropertyDefinition &propertyDef, AddOption option=AddOption::Overwrite)
bool commitToBase(const std::shared_ptr< DomEnvironment > &validEnvPtr=nullptr)
QString canonicalFilePath() const
MutableDomItem fileObject(GoTo option=GoTo::Strict)
MutableDomItem operator[](const char16_t *component)
MutableDomItem key(QStringView name)
MutableDomItem operator[](const QString &component)
MutableDomItem addMethod(const MethodInfo &functionDef, AddOption option=AddOption::Overwrite)
MutableDomItem field(QStringView name)
void dump(const Sink &s, int indent=0, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter)
void writeOut(OutWriter &lw)
MutableDomItem(const DomItem &owner, const Path &pathFromOwner)
MutableDomItem containingObject()
void addError(ErrorMessage &&msg)
MutableDomItem path(const QString &p)
std::shared_ptr< DomTop > topPtr()
MutableDomItem key(const QString &name)
QSet< QString > const keys()
MutableDomItem qmlObject(GoTo option=GoTo::Strict, FilterUpOptions fOptions=FilterUpOptions::ReturnOuter)
QList< QString > const fields()
MutableDomItem component(GoTo option=GoTo::Strict)
MutableDomItem path(const Path &p)
MutableDomItem makeCopy(CopyOption option=CopyOption::EnvConnected)
MutableDomItem operator[](const Path &path)
MutableDomItem index(index_type i)
MutableDomItem child(index_type i)
MutableDomItem(const DomItem &item)
std::shared_ptr< OwningItem > owningItemPtr()
friend bool operator!=(const MutableDomItem &o1, const MutableDomItem &o2)
MutableDomItem rootQmlObject(GoTo option=GoTo::Strict)
DomItem::CopyOption CopyOption
MutableDomItem operator[](QStringView component)
MutableDomItem path(QStringView p)
MutableDomItem addBinding(Binding binding, AddOption option=AddOption::Overwrite)
A DomItem that owns other DomItems and is managed through a shared pointer.
QDateTime createdAt() const
virtual bool iterateSubOwners(const DomItem &self, function_ref< bool(const DomItem &owner)> visitor)
virtual int revision() const
QBasicMutex * mutex() const
DomItem containingObject(const DomItem &self) const override
virtual std::shared_ptr< OwningItem > doCopy(const DomItem &self) const =0
std::shared_ptr< OwningItem > makeCopy(const DomItem &self) const
Path pathFromOwner() const override final
OwningItem(const OwningItem &&)=delete
bool iterateErrors(const DomItem &self, function_ref< bool(const DomItem &source, const ErrorMessage &msg)> visitor, const Path &inPath=Path())
virtual void addError(const DomItem &self, ErrorMessage &&msg)
QDateTime frozenAt() const
void addErrorLocal(ErrorMessage &&msg)
virtual QDateTime lastDataUpdateAt() const
void clearErrors(const ErrorGroups &groups=ErrorGroups({}))
Path canonicalPath(const DomItem &self) const override=0
QMultiMap< Path, ErrorMessage > localErrors() const
OwningItem & operator=(const OwningItem &&)=delete
OwningItem(int derivedFrom, const QDateTime &lastDataUpdateAt)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
virtual bool frozen() const
virtual void refreshedDataAt(QDateTime tNew)
OwningItem(int derivedFrom=0)
OwningItem(const OwningItem &o)
Source split() const
Splits the path at the last field, root or current Component.
PathEls::Kind Kind
static Path fromRoot(PathRoot r)
Path withComponent(const PathEls::PathComponent &c)
Path operator[](int i) const
Path mid(int offset, int length) const
Path last() const
Kind headKind() const
static Path fromCurrent(PathCurrent c)
Pragma(const QString &pragmaName=QString(), const QStringList &pragmaValues={})
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOut(const DomItem &self, OutWriter &ow) const
static constexpr DomType kindValue
static constexpr DomType kindValue
ScriptElementVariant m_nameIdentifiers
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOut(const DomItem &self, OutWriter &lw) const
ScriptElementVariant nameIdentifiers() const
void setNameIdentifiers(const ScriptElementVariant &name)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
static constexpr DomType kindValue
QQmlDomAstCreatorBase(const MutableDomItem &qmlFile)
void endVisit(AST::UiProgram *) override
void throwRecursionDepthError() override
void endVisitHelper(AST::PatternElement *pe, const std::shared_ptr< ScriptElements::GenericScriptElement > &element)
void loadAnnotations(AST::UiObjectMember *el)
bool visit(AST::UiProgram *program) override
void enableLoadFileLazily(bool enable=true)
void enableScriptExpressions(bool enable=true)
virtual QQmlJSASTClassListToVisit void throwRecursionDepthError() override
QQmlDomAstCreatorWithQQmlJSScope(const QQmlJSScope::Ptr &current, MutableDomItem &qmlFile, QQmlJSLogger *logger, QQmlJSImporter *importer)
QQmlJSScope::ConstPtr semanticScope() const
void setIds(const QMultiMap< QString, Id > &ids)
void setNextComponentPath(const Path &p)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
QList< DomItem > subComponents(const DomItem &self) const
const QMultiMap< QString, Id > & ids() const &
void updatePathFromOwner(const Path &newPath) override
void setNameIdentifiers(const ScriptElementVariant &name)
static constexpr DomType kindValue
void writeOut(const DomItem &self, OutWriter &) const override
void setSemanticScope(const QQmlJSScope::ConstPtr &scope)
QmlComponent(const QString &name=QString())
QList< QString > subComponentsNames(const DomItem &self) const
Path addId(const Id &id, AddOption option=AddOption::Overwrite, Id **idPtr=nullptr)
ScriptElementVariant nameIdentifiers() const
DomType kind() const override
QList< QString > fields(const DomItem &) const override
void setNameIdentifiers(const ScriptElementVariant &name)
Path addChild(const QmlObject &child, QmlObject **cPtr=nullptr)
MutableDomItem addBinding(MutableDomItem &self, const Binding &binding, AddOption option)
void setMethods(const QMultiMap< QString, MethodInfo > &functionDefs)
void writeOut(const DomItem &self, OutWriter &ow, const QString &onTarget) const
ScriptElementVariant nameIdentifiers() const
void setName(const QString &name)
QList< std::pair< SourceLocation, DomItem > > orderOfAttributes(const DomItem &self, const DomItem &component) const
bool iterateSubOwners(const DomItem &self, function_ref< bool(const DomItem &owner)> visitor) const
MutableDomItem addChild(MutableDomItem &self, const QmlObject &child)
void setAnnotations(const QList< QmlObject > &annotations)
const QMultiMap< QString, Binding > & bindings() const &
DomType kind() const override
void setNextScopePath(const Path &nextScopePath)
void updatePathFromOwner(const Path &newPath) override
void setChildren(const QList< QmlObject > &children)
Path addBinding(const Binding &binding, AddOption option, Binding **bPtr=nullptr)
static constexpr DomType kindValue
Path addAnnotation(const QmlObject &annotation, QmlObject **aPtr=nullptr)
void writeOutSortedEnumerations(const DomItem &component, OutWriter &ow) const
LocallyResolvedAlias resolveAlias(const DomItem &self, std::shared_ptr< ScriptExpression > accessSequence) const
void writeOutId(const DomItem &self, OutWriter &ow) const
QList< QmlObject > children() const
LocallyResolvedAlias resolveAlias(const DomItem &self, const QStringList &accessSequence) const
const QList< Path > & prototypePaths() const &
void writeOutSortedPropertyDefinition(const DomItem &self, OutWriter &ow, QSet< QString > &mergedDefBinding) const
Path addPropertyDef(const PropertyDefinition &propertyDef, AddOption option, PropertyDefinition **pDef=nullptr)
const QMultiMap< QString, MethodInfo > & methods() const &
MutableDomItem addPropertyDef(MutableDomItem &self, const PropertyDefinition &propertyDef, AddOption option)
DomItem field(const DomItem &self, QStringView name) const override
void setBindings(const QMultiMap< QString, Binding > &bindings)
QString localDefaultPropertyName() const
QString defaultPropertyName(const DomItem &self) const
void setPropertyDefs(const QMultiMap< QString, PropertyDefinition > &propertyDefs)
QmlObject(const Path &pathFromOwner=Path())
void writeOutSortedAttributes(const DomItem &self, OutWriter &ow, const DomItem &component) const
MutableDomItem addMethod(MutableDomItem &self, const MethodInfo &functionDef, AddOption option)
void writeOutAttributes(const DomItem &self, OutWriter &ow, const DomItem &component, const QString &code) const
void setIdStr(const QString &id)
QQmlJSScope::ConstPtr semanticScope() const
const QMultiMap< QString, PropertyDefinition > & propertyDefs() const &
void writeOut(const DomItem &self, OutWriter &lw) const override
Path addPrototypePath(const Path &prototypePath)
void setSemanticScope(const QQmlJSScope::ConstPtr &scope)
void setDefaultPropertyName(const QString &name)
void setPrototypePaths(const QList< Path > &prototypePaths)
QList< QmlObject > annotations() const
QList< QString > fields() const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
Path addMethod(const MethodInfo &functionDef, AddOption option, MethodInfo **mPtr=nullptr)
bool iterateBaseDirectSubpaths(const DomItem &self, DirectVisitor) const
static QmlUri fromString(const QString &importStr)
QString absoluteLocalPath(const QString &basePath=QString()) const
QString directoryString() const
static QmlUri fromUriString(const QString &importStr)
QString localPath() const
QString moduleUri() const
friend bool operator==(const QmlUri &i1, const QmlUri &i2)
static QmlUri fromDirectoryString(const QString &importStr)
friend bool operator!=(const QmlUri &i1, const QmlUri &i2)
void setInterfaceNames(const QStringList &interfaces)
void setMetaRevisions(const QList< int > &metaRevisions)
QQmlJSScope::AccessSemantics accessSemantics() const
void setFileName(const QString &fileName)
static constexpr DomType kindValue
QQmlJSScope::ConstPtr semanticScope() const
void setAccessSemantics(QQmlJSScope::AccessSemantics v)
void setSemanticScope(const QQmlJSScope::ConstPtr &scope)
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
void setExtensionTypeName(const QString &name)
void setElementTypeName(const QString &name)
const QList< int > & metaRevisions() const &
const QList< Export > & exports() const &
void setExports(const QList< Export > &exports)
void addExport(const Export &exportedEntry)
const QStringList & interfaceNames() const &
QmltypesComponent(const Path &pathFromOwner=Path())
DomType kind() const override
QList< QString > fields(const DomItem &self) const override
quintptr id() const override
static constexpr DomType kindValue
const Reference & operator*() const
DomItem index(const DomItem &, index_type) const override
DomItem field(const DomItem &self, QStringView name) const override
DomItem get(const DomItem &self, const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
QList< DomItem > getAll(const DomItem &self, const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
index_type indexes(const DomItem &) const override
DomType kind() const override
QSet< QString > const keys(const DomItem &) const override
const Reference * operator->() const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
Reference(const Path &referredObject=Path(), const Path &pathFromOwner=Path(), const SourceLocation &loc=SourceLocation())
DomItem key(const DomItem &, const QString &) const override
Keeps the comments associated with a DomItem.
const DomBase & operator*() const
const DomBase * operator->() const
static constexpr DomType kindValue
ScriptElementVariant element() const
ScriptElementDomWrapper(const ScriptElementVariant &element)
Use this to contain any script element.
void visitConst(F &&visitor) const
std::optional< ScriptElementT > data()
ScriptElement::PointerType< ScriptElement > base() const
Returns a pointer to the virtual base for virtual method calls.
static ScriptElementVariant fromElement(const T &element)
void setData(const ScriptElementT &data)
void replaceKindForGenericChildren(DomType oldType, DomType newType)
QStringView loc2Str(const SourceLocation &) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
DomType kind() const override
std::shared_ptr< AstComments > astComments() const
std::shared_ptr< QQmlJS::Engine > engine() const
ScriptExpression(const QString &code, ExpressionType expressionType)
static constexpr DomType kindValue
SourceLocation locationToLocal(const SourceLocation &x) const
std::shared_ptr< ScriptExpression > makeCopy(const DomItem &self) const
ScriptExpression(const ScriptExpression &e)
ExpressionType expressionType() const
void writeOut(const DomItem &self, OutWriter &lw) const override
SourceLocation globalLocation(const DomItem &self) const
ScriptExpression(QStringView code, const std::shared_ptr< QQmlJS::Engine > &engine, AST::Node *ast, const std::shared_ptr< AstComments > &comments, ExpressionType expressionType, const SourceLocation &localOffset=SourceLocation())
void setScriptElement(const ScriptElementVariant &p)
std::shared_ptr< OwningItem > doCopy(const DomItem &) const override
ScriptElementVariant scriptElement()
void astDumper(const Sink &s, AstDumperOptions options) const
SourceLocation localOffset() const
Path canonicalPath(const DomItem &self) const override
static constexpr DomType kindValue
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
SimpleObjectWrapBase(const Path &pathFromOwner, const QVariant &value, quintptr idValue, DomType kind=kindValue, SimpleWrapOptions options=SimpleWrapOption::None)
virtual void moveTo(SimpleObjectWrapBase *) const
DomKind domKind() const final override
virtual void copyTo(SimpleObjectWrapBase *) const
DomType kind() const final override
quintptr id() const final override
SimpleObjectWrapT(const Path &pathFromOwner, const QVariant &v, quintptr idValue, SimpleWrapOptions o)
void moveTo(SimpleObjectWrapBase *target) const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
static constexpr DomType kindValue
void writeOut(const DomItem &self, OutWriter &lw) const override
void copyTo(SimpleObjectWrapBase *target) const override
const SimpleObjectWrapBase & operator*() const
SimpleObjectWrapBase & operator*()
static SimpleObjectWrap fromObjectRef(const Path &pathFromOwner, T &value)
const SimpleObjectWrapBase * operator->() const
static constexpr DomType kindValue
SimpleObjectWrapBase * operator->()
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
QString majorString() const
static constexpr DomType kindValue
Version(qint32 majorVersion=Undefined, qint32 minorVersion=Undefined)
QString minorString() const
int compare(Version o) const
static Version fromString(QStringView v)
QString stringValue() const
static constexpr qint32 Undefined
static constexpr qint32 Latest
QString majorSymbolicString() const
Provides entities to maintain mappings between elements and their location in a file.
Tree ensure(const Tree &base, const Path &basePath)
Path lookupTypePath(const QString &name)
Path loadInfoPath(const Path &el)
Path moduleScopePath(const QString &uri, const ErrorHandler &errorHandler=nullptr)
Path qmltypesFilePath(const QString &path)
Path jsFilePath(const QString &path)
Path lookupCppTypePath(const QString &name)
Path qmlFileInfoPath(const QString &canonicalFilePath)
Path moduleIndexPath(const QString &uri, int majorVersion, const ErrorHandler &errorHandler=nullptr)
Path qmlFilePath(const QString &canonicalFilePath)
Path globalScopePath(const QString &name)
Path moduleScopePath(const QString &uri, const QString &version, const ErrorHandler &errorHandler=nullptr)
Path lookupSymbolPath(const QString &name)
Path jsFileInfoPath(const QString &path)
Path lookupPropertyPath(const QString &name)
Path moduleScopePath(const QString &uri, Version version, const ErrorHandler &errorHandler=nullptr)
Path qmlDirPath(const QString &path)
Path qmlDirectoryPath(const QString &path)
Path qmldirFilePath(const QString &path)
Path qmlDirectoryInfoPath(const QString &path)
Path qmltypesFileInfoPath(const QString &path)
Path qmldirFileInfoPath(const QString &path)
Path qmlDirInfoPath(const QString &path)
Path qmlFileObjectPath(const QString &canonicalFilePath)
Path globalScopeInfoPath(const QString &name)
bool operator>(Version v1, Version v2)
QMLDOM_EXPORT bool domTypeIsContainer(DomType k)
bool operator==(Version v1, Version v2)
constexpr bool domTypeIsOwningItem(DomType)
Path appendUpdatableElementInQList(const Path &listPathFromOwner, QList< T > &list, const T &value, T **vPtr=nullptr)
constexpr bool domTypeIsValueWrap(DomType k)
std::variant< ConstantData, Empty, List, ListP, Map, Reference, ScriptElementDomWrapper, SimpleObjectWrap, const AstComments *, const FileLocations::Node *, const DomEnvironment *, const DomUniverse *, const EnumDecl *, const ExternalItemInfoBase *, const ExternalItemPairBase *, const GlobalComponent *, const GlobalScope *, const JsFile *, const JsResource *, const LoadInfo *, const MockObject *, const MockOwner *, const ModuleIndex *, const ModuleScope *, const QmlComponent *, const QmlDirectory *, const QmlFile *, const QmlObject *, const QmldirFile *, const QmltypesComponent *, const QmltypesFile *, const ScriptExpression * > ElementT
Path insertUpdatableElementInMultiMap(const Path &mapPathFromOwner, QMultiMap< K, T > &mmap, K key, const T &value, AddOption option=AddOption::KeepExisting, T **valuePtr=nullptr)
std::variant< std::monostate, std::shared_ptr< DomEnvironment >, std::shared_ptr< DomUniverse > > TopT
bool noFilter(const DomItem &, const PathEls::PathComponent &, const DomItem &)
QMLDOM_EXPORT QMap< DomKind, QString > domKindToStringMap()
QMLDOM_EXPORT QDebug operator<<(QDebug debug, const DomItem &c)
std::shared_ptr< ExternalOwningItem > getFileItemOwner(const DomItem &fileItem)
DomKind kind2domKind(DomType k)
static DomItem keyMultiMapHelper(const DomItem &self, const QString &key, const QMultiMap< QString, T > &mmap)
bool operator!=(const DomItem &o1, const DomItem &o2)
QMLDOM_EXPORT bool domTypeIsExternalItem(DomType k)
constexpr bool domTypeIsUnattachedOwningItem(DomType)
QMLDOM_EXPORT QMap< DomType, QString > domTypeToStringMap()
QMLDOM_EXPORT bool domTypeIsScope(DomType k)
QMLDOM_EXPORT QDebug operator<<(QDebug debug, const MutableDomItem &c)
std::disjunction< std::is_same< U, V >... > IsInList
QMLDOM_EXPORT QString domTypeToString(DomType k)
std::variant< std::monostate, std::shared_ptr< ModuleIndex >, std::shared_ptr< MockOwner >, std::shared_ptr< ExternalItemInfoBase >, std::shared_ptr< ExternalItemPairBase >, std::shared_ptr< QmlDirectory >, std::shared_ptr< QmldirFile >, std::shared_ptr< JsFile >, std::shared_ptr< QmlFile >, std::shared_ptr< QmltypesFile >, std::shared_ptr< GlobalScope >, std::shared_ptr< ScriptExpression >, std::shared_ptr< AstComments >, std::shared_ptr< LoadInfo >, std::shared_ptr< FileLocations::Node >, std::shared_ptr< DomEnvironment >, std::shared_ptr< DomUniverse > > OwnerT
auto writeOutWrap(const T &, const DomItem &, OutWriter &, rank< 0 >) -> void
constexpr bool domTypeIsScriptElement(DomType)
QMLDOM_EXPORT QString domKindToString(DomKind k)
constexpr bool domTypeIsDomElement(DomType)
void updatePathFromOwnerQList(QList< T > &list, const Path &newPath)
constexpr bool domTypeCanBeInline(DomType k)
bool operator<(Version v1, Version v2)
bool operator<=(Version v1, Version v2)
auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw) -> void
auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw, rank< 1 >) -> decltype(t.writeOut(self, lw))
bool operator!=(Version v1, Version v2)
bool operator>=(Version v1, Version v2)
bool visitWithCustomListIteration(T *t, AST::Visitor *visitor)
std::function< void(const ErrorMessage &)> ErrorHandler
QMLDOM_EXPORT bool domTypeIsTopItem(DomType k)
QMLDOM_EXPORT void defaultErrorHandler(const ErrorMessage &)
Calls the default error handler (by default errorToQDebug)
void updatePathFromOwnerMultiMap(QMultiMap< K, T > &mmap, const Path &newPath)
constexpr bool domTypeIsObjWrap(DomType k)
bool emptyChildrenVisitor(Path, const DomItem &, bool)
static ErrorGroups importErrors
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")
#define QMLDOM_EXPORT
#define Q_SCRIPTELEMENT_EXIT_IF(check)
#define Q_SCRIPTELEMENT_DISABLE()
#define NewErrorGroup(name)
QT_BEGIN_NAMESPACE QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(writeOutLog, QMLDOM_EXPORT)
A common base class for all the script elements.
void setSemanticScope(const QQmlJSScope::ConstPtr &scope)
virtual void createFileLocations(const std::shared_ptr< FileLocations::Node > &fileLocationOfOwner)=0
std::shared_ptr< T > PointerType
QQmlJSScope::ConstPtr semanticScope()
SubclassStorage & operator=(const SubclassStorage &o)
SubclassStorage(const SubclassStorage &&o)
SubclassStorage(const SubclassStorage &o)