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
51QT_BEGIN_NAMESPACE
52
53QT_ENABLE_P0846_SEMANTICS_FOR(get_if)
54
55QT_DECLARE_EXPORTED_QT_LOGGING_CATEGORY(writeOutLog, QMLDOM_EXPORT);
56
57namespace QQmlJS {
58// we didn't have enough 'O's to properly name everything...
59namespace Dom {
60
61class Path;
62
63constexpr bool domTypeIsObjWrap(DomType k);
64constexpr bool domTypeIsValueWrap(DomType k);
65constexpr bool domTypeIsDomElement(DomType);
66constexpr bool domTypeIsOwningItem(DomType);
68constexpr bool domTypeIsScriptElement(DomType);
72constexpr bool domTypeCanBeInline(DomType k)
73{
74 switch (k) {
75 case DomType::Empty:
76 case DomType::Map:
77 case DomType::List:
78 case DomType::ListP:
83 return true;
84 default:
85 return false;
86 }
87}
89
94
95inline bool noFilter(const DomItem &, const PathEls::PathComponent &, const DomItem &)
96{
97 return true;
98}
99
101// using DirectVisitor = function_ref<bool(Path, const DomItem &)>;
102
103namespace {
104template<typename T>
105struct IsMultiMap : std::false_type
106{
107};
108
109template<typename Key, typename T>
110struct IsMultiMap<QMultiMap<Key, T>> : std::true_type
111{
112};
113
114template<typename T>
115struct IsMap : std::false_type
116{
117};
118
119template<typename Key, typename T>
120struct IsMap<QMap<Key, T>> : std::true_type
121{
122};
123
124template<typename... Ts>
125using void_t = void;
126
127template<typename T, typename = void>
128struct IsDomObject : std::false_type
129{
130};
131
132template<typename T>
133struct IsDomObject<T, void_t<decltype(T::kindValue)>> : std::true_type
134{
135};
136
137template<typename T, typename = void>
138struct IsInlineDom : std::false_type
139{
140};
141
142template<typename T>
143struct IsInlineDom<T, void_t<decltype(T::kindValue)>>
144 : std::integral_constant<bool, domTypeCanBeInline(T::kindValue)>
145{
146};
147
148template<typename T>
149struct IsInlineDom<T *, void_t<decltype(T::kindValue)>> : std::true_type
150{
151};
152
153template<typename T>
154struct IsInlineDom<std::shared_ptr<T>, void_t<decltype(T::kindValue)>> : std::true_type
155{
156};
157
158template<typename T>
159struct IsSharedPointerToDomObject : std::false_type
160{
161};
162
163template<typename T>
164struct IsSharedPointerToDomObject<std::shared_ptr<T>> : IsDomObject<T>
165{
166};
167
168template<typename T, typename = void>
169struct IsList : std::false_type
170{
171};
172
173template<typename T>
174struct IsList<T, void_t<typename T::value_type>> : std::true_type
175{
176};
177
178}
179
180template<typename T>
182 int i;
183 T lp;
184
185 // TODO: these are extremely nasty. What is this int doing in here?
186 T *data() { return reinterpret_cast<T *>(this); }
187 const T *data() const { return reinterpret_cast<const T *>(this); }
188
190 SubclassStorage(T &&el) { el.moveTo(data()); }
191 SubclassStorage(const T *el) { el->copyTo(data()); }
195 {
196 data()->~T();
197 o.data()->copyTo(data());
198 return *this;
199 }
200 ~SubclassStorage() { data()->~T(); }
201};
202
204{
205public:
206 using FilterT = function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>;
207
208 virtual ~DomBase() = default;
209
210 DomBase *domBase() { return this; }
211 const DomBase *domBase() const { return this; }
212
213 // minimal overload set:
214 virtual DomType kind() const = 0;
215 virtual DomKind domKind() const;
216 virtual Path pathFromOwner() const = 0;
217 virtual Path canonicalPath(const DomItem &self) const = 0;
218 virtual bool
220 DirectVisitor visitor) const = 0; // iterates the *direct* subpaths, returns
221 // false if a quick end was requested
222
224 const DomItem &self) const; // the DomItem corresponding to the canonicalSource source
225 virtual void dump(const DomItem &, const Sink &sink, int indent, FilterT filter) const;
226 virtual quintptr id() const;
227 QString typeName() const;
228
229 virtual QList<QString> fields(const DomItem &self) const;
230 virtual DomItem field(const DomItem &self, QStringView name) const;
231
232 virtual index_type indexes(const DomItem &self) const;
233 virtual DomItem index(const DomItem &self, index_type index) const;
234
235 virtual QSet<QString> const keys(const DomItem &self) const;
236 virtual DomItem key(const DomItem &self, const QString &name) const;
237
238 virtual QString canonicalFilePath(const DomItem &self) const;
239
240 virtual void writeOut(const DomItem &self, OutWriter &lw) const;
241
242 virtual QCborValue value() const {
243 return QCborValue();
244 }
245};
246
248{
249 switch (k) {
250 case DomType::Empty:
251 return DomKind::Empty;
252 case DomType::List:
253 case DomType::ListP:
254 return DomKind::List;
255 case DomType::Map:
256 return DomKind::Map;
257 case DomType::ConstantData:
258 return DomKind::Value;
259 default:
260 return DomKind::Object;
261 }
262}
263
264class QMLDOM_EXPORT Empty final : public DomBase
265{
266public:
267 constexpr static DomType kindValue = DomType::Empty;
268 DomType kind() const override { return kindValue; }
269
270 Empty *operator->() { return this; }
271 const Empty *operator->() const { return this; }
272 Empty &operator*() { return *this; }
273 const Empty &operator*() const { return *this; }
274
275 Empty();
276 quintptr id() const override { return ~quintptr(0); }
277 Path pathFromOwner() const override;
278 Path canonicalPath(const DomItem &self) const override;
279 DomItem containingObject(const DomItem &self) const override;
280 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
281 void dump(const DomItem &, const Sink &s, int indent,
282 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter)
283 const override;
284};
285
287protected:
288 DomElement& operator=(const DomElement&) = default;
289public:
290 DomElement(const Path &pathFromOwner = Path());
291 DomElement(const DomElement &o) = default;
292 Path pathFromOwner() const override { return m_pathFromOwner; }
293 Path canonicalPath(const DomItem &self) const override;
294 DomItem containingObject(const DomItem &self) const override;
295 virtual void updatePathFromOwner(const Path &newPath);
296
297private:
298 Path m_pathFromOwner;
299};
300
301class QMLDOM_EXPORT Map final : public DomElement
302{
303public:
304 constexpr static DomType kindValue = DomType::Map;
305 DomType kind() const override { return kindValue; }
306
307 Map *operator->() { return this; }
308 const Map *operator->() const { return this; }
309 Map &operator*() { return *this; }
310 const Map &operator*() const { return *this; }
311
312 using LookupFunction = std::function<DomItem(const DomItem &, QString)>;
313 using Keys = std::function<QSet<QString>(const DomItem &)>;
314 Map(const Path &pathFromOwner, const LookupFunction &lookup,
315 const Keys &keys, const QString &targetType);
316 quintptr id() const override;
317 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
318 QSet<QString> const keys(const DomItem &self) const override;
319 DomItem key(const DomItem &self, const QString &name) const override;
320
321 template<typename T>
322 static Map fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
323 template<typename T>
324 static Map fromMultiMap(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
325 template<typename T>
326 static Map
328 const Path &pathFromOwner, const QMap<QString, T> &mmap,
329 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper);
330
331 template<typename T>
332 static Map fromFileRegionMap(
333 const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map);
334
335private:
336 template<typename MapT>
337 static QSet<QString> fileRegionKeysFromMap(const MapT &map);
338 LookupFunction m_lookup;
339 Keys m_keys;
340 QString m_targetType;
341};
342
343class QMLDOM_EXPORT List final : public DomElement
344{
345public:
346 constexpr static DomType kindValue = DomType::List;
347 DomType kind() const override { return kindValue; }
348
349 List *operator->() { return this; }
350 const List *operator->() const { return this; }
351 List &operator*() { return *this; }
352 const List &operator*() const { return *this; }
353
354 using LookupFunction = std::function<DomItem(const DomItem &, index_type)>;
357 std::function<bool(const DomItem &, function_ref<bool(index_type, function_ref<DomItem()>)>)>;
358
359 List(const Path &pathFromOwner, const LookupFunction &lookup, const Length &length,
360 const IteratorFunction &iterator, const QString &elType);
361 quintptr id() const override;
362 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
363 void
364 dump(const DomItem &, const Sink &s, int indent,
365 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>) const override;
366 index_type indexes(const DomItem &self) const override;
367 DomItem index(const DomItem &self, index_type index) const override;
368
369 template<typename T>
370 static List
371 fromQList(const Path &pathFromOwner, const QList<T> &list,
372 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
374 template<typename T>
375 static List
376 fromQListRef(const Path &pathFromOwner, const QList<T> &list,
377 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
379 void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
380 void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
381
382private:
383 LookupFunction m_lookup;
384 Length m_length;
385 IteratorFunction m_iterator;
386 QString m_elType;
387};
388
390{
391public:
392 constexpr static DomType kindValue = DomType::ListP;
393 DomType kind() const override { return kindValue; }
394
395 ListPBase(const Path &pathFromOwner, const QList<const void *> &pList, const QString &elType)
396 : DomElement(pathFromOwner), m_pList(pList), m_elType(elType)
397 {
398 }
399 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
400 virtual void copyTo(ListPBase *) const { Q_ASSERT(false); };
401 virtual void moveTo(ListPBase *) const { Q_ASSERT(false); };
402 quintptr id() const override { return quintptr(0); }
403 index_type indexes(const DomItem &) const override { return index_type(m_pList.size()); }
404 void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
405 void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
406
407protected:
408 QList<const void *> m_pList;
410};
411
412template<typename T>
413class ListPT final : public ListPBase
414{
415public:
416 constexpr static DomType kindValue = DomType::ListP;
417
418 ListPT(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
420 : ListPBase(pathFromOwner, {},
421 (elType.isEmpty() ? QLatin1String(typeid(T).name()) : elType))
422 {
423 static_assert(sizeof(ListPBase) == sizeof(ListPT),
424 "ListPT does not have the same size as ListPBase");
425 static_assert(alignof(ListPBase) == alignof(ListPT),
426 "ListPT does not have the same size as ListPBase");
427 m_pList.reserve(pList.size());
428 if (options == ListOptions::Normal) {
429 for (const void *p : pList)
430 m_pList.append(p);
431 } else if (options == ListOptions::Reverse) {
432 for (qsizetype i = pList.size(); i-- != 0;)
433 // probably writing in reverse and reading sequentially would be better
434 m_pList.append(pList.at(i));
435 } else {
436 Q_ASSERT(false);
437 }
438 }
439 void copyTo(ListPBase *t) const override { new (t) ListPT(*this); }
440 void moveTo(ListPBase *t) const override { new (t) ListPT(std::move(*this)); }
441 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
442
443 DomItem index(const DomItem &self, index_type index) const override;
444};
445
447{
448public:
449 constexpr static DomType kindValue = DomType::ListP;
450 template<typename T>
451 ListP(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
454 {
455 }
456 ListP() = delete;
457
458 ListPBase *operator->() { return list.data(); }
459 const ListPBase *operator->() const { return list.data(); }
460 ListPBase &operator*() { return *list.data(); }
461 const ListPBase &operator*() const { return *list.data(); }
462
463private:
465};
466
467class QMLDOM_EXPORT ConstantData final : public DomElement
468{
469public:
471 DomType kind() const override { return kindValue; }
472
477
478 ConstantData *operator->() { return this; }
479 const ConstantData *operator->() const { return this; }
480 ConstantData &operator*() { return *this; }
481 const ConstantData &operator*() const { return *this; }
482
483 ConstantData(const Path &pathFromOwner, const QCborValue &value,
484 Options options = Options::MapIsMap);
485 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
486 quintptr id() const override;
487 DomKind domKind() const override;
488 QCborValue value() const override { return m_value; }
489 Options options() const { return m_options; }
490private:
491 QCborValue m_value;
492 Options m_options;
493};
494
496{
497public:
499 DomType kind() const final override { return m_kind; }
500
501 quintptr id() const final override { return m_id; }
502 DomKind domKind() const final override { return m_domKind; }
503
504 template <typename T>
505 T const *as() const
506 {
507 if (m_options & SimpleWrapOption::ValueType) {
508 if (m_value.metaType() == QMetaType::fromType<T>())
509 return static_cast<const T *>(m_value.constData());
510 return nullptr;
511 } else {
512 return m_value.value<const T *>();
513 }
514 }
515
517 virtual void copyTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
518 virtual void moveTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
519 bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
520 {
521 Q_ASSERT(false);
522 return true;
523 }
524
525protected:
526 friend class TestDomItem;
527 SimpleObjectWrapBase(const Path &pathFromOwner, const QVariant &value, quintptr idValue,
528 DomType kind = kindValue,
529 SimpleWrapOptions options = SimpleWrapOption::None)
530 : DomElement(pathFromOwner),
531 m_kind(kind),
533 m_value(value),
534 m_id(idValue),
536 {
537 }
538
544};
545
546template<typename T>
547class SimpleObjectWrapT final : public SimpleObjectWrapBase
548{
549public:
551
552 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
553 {
554 return asT()->iterateDirectSubpaths(self, visitor);
555 }
556
557 void writeOut(const DomItem &self, OutWriter &lw) const override;
558
559 const T *asT() const
560 {
561 if constexpr (domTypeIsValueWrap(T::kindValue)) {
562 if (m_value.metaType() == QMetaType::fromType<T>())
563 return static_cast<const T *>(m_value.constData());
564 return nullptr;
565 } else if constexpr (domTypeIsObjWrap(T::kindValue)) {
566 return m_value.value<const T *>();
567 } else {
568 // need dependent static assert to not unconditially trigger
569 static_assert(!std::is_same_v<T, T>, "wrapping of unexpected type");
570 return nullptr; // necessary to avoid warnings on INTEGRITY
571 }
572 }
573
574 void copyTo(SimpleObjectWrapBase *target) const override
575 {
576 static_assert(sizeof(SimpleObjectWrapBase) == sizeof(SimpleObjectWrapT),
577 "Size mismatch in SimpleObjectWrapT");
578 static_assert(alignof(SimpleObjectWrapBase) == alignof(SimpleObjectWrapT),
579 "Size mismatch in SimpleObjectWrapT");
580 new (target) SimpleObjectWrapT(*this);
581 }
582
583 void moveTo(SimpleObjectWrapBase *target) const override
584 {
585 static_assert(sizeof(SimpleObjectWrapBase) == sizeof(SimpleObjectWrapT),
586 "Size mismatch in SimpleObjectWrapT");
587 static_assert(alignof(SimpleObjectWrapBase) == alignof(SimpleObjectWrapT),
588 "Size mismatch in SimpleObjectWrapT");
589 new (target) SimpleObjectWrapT(std::move(*this));
590 }
591
592 SimpleObjectWrapT(const Path &pathFromOwner, const QVariant &v,
593 quintptr idValue, SimpleWrapOptions o)
594 : SimpleObjectWrapBase(pathFromOwner, v, idValue, T::kindValue, o)
595 {
596 Q_ASSERT(domTypeIsValueWrap(T::kindValue) == bool(o & SimpleWrapOption::ValueType));
597 }
598};
599
601{
602public:
604
605 SimpleObjectWrapBase *operator->() { return wrap.data(); }
606 const SimpleObjectWrapBase *operator->() const { return wrap.data(); }
607 SimpleObjectWrapBase &operator*() { return *wrap.data(); }
608 const SimpleObjectWrapBase &operator*() const { return *wrap.data(); }
609
610 template<typename T>
611 static SimpleObjectWrap fromObjectRef(const Path &pathFromOwner, T &value)
612 {
613 return SimpleObjectWrap(pathFromOwner, value);
614 }
616
617private:
618 template<typename T>
619 SimpleObjectWrap(const Path &pathFromOwner, T &value)
620 {
621 using BaseT = std::decay_t<T>;
622 if constexpr (domTypeIsObjWrap(BaseT::kindValue)) {
623 new (wrap.data()) SimpleObjectWrapT<BaseT>(pathFromOwner, QVariant::fromValue(&value),
624 quintptr(&value), SimpleWrapOption::None);
625 } else if constexpr (domTypeIsValueWrap(BaseT::kindValue)) {
626 new (wrap.data()) SimpleObjectWrapT<BaseT>(pathFromOwner, QVariant::fromValue(value),
627 quintptr(0), SimpleWrapOption::ValueType);
628 } else {
629 qCWarning(domLog) << "Unexpected object to wrap in SimpleObjectWrap: "
630 << domTypeToString(BaseT::kindValue);
631 Q_ASSERT_X(false, "SimpleObjectWrap",
632 "simple wrap of unexpected object"); // allow? (mocks for testing,...)
633 new (wrap.data())
634 SimpleObjectWrapT<BaseT>(pathFromOwner, nullptr, 0, SimpleWrapOption::None);
635 }
636 }
638};
639
641{
643public:
644 constexpr static DomType kindValue = DomType::Reference;
645 DomType kind() const override { return kindValue; }
646
647 Reference *operator->() { return this; }
648 const Reference *operator->() const { return this; }
649 Reference &operator*() { return *this; }
650 const Reference &operator*() const { return *this; }
651
652 bool shouldCache() const;
653 Reference(const Path &referredObject = Path(), const Path &pathFromOwner = Path(),
654 const SourceLocation &loc = SourceLocation());
655 quintptr id() const override;
656 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
657 DomItem field(const DomItem &self, QStringView name) const override;
658 QList<QString> fields(const DomItem &self) const override;
659 index_type indexes(const DomItem &) const override { return 0; }
660 DomItem index(const DomItem &, index_type) const override;
661 QSet<QString> const keys(const DomItem &) const override { return {}; }
662 DomItem key(const DomItem &, const QString &) const override;
663
664 DomItem get(const DomItem &self, const ErrorHandler &h = nullptr,
665 QList<Path> *visitedRefs = nullptr) const;
666 QList<DomItem> getAll(const DomItem &self, const ErrorHandler &h = nullptr,
667 QList<Path> *visitedRefs = nullptr) const;
668
670};
671
672namespace FileLocations {
673struct Info;
674}
675
676/*!
677 \internal
678 \brief A common base class for all the script elements.
679
680 This marker class allows to use all the script elements as a ScriptElement*, using virtual
681 dispatch. For now, it does not add any extra functionality, compared to a DomElement, but allows
682 to forbid DomElement* at the places where only script elements are required.
683 */
684// TODO: do we need another marker struct like this one to differentiate expressions from
685// statements? This would allow to avoid mismatchs between script expressions and script statements,
686// using type-safety.
688{
689 template<typename T>
690 using PointerType = std::shared_ptr<T>;
691
692 using DomElement::DomElement;
693 virtual void
694 createFileLocations(const std::shared_ptr<FileLocations::Node> &fileLocationOfOwner) = 0;
695
697 void setSemanticScope(const QQmlJSScope::ConstPtr &scope);
698
699private:
700 QQmlJSScope::ConstPtr m_scope;
701};
702
703/*!
704 \internal
705 \brief Use this to contain any script element.
706 */
708{
709private:
710 template<typename... T>
712
713 template<typename T, typename Variant>
714 struct TypeIsInVariant;
715
716 template<typename T, typename... Ts>
717 struct TypeIsInVariant<T, std::variant<Ts...>> : public std::disjunction<std::is_same<T, Ts>...>
718 {
719 };
720
721public:
728
729 template<typename T>
730 static ScriptElementVariant fromElement(const T &element)
731 {
732 static_assert(TypeIsInVariant<T, ScriptElementT>::value,
733 "Cannot construct ScriptElementVariant from T, as it is missing from the "
734 "ScriptElementT.");
736 p.m_data = element;
737 return p;
738 }
739
741
742 operator bool() const { return m_data.has_value(); }
743
744 template<typename F>
745 void visitConst(F &&visitor) const
746 {
747 if (m_data)
748 std::visit(std::forward<F>(visitor), *m_data);
749 }
750
751 template<typename F>
752 void visit(F &&visitor)
753 {
754 if (m_data)
755 std::visit(std::forward<F>(visitor), *m_data);
756 }
757 std::optional<ScriptElementT> data() { return m_data; }
758 void setData(const ScriptElementT &data) { m_data = data; }
759
760private:
761 std::optional<ScriptElementT> m_data;
762};
763
764/*!
765 \internal
766
767 To avoid cluttering the already unwieldy \l ElementT type below with all the types that the
768 different script elements can have, wrap them in an extra class. It will behave like an internal
769 Dom structure (e.g. like a List or a Map) and contain a pointer the the script element.
770 */
772{
773public:
775
777
778 DomBase *operator->() { return m_element.base().get(); }
779 const DomBase *operator->() const { return m_element.base().get(); }
780 DomBase &operator*() { return *m_element.base(); }
781 const DomBase &operator*() const { return *m_element.base(); }
782
783 ScriptElementVariant element() const { return m_element; }
784
785private:
786 ScriptElementVariant m_element;
787};
788
789// TODO: create more "groups" to simplify this variant? Maybe into Internal, ScriptExpression, ???
790using ElementT =
791 std::variant<ConstantData, Empty, List, ListP, Map, Reference, ScriptElementDomWrapper,
793 const DomEnvironment *, const DomUniverse *, const EnumDecl *,
795 const GlobalComponent *, const GlobalScope *, const JsFile *,
796 const JsResource *, const LoadInfo *, const MockObject *, const MockOwner *,
797 const ModuleIndex *, const ModuleScope *, const QmlComponent *,
798 const QmlDirectory *, const QmlFile *, const QmlObject *, const QmldirFile *,
799 const QmltypesComponent *, const QmltypesFile *, const ScriptExpression *>;
800
801using TopT = std::variant<
802 std::monostate,
803 std::shared_ptr<DomEnvironment>,
804 std::shared_ptr<DomUniverse>>;
805
806using OwnerT =
807 std::variant<std::monostate, std::shared_ptr<ModuleIndex>, std::shared_ptr<MockOwner>,
808 std::shared_ptr<ExternalItemInfoBase>, std::shared_ptr<ExternalItemPairBase>,
809 std::shared_ptr<QmlDirectory>, std::shared_ptr<QmldirFile>,
810 std::shared_ptr<JsFile>, std::shared_ptr<QmlFile>,
811 std::shared_ptr<QmltypesFile>, std::shared_ptr<GlobalScope>,
812 std::shared_ptr<ScriptExpression>, std::shared_ptr<AstComments>,
813 std::shared_ptr<LoadInfo>, std::shared_ptr<FileLocations::Node>,
814 std::shared_ptr<DomEnvironment>, std::shared_ptr<DomUniverse>>;
815
816inline bool emptyChildrenVisitor(Path, const DomItem &, bool)
817{
818 return true;
819}
820
821class MutableDomItem;
822
824{
825public:
831
832 FileToLoad(const std::weak_ptr<DomEnvironment> &environment, const QString &canonicalPath,
833 const QString &logicalPath, const std::optional<InMemoryContents> &content);
834 FileToLoad() = default;
835
836 static FileToLoad fromMemory(const std::weak_ptr<DomEnvironment> &environment,
837 const QString &path, const QString &data);
838 static FileToLoad fromFileSystem(const std::weak_ptr<DomEnvironment> &environment,
839 const QString &canonicalPath);
840
841 std::shared_ptr<DomEnvironment> environment() const { return m_environment.lock(); }
842 QString canonicalPath() const { return m_canonicalPath; }
843 QString logicalPath() const { return m_logicalPath; }
844 void setCanonicalPath(const QString &canonicalPath) { m_canonicalPath = canonicalPath; }
845 void setLogicalPath(const QString &logicalPath) { m_logicalPath = logicalPath; }
846 std::optional<InMemoryContents> content() const { return m_content; }
847
848private:
849 std::weak_ptr<DomEnvironment> m_environment;
850 QString m_canonicalPath;
851 QString m_logicalPath;
852 std::optional<InMemoryContents> m_content;
853};
854
857public:
858 using Callback = std::function<void(const Path &, const DomItem &, const DomItem &)>;
859
861 using Visitor = function_ref<bool(const Path &, const DomItem &)>;
862 using ChildrenVisitor = function_ref<bool(const Path &, const DomItem &, bool)>;
863
865 static ErrorGroups myErrors();
868
870
871 template<typename F>
872 auto visitEl(F f) const
873 {
874 return std::visit(f, this->m_element);
875 }
876
877 explicit operator bool() const { return m_kind != DomType::Empty; }
879 return m_kind;
880 }
881 QString internalKindStr() const { return domTypeToString(internalKind()); }
883 {
884 if (m_kind == DomType::ConstantData)
885 return std::get<ConstantData>(m_element).domKind();
886 else
887 return kind2domKind(m_kind);
888 }
889
890 Path canonicalPath() const;
891
892 DomItem filterUp(function_ref<bool(DomType k, const DomItem &)> filter, FilterUpOptions options) const;
894 DomItem container() const;
895 DomItem owner() const;
896 DomItem top() const;
897 DomItem environment() const;
898 DomItem universe() const;
899 DomItem containingFile() const;
901 DomItem goToFile(const QString &filePath) const;
902 DomItem goUp(int) const;
903 DomItem directParent() const;
904
905 DomItem qmlObject(GoTo option = GoTo::Strict,
907 DomItem fileObject(GoTo option = GoTo::Strict) const;
908 DomItem rootQmlObject(GoTo option = GoTo::Strict) const;
909 DomItem globalScope() const;
910 DomItem component(GoTo option = GoTo::Strict) const;
914
915 // convenience getters
916 DomItem get(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
917 QList<DomItem> getAll(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
923 bool isCanonicalChild(const DomItem &child) const;
924 bool hasAnnotations() const;
925 QString name() const { return field(Fields::name).value().toString(); }
926 DomItem pragmas() const { return field(Fields::pragmas); }
927 DomItem ids() const { return field(Fields::ids); }
928 QString idStr() const { return field(Fields::idStr).value().toString(); }
929 DomItem propertyInfos() const { return field(Fields::propertyInfos); }
930 PropertyInfo propertyInfoWithName(const QString &name) const;
932 DomItem propertyDefs() const { return field(Fields::propertyDefs); }
933 DomItem bindings() const { return field(Fields::bindings); }
934 DomItem methods() const { return field(Fields::methods); }
935 DomItem enumerations() const { return field(Fields::enumerations); }
936 DomItem children() const { return field(Fields::children); }
937 DomItem child(index_type i) const { return field(Fields::children).index(i); }
939 {
941 return field(Fields::annotations);
942 else
943 return DomItem();
944 }
945
946 bool resolve(const Path &path, Visitor visitor, const ErrorHandler &errorHandler,
947 ResolveOptions options = ResolveOption::None, const Path &fullPath = Path(),
948 QList<Path> *visitedRefs = nullptr) const;
949
950 DomItem operator[](const Path &path) const;
951 DomItem operator[](QStringView component) const;
952 DomItem operator[](const QString &component) const;
953 DomItem operator[](const char16_t *component) const
954 {
955 return (*this)[QStringView(component)];
956 } // to avoid clash with stupid builtin ptrdiff_t[DomItem&], coming from C
957 DomItem operator[](index_type i) const { return index(i); }
958 DomItem operator[](int i) const { return index(i); }
959 index_type size() const { return indexes() + keys().size(); }
960 index_type length() const { return size(); }
961
962 DomItem path(const Path &p, const ErrorHandler &h = &defaultErrorHandler) const;
963 DomItem path(const QString &p, const ErrorHandler &h = &defaultErrorHandler) const;
964 DomItem path(QStringView p, const ErrorHandler &h = &defaultErrorHandler) const;
965
966 QList<QString> fields() const;
967 DomItem field(QStringView name) const;
968
969 index_type indexes() const;
970 DomItem index(index_type) const;
971 bool visitIndexes(function_ref<bool(const DomItem &)> visitor) const;
972
973 QSet<QString> keys() const;
974 QStringList sortedKeys() const;
975 DomItem key(const QString &name) const;
976 DomItem key(QStringView name) const { return key(name.toString()); }
977 bool visitKeys(function_ref<bool(const QString &, const DomItem &)> visitor) const;
978
979 QList<DomItem> values() const;
980 void writeOutPre(OutWriter &lw) const;
981 void writeOut(OutWriter &lw) const;
982 void writeOutPost(OutWriter &lw) const;
983 bool writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks) const;
984 bool writeOut(const QString &path, const LineWriterOptions &opt = LineWriterOptions(),
985 FileWriter *fw = nullptr,
986 WriteOutChecks extraChecks = WriteOutCheck::Default) const;
987
988 bool visitTree(const Path &basePath, ChildrenVisitor visitor,
989 VisitOptions options = VisitOption::Default,
990 ChildrenVisitor openingVisitor = emptyChildrenVisitor,
991 ChildrenVisitor closingVisitor = emptyChildrenVisitor,
992 const FieldFilter &filter = FieldFilter::noFilter()) const;
993 bool visitPrototypeChain(function_ref<bool(const DomItem &)> visitor,
994 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
995 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
996 QList<Path> *visitedRefs = nullptr) const;
997 bool visitDirectAccessibleScopes(function_ref<bool(const DomItem &)> visitor,
998 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
999 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1000 QList<Path> *visitedRefs = nullptr) const;
1001 bool
1002 visitStaticTypePrototypeChains(function_ref<bool(const DomItem &)> visitor,
1003 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
1004 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1005 QList<Path> *visitedRefs = nullptr) const;
1006
1007 bool visitUp(function_ref<bool(const DomItem &)> visitor) const;
1008 bool visitScopeChain(
1009 function_ref<bool(const DomItem &)> visitor, LookupOptions = LookupOption::Normal,
1010 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1011 QList<Path> *visitedRefs = nullptr) const;
1013 const QString &name, function_ref<bool(const DomItem &)> visitor) const;
1014 bool visitLookup1(
1015 const QString &symbolName, function_ref<bool(const DomItem &)> visitor,
1016 LookupOptions = LookupOption::Normal, const ErrorHandler &h = nullptr,
1017 QSet<quintptr> *visited = nullptr, QList<Path> *visitedRefs = nullptr) const;
1018 bool visitLookup(
1019 const QString &symbolName, function_ref<bool(const DomItem &)> visitor,
1020 LookupType type = LookupType::Symbol, LookupOptions = LookupOption::Normal,
1021 const ErrorHandler &errorHandler = nullptr, QSet<quintptr> *visited = nullptr,
1022 QList<Path> *visitedRefs = nullptr) const;
1024 const QString &name, function_ref<bool(const DomItem &)> visitor) const;
1026 const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
1028 const QString &symbolName, LookupType type = LookupType::Symbol,
1029 LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
1031 const QString &symbolName, LookupType type = LookupType::Symbol,
1032 LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
1033
1034 quintptr id() const;
1035 Path pathFromOwner() const;
1036 QString canonicalFilePath() const;
1038 bool commitToBase(const std::shared_ptr<DomEnvironment> &validPtr = nullptr) const;
1040 QCborValue value() const;
1041
1042 void dumpPtr(const Sink &sink) const;
1043 void dump(const Sink &, int indent = 0,
1044 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter =
1045 noFilter) const;
1047 dump(const QString &path,
1048 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>
1049 filter = noFilter,
1050 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 subValueItem(const PathEls::PathComponent &c, const T &value,
1076 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1077 template <typename T>
1078 bool invokeVisitorOnValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value,
1079 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1080 template <typename F>
1081 bool invokeVisitorOnLazyField(DirectVisitor visitor, QStringView f, F valueF,
1082 ConstantData::Options options = ConstantData::Options::MapIsMap) const
1083 {
1084 PathEls::PathComponent c = PathEls::Field(f);
1085 auto lazyWrap = [this, &c, &valueF, options]() {
1086 return this->subValueItem<decltype(valueF())>(c, valueF(), options);
1087 };
1088 return visitor(c, lazyWrap);
1089 }
1090 DomItem subReferencesItem(const PathEls::PathComponent &c, const QList<Path> &paths) const;
1091 DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const;
1092 bool invokeVisitorOnReference(DirectVisitor visitor, QStringView f,
1093 const Path &referencedObject) const
1094 {
1095 PathEls::PathComponent c = PathEls::Field(f);
1096 return visitor(c, [c, this, referencedObject]() {
1097 return this->subReferenceItem(c, referencedObject);
1098 });
1099 }
1100 bool invokeVisitorOnReferences(DirectVisitor visitor, QStringView f,
1101 const QList<Path> &paths) const
1102 {
1103 PathEls::PathComponent c = PathEls::Field(f);
1104 return visitor(c, [c, this, paths]() { return this->subReferencesItem(c, paths); });
1105 }
1106 DomItem subListItem(const List &list) const;
1107 DomItem subMapItem(const Map &map) const;
1108
1110 {
1111 Q_ASSERT(obj);
1112 return DomItem(m_top, m_owner, m_ownerPath, ScriptElementDomWrapper(obj));
1113 }
1114
1115 template<typename Owner>
1116 DomItem subOwnerItem(const PathEls::PathComponent &c, Owner o) const
1117 {
1118 if constexpr (domTypeIsUnattachedOwningItem(Owner::element_type::kindValue))
1119 return DomItem(m_top, o, canonicalPath().withComponent(c), o.get());
1120 else
1121 return DomItem(m_top, o, Path(), o.get());
1122 }
1123 template <typename T>
1124 DomItem wrap(const PathEls::PathComponent &c, const T &obj) const;
1125 template <typename T>
1126 bool invokeVisitorOnField(DirectVisitor visitor, QStringView f, T &obj) const
1127 {
1128 PathEls::PathComponent c = PathEls::Field(f);
1129 auto lazyWrap = [this, &c, &obj]() { return this->wrap<T>(c, obj); };
1130 return visitor(c, lazyWrap);
1131 }
1132
1133 DomItem() = default;
1134 DomItem(const std::shared_ptr<DomEnvironment> &);
1135 DomItem(const std::shared_ptr<DomUniverse> &);
1136
1137 // TODO move to DomEnvironment?
1138 static DomItem fromCode(const QString &code, DomType fileType = DomType::QmlFile);
1139
1140 // --- start of potentially dangerous stuff, make private? ---
1141
1142 std::shared_ptr<DomTop> topPtr() const;
1143 std::shared_ptr<OwningItem> owningItemPtr() const;
1144
1145 // keep the DomItem around to ensure that it doesn't get deleted
1146 template<typename T, typename std::enable_if<std::is_base_of_v<DomBase, T>, bool>::type = true>
1147 T const *as() const
1148 {
1149 if (m_kind == T::kindValue) {
1150 if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
1151 return std::get<SimpleObjectWrap>(m_element)->as<T>();
1152 else
1153 return static_cast<T const *>(base());
1154 }
1155 return nullptr;
1156 }
1157
1158 template<typename T, typename std::enable_if<!std::is_base_of_v<DomBase, T>, bool>::type = true>
1159 T const *as() const
1160 {
1161 if (m_kind == T::kindValue) {
1162 Q_ASSERT(domTypeIsObjWrap(m_kind) || domTypeIsValueWrap(m_kind));
1163 return std::get<SimpleObjectWrap>(m_element)->as<T>();
1164 }
1165 return nullptr;
1166 }
1167
1168 template<typename T>
1169 std::shared_ptr<T> ownerAs() const;
1170
1171 template<typename Owner, typename T>
1172 DomItem copy(const Owner &owner, const Path &ownerPath, const T &base) const
1173 {
1174 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1175 static_assert(IsInlineDom<std::decay_t<T>>::value, "Expected an inline item or pointer");
1176 return DomItem(m_top, owner, ownerPath, base);
1177 }
1178
1179 template<typename Owner>
1180 DomItem copy(const Owner &owner, const Path &ownerPath) const
1181 {
1182 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1183 return DomItem(m_top, owner, ownerPath, owner.get());
1184 }
1185
1186 template<typename T>
1187 DomItem copy(const T &base) const
1188 {
1189 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1190 using BaseT = std::decay_t<T>;
1191 static_assert(!std::is_same_v<BaseT, ElementT>,
1192 "variant not supported, pass in the stored types");
1193 static_assert(IsInlineDom<BaseT>::value || std::is_same_v<BaseT, std::monostate>,
1194 "expected either a pointer or an inline item");
1195
1196 if constexpr (IsSharedPointerToDomObject<BaseT>::value)
1197 return DomItem(m_top, base, Path(), base.get());
1198 else if constexpr (IsInlineDom<BaseT>::value)
1199 return DomItem(m_top, m_owner, m_ownerPath, base);
1200
1201 Q_UNREACHABLE_RETURN(DomItem(m_top, m_owner, m_ownerPath, nullptr));
1202 }
1203
1204private:
1205 template <typename T>
1206 std::shared_ptr<T> ownerAs_impl() const
1207 {
1208 if (auto p = get_if<std::shared_ptr<T>>(&m_owner))
1209 return *p;
1210 return nullptr;
1211 }
1212
1213 enum class WriteOutCheckResult { Success, Failed };
1214 WriteOutCheckResult performWriteOutChecks(const DomItem &, OutWriter &, WriteOutChecks) const;
1215 const DomBase *base() const;
1216
1217 template<typename Env, typename Owner>
1218 DomItem(Env, Owner, Path, std::nullptr_t) : DomItem()
1219 {
1220 }
1221
1222 template<typename Env, typename Owner, typename T,
1223 typename = std::enable_if_t<IsInlineDom<std::decay_t<T>>::value>>
1224 DomItem(Env env, Owner owner, const Path &ownerPath, const T &el)
1225 : m_top(env), m_owner(owner), m_ownerPath(ownerPath), m_element(el)
1226 {
1227 using BaseT = std::decay_t<T>;
1228 if constexpr (std::is_pointer_v<BaseT>) {
1229 if (!el || el->kind() == DomType::Empty) { // avoid null ptr, and allow only a
1230 // single kind of Empty
1231 m_kind = DomType::Empty;
1232 m_top = std::monostate();
1233 m_owner = std::monostate();
1234 m_ownerPath = Path();
1235 m_element = Empty();
1236 } else {
1237 using DomT = std::remove_pointer_t<BaseT>;
1238 m_element = el;
1239 m_kind = DomT::kindValue;
1240 }
1241 } else {
1242 static_assert(!std::is_same_v<BaseT, ElementT>,
1243 "variant not supported, pass in the internal type");
1244 m_kind = el->kind();
1245 }
1246 }
1247 friend class DomBase;
1248 friend class DomElement;
1249 friend class Map;
1250 friend class List;
1251 friend class QmlObject;
1252 friend class DomUniverse;
1253 friend class DomEnvironment;
1255 friend class ConstantData;
1256 friend class MutableDomItem;
1257 friend class ScriptExpression;
1258 friend class AstComments;
1259 friend class FileLocations::Node;
1260 friend class TestDomItem;
1261 friend QMLDOM_EXPORT bool operator==(const DomItem &, const DomItem &);
1262 DomType m_kind = DomType::Empty;
1263 TopT m_top;
1264 OwnerT m_owner;
1265 Path m_ownerPath;
1266 ElementT m_element = Empty();
1267};
1268
1269QMLDOM_EXPORT bool operator==(const DomItem &o1, const DomItem &o2);
1270
1271inline bool operator!=(const DomItem &o1, const DomItem &o2)
1272{
1273 return !(o1 == o2);
1274}
1275
1276template<typename T>
1277static DomItem keyMultiMapHelper(const DomItem &self, const QString &key,
1278 const QMultiMap<QString, T> &mmap)
1279{
1280 auto it = mmap.find(key);
1281 auto end = mmap.cend();
1282 if (it == end)
1283 return DomItem();
1284 else {
1285 // special case single element (++it == end || it.key() != key)?
1286 QList<const T *> values;
1287 while (it != end && it.key() == key)
1288 values.append(&(*it++));
1289 ListP ll(self.pathFromOwner().withComponent(PathEls::Key(key)), values, QString(),
1291 return self.copy(ll);
1292 }
1293}
1294
1295template<typename T>
1296Map Map::fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap)
1297{
1298 return Map(
1299 pathFromOwner,
1300 [&mmap](const DomItem &self, const QString &key) {
1301 return keyMultiMapHelper(self, key, mmap);
1302 },
1303 [&mmap](const DomItem &) { return QSet<QString>(mmap.keyBegin(), mmap.keyEnd()); },
1304 QLatin1String(typeid(T).name()));
1305}
1306
1307template<typename T>
1308Map Map::fromMapRef(
1309 const Path &pathFromOwner, const QMap<QString, T> &map,
1310 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper)
1311{
1312 return Map(
1313 pathFromOwner,
1314 [&map, elWrapper](const DomItem &self, const QString &key) {
1315 const auto it = map.constFind(key);
1316 if (it == map.constEnd())
1317 return DomItem();
1318 return elWrapper(self, PathEls::Key(key), it.value());
1319 },
1320 [&map](const DomItem &) { return QSet<QString>(map.keyBegin(), map.keyEnd()); },
1321 QLatin1String(typeid(T).name()));
1322}
1323
1324template<typename MapT>
1325QSet<QString> Map::fileRegionKeysFromMap(const MapT &map)
1326{
1327 QSet<QString> keys;
1328 std::transform(map.keyBegin(), map.keyEnd(), std::inserter(keys, keys.begin()), fileLocationRegionName);
1329 return keys;
1330}
1331
1332template<typename T>
1333Map Map::fromFileRegionMap(const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map)
1334{
1335 auto result = Map(
1336 pathFromOwner,
1337 [&map](const DomItem &mapItem, const QString &key) -> DomItem {
1338 auto it = map.constFind(fileLocationRegionValue(key));
1339 if (it == map.constEnd())
1340 return {};
1341
1342 return mapItem.wrap(PathEls::Key(key), *it);
1343 },
1344 [&map](const DomItem &) { return fileRegionKeysFromMap(map); },
1345 QString::fromLatin1(typeid(T).name()));
1346 return result;
1347}
1348
1349template<typename T>
1350List List::fromQList(
1351 const Path &pathFromOwner, const QList<T> &list,
1352 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
1353 ListOptions options)
1354{
1355 index_type len = list.size();
1356 if (options == ListOptions::Reverse) {
1357 return List(
1358 pathFromOwner,
1359 [list, elWrapper](const DomItem &self, index_type i) mutable {
1360 if (i < 0 || i >= list.size())
1361 return DomItem();
1362 return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
1363 },
1364 [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
1365 } else {
1366 return List(
1367 pathFromOwner,
1368 [list, elWrapper](const DomItem &self, index_type i) mutable {
1369 if (i < 0 || i >= list.size())
1370 return DomItem();
1371 return elWrapper(self, PathEls::Index(i), list[i]);
1372 },
1373 [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
1374 }
1375}
1376
1377template<typename T>
1378List List::fromQListRef(
1379 const Path &pathFromOwner, const QList<T> &list,
1380 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
1381 ListOptions options)
1382{
1383 if (options == ListOptions::Reverse) {
1384 return List(
1385 pathFromOwner,
1386 [&list, elWrapper](const DomItem &self, index_type i) {
1387 if (i < 0 || i >= list.size())
1388 return DomItem();
1389 return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
1390 },
1391 [&list](const DomItem &) { return list.size(); }, nullptr,
1392 QLatin1String(typeid(T).name()));
1393 } else {
1394 return List(
1395 pathFromOwner,
1396 [&list, elWrapper](const DomItem &self, index_type i) {
1397 if (i < 0 || i >= list.size())
1398 return DomItem();
1399 return elWrapper(self, PathEls::Index(i), list[i]);
1400 },
1401 [&list](const DomItem &) { return list.size(); }, nullptr,
1402 QLatin1String(typeid(T).name()));
1403 }
1404}
1405
1407protected:
1408 virtual std::shared_ptr<OwningItem> doCopy(const DomItem &self) const = 0;
1409
1410public:
1411 OwningItem(const OwningItem &o);
1412 OwningItem(int derivedFrom=0);
1413 OwningItem(int derivedFrom, const QDateTime &lastDataUpdateAt);
1414 OwningItem(const OwningItem &&) = delete;
1415 OwningItem &operator=(const OwningItem &&) = delete;
1416 static int nextRevision();
1417
1418 Path canonicalPath(const DomItem &self) const override = 0;
1419
1420 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
1421 std::shared_ptr<OwningItem> makeCopy(const DomItem &self) const { return doCopy(self); }
1422 Path pathFromOwner() const override final { return Path(); }
1423 DomItem containingObject(const DomItem &self) const override;
1424 int derivedFrom() const;
1425 virtual int revision() const;
1426
1427 QDateTime createdAt() const;
1428 virtual QDateTime lastDataUpdateAt() const;
1429 virtual void refreshedDataAt(QDateTime tNew);
1430
1431 // explicit freeze handling needed?
1432 virtual bool frozen() const;
1433 virtual bool freeze();
1434 QDateTime frozenAt() const;
1435
1436 virtual void addError(const DomItem &self, ErrorMessage &&msg);
1437 void addErrorLocal(ErrorMessage &&msg);
1438 void clearErrors(const ErrorGroups &groups = ErrorGroups({}));
1439 // return false if a quick exit was requested
1440 bool iterateErrors(
1441 const DomItem &self,
1442 function_ref<bool(const DomItem &source, const ErrorMessage &msg)> visitor,
1443 const Path &inPath = Path());
1445 QMutexLocker l(mutex());
1446 return m_errors;
1447 }
1448
1449 virtual bool iterateSubOwners(const DomItem &self, function_ref<bool(const DomItem &owner)> visitor);
1450
1451 QBasicMutex *mutex() const { return &m_mutex; }
1452private:
1453 mutable QBasicMutex m_mutex;
1454 int m_derivedFrom;
1455 int m_revision;
1456 QDateTime m_createdAt;
1457 QDateTime m_lastDataUpdateAt;
1458 QDateTime m_frozenAt;
1459 QMultiMap<Path, ErrorMessage> m_errors;
1460 QMap<ErrorMessage, quint32> m_errorsCounts;
1461};
1462
1463template<typename T>
1464std::shared_ptr<T> DomItem::ownerAs() const
1465{
1466 static_assert(domTypeIsOwningItem(T::kindValue),
1467 "unexpected non owning value in ownerAs");
1468 if constexpr (T::kindValue == DomType::FileLocationsNode)
1469 return std::static_pointer_cast<T>(ownerAs_impl<FileLocations::Node>());
1470 else if constexpr (T::kindValue == DomType::ExternalItemInfo)
1471 return std::static_pointer_cast<T>(ownerAs_impl<ExternalItemInfoBase>());
1472 else if constexpr (T::kindValue == DomType::ExternalItemPair)
1473 return std::static_pointer_cast<T>(ownerAs_impl<ExternalItemPairBase>());
1474 else
1475 return ownerAs_impl<T>();
1476}
1477
1478template<int I>
1479struct rank : rank<I - 1>
1480{
1481 static_assert(I > 0, "");
1482};
1483template<>
1484struct rank<0>
1485{
1486};
1487
1488template<typename T>
1489auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw, rank<1>)
1490 -> decltype(t.writeOut(self, lw))
1491{
1492 t.writeOut(self, lw);
1493}
1494
1495template<typename T>
1496auto writeOutWrap(const T &, const DomItem &, OutWriter &, rank<0>) -> void
1497{
1498 qCWarning(writeOutLog) << "Ignoring writeout to wrapped object not supporting it ("
1499 << typeid(T).name();
1500}
1501template<typename T>
1502auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw) -> void
1503{
1504 writeOutWrap(t, self, lw, rank<1>());
1505}
1506
1507template<typename T>
1508void SimpleObjectWrapT<T>::writeOut(const DomItem &self, OutWriter &lw) const
1509{
1510 writeOutWrap<T>(*asT(), self, lw);
1511}
1512
1513QMLDOM_EXPORT QDebug operator<<(QDebug debug, const DomItem &c);
1514
1515// TODO QTBUG-121518 quite some methods are used only in the "examples"
1516// Even though MutableDomItem provides some API for modifying internal data,
1517// de-facto it's not very helpful / convinient / intuitive to use
1518// Moreover it just amplifies and repeats issues of DomItem interface,
1519// a.k.a. abuse or misuse of type erasure technique
1521public:
1523
1524 explicit operator bool() const
1525 {
1526 return bool(m_owner);
1527 } // this is weaker than item(), but normally correct
1529 QString internalKindStr() { return domTypeToString(internalKind()); }
1530 DomKind domKind() { return kind2domKind(internalKind()); }
1531
1532 Path canonicalPath() const { return m_owner.canonicalPath().withPath(m_pathFromOwner); }
1534 {
1535 if (m_pathFromOwner)
1536 return MutableDomItem(m_owner, m_pathFromOwner.split().pathToSource);
1537 else {
1538 DomItem cObj = m_owner.containingObject();
1540 }
1541 }
1542
1544 {
1545 if (m_pathFromOwner)
1546 return MutableDomItem(m_owner, m_pathFromOwner.dropTail());
1547 else {
1549 }
1550 }
1551
1554 {
1555 return MutableDomItem(item().qmlObject(option, fOptions));
1556 }
1558 {
1559 return MutableDomItem(item().fileObject(option));
1560 }
1562 {
1563 return MutableDomItem(item().rootQmlObject(option));
1564 }
1567
1569 {
1570 return MutableDomItem { item().component(option) };
1571 }
1572 MutableDomItem owner() { return MutableDomItem(m_owner); }
1576 Path pathFromOwner() { return m_pathFromOwner; }
1578 MutableDomItem operator[](QStringView component) { return MutableDomItem(item()[component]); }
1579 MutableDomItem operator[](const QString &component)
1580 {
1581 return MutableDomItem(item()[component]);
1582 }
1583 MutableDomItem operator[](const char16_t *component)
1584 {
1585 // to avoid clash with stupid builtin ptrdiff_t[MutableDomItem&], coming from C
1586 return MutableDomItem(item()[QStringView(component)]);
1587 }
1588 MutableDomItem operator[](index_type i) { return MutableDomItem(item().index(i)); }
1589
1591 MutableDomItem path(const QString &p) { return path(Path::fromString(p)); }
1592 MutableDomItem path(QStringView p) { return path(Path::fromString(p)); }
1593
1594 QList<QString> const fields() { return item().fields(); }
1595 MutableDomItem field(QStringView name) { return MutableDomItem(item().field(name)); }
1596 index_type indexes() { return item().indexes(); }
1597 MutableDomItem index(index_type i) { return MutableDomItem(item().index(i)); }
1598
1599 QSet<QString> const keys() { return item().keys(); }
1600 MutableDomItem key(const QString &name) { return MutableDomItem(item().key(name)); }
1601 MutableDomItem key(QStringView name) { return key(name.toString()); }
1602
1603 void
1604 dump(const Sink &s, int indent = 0,
1605 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter)
1606 {
1607 item().dump(s, indent, filter);
1608 }
1610 dump(const QString &path,
1611 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>
1612 filter = noFilter,
1613 int indent = 0, FileWriter *fw = nullptr)
1614 {
1615 return item().dump(path, filter, indent, fw);
1616 }
1617 void writeOut(OutWriter &lw) { return item().writeOut(lw); }
1618 bool writeOut(const QString &path, const LineWriterOptions &opt = LineWriterOptions(),
1619 FileWriter *fw = nullptr)
1620 {
1621 return item().writeOut(path, opt, fw);
1622 }
1623
1628 bool commitToBase(const std::shared_ptr<DomEnvironment> &validEnvPtr = nullptr)
1629 {
1630 return item().commitToBase(validEnvPtr);
1631 }
1632 QString canonicalFilePath() const { return item().canonicalFilePath(); }
1633
1635
1636 QCborValue value() { return item().value(); }
1637
1638 QString toString() { return item().toString(); }
1639
1640 // convenience getters
1641 QString name() { return item().name(); }
1644 QString idStr() { return item().idStr(); }
1649 MutableDomItem child(index_type i) { return MutableDomItem(item().child(i)); }
1651
1652 // // OwnigItem elements
1653 int derivedFrom() { return m_owner.derivedFrom(); }
1654 int revision() { return m_owner.revision(); }
1655 QDateTime createdAt() { return m_owner.createdAt(); }
1656 QDateTime frozenAt() { return m_owner.frozenAt(); }
1657 QDateTime lastDataUpdateAt() { return m_owner.lastDataUpdateAt(); }
1658
1659 void addError(ErrorMessage &&msg) { item().addError(std::move(msg)); }
1661
1662 // convenience setters
1667 const MethodInfo &functionDef, AddOption option = AddOption::Overwrite);
1669
1670 MutableDomItem() = default;
1671 MutableDomItem(const DomItem &owner, const Path &pathFromOwner):
1673 {}
1677
1678 std::shared_ptr<DomTop> topPtr() { return m_owner.topPtr(); }
1679 std::shared_ptr<OwningItem> owningItemPtr() { return m_owner.owningItemPtr(); }
1680
1681 template<typename T>
1682 T const *as()
1683 {
1684 return item().as<T>();
1685 }
1686
1687 template <typename T>
1689 Q_ASSERT(!m_owner || !m_owner.owningItemPtr()->frozen());
1690
1691 DomItem self = item();
1692 if (self.m_kind != T::kindValue)
1693 return nullptr;
1694
1695 const T *t = nullptr;
1696 if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
1697 t = static_cast<const SimpleObjectWrapBase *>(self.base())->as<T>();
1698 else if constexpr (std::is_base_of<DomBase, T>::value)
1699 t = static_cast<const T *>(self.base());
1700 else
1701 Q_UNREACHABLE_RETURN(nullptr);
1702
1703 // Nasty. But since ElementT has to store the const pointers, we allow it in this one place.
1704 return const_cast<T *>(t);
1705 }
1706
1707 template<typename T>
1708 std::shared_ptr<T> ownerAs() const
1709 {
1710 return m_owner.ownerAs<T>();
1711 }
1712 // it is dangerous to assume it stays valid when updates are preformed...
1713 DomItem item() const { return m_owner.path(m_pathFromOwner); }
1714
1715 friend bool operator==(const MutableDomItem &o1, const MutableDomItem &o2)
1716 {
1717 return o1.m_owner == o2.m_owner && o1.m_pathFromOwner == o2.m_pathFromOwner;
1718 }
1719 friend bool operator!=(const MutableDomItem &o1, const MutableDomItem &o2)
1720 {
1721 return !(o1 == o2);
1722 }
1723
1724private:
1725 DomItem m_owner;
1726 Path m_pathFromOwner;
1727};
1728
1729QMLDOM_EXPORT QDebug operator<<(QDebug debug, const MutableDomItem &c);
1730
1731template<typename K, typename T>
1732Path insertUpdatableElementInMultiMap(const Path &mapPathFromOwner, QMultiMap<K, T> &mmap, K key,
1733 const T &value, AddOption option = AddOption::KeepExisting,
1734 T **valuePtr = nullptr)
1735{
1736 if (option == AddOption::Overwrite) {
1737 auto it = mmap.find(key);
1738 if (it != mmap.end()) {
1739 T &v = *it;
1740 v = value;
1741 if (++it != mmap.end() && it.key() == key) {
1742 qWarning() << " requested overwrite of " << key
1743 << " that contains aleready multiple entries in" << mapPathFromOwner;
1744 }
1745 Path newPath = mapPathFromOwner.withKey(key).withIndex(0);
1746 v.updatePathFromOwner(newPath);
1747 if (valuePtr)
1748 *valuePtr = &v;
1749 return newPath;
1750 }
1751 }
1752 mmap.insert(key, value);
1753 auto it = mmap.find(key);
1754 auto it2 = it;
1755 int nVal = 0;
1756 while (it2 != mmap.end() && it2.key() == key) {
1757 ++nVal;
1758 ++it2;
1759 }
1760 Path newPath = mapPathFromOwner.withKey(key).withIndex(nVal-1);
1761 T &v = *it;
1762 v.updatePathFromOwner(newPath);
1763 if (valuePtr)
1764 *valuePtr = &v;
1765 return newPath;
1766}
1767
1768template<typename T>
1769Path appendUpdatableElementInQList(const Path &listPathFromOwner, QList<T> &list, const T &value,
1770 T **vPtr = nullptr)
1771{
1772 int idx = list.size();
1773 list.append(value);
1774 Path newPath = listPathFromOwner.withIndex(idx);
1775 T &targetV = list[idx];
1776 targetV.updatePathFromOwner(newPath);
1777 if (vPtr)
1778 *vPtr = &targetV;
1779 return newPath;
1780}
1781
1782template <typename T, typename K = QString>
1783void updatePathFromOwnerMultiMap(QMultiMap<K, T> &mmap, const Path &newPath)
1784{
1785 auto it = mmap.begin();
1786 auto end = mmap.end();
1787 index_type i = 0;
1788 K name;
1789 QList<T*> els;
1790 while (it != end) {
1791 if (i > 0 && name != it.key()) {
1792 Path pName = newPath.withKey(QString(name));
1793 for (T *el : els)
1794 el->updatePathFromOwner(pName.withIndex(--i));
1795 els.clear();
1796 els.append(&(*it));
1797 name = it.key();
1798 i = 1;
1799 } else {
1800 els.append(&(*it));
1801 name = it.key();
1802 ++i;
1803 }
1804 ++it;
1805 }
1806 Path pName = newPath.withKey(name);
1807 for (T *el : els)
1808 el->updatePathFromOwner(pName.withIndex(--i));
1809}
1810
1811template <typename T>
1812void updatePathFromOwnerQList(QList<T> &list, const Path &newPath)
1813{
1814 auto it = list.begin();
1815 auto end = list.end();
1816 index_type i = 0;
1817 while (it != end)
1818 (it++)->updatePathFromOwner(newPath.withIndex(i++));
1819}
1820
1821constexpr bool domTypeIsObjWrap(DomType k)
1822{
1823 switch (k) {
1824 case DomType::Binding:
1825 case DomType::EnumItem:
1827 case DomType::Export:
1828 case DomType::Id:
1829 case DomType::Import:
1834 case DomType::Pragma:
1836 case DomType::Version:
1837 case DomType::Comment:
1841 return true;
1842 default:
1843 return false;
1844 }
1845}
1846
1848{
1849 switch (k) {
1851 return true;
1852 default:
1853 return false;
1854 }
1855}
1856
1858{
1859 switch (k) {
1861 case DomType::QmlObject:
1864 case DomType::Reference:
1865 case DomType::Map:
1866 case DomType::List:
1867 case DomType::ListP:
1868 case DomType::EnumDecl:
1874 return true;
1875 default:
1876 return false;
1877 }
1878}
1879
1881{
1882 switch (k) {
1884
1885 case DomType::MockOwner:
1886
1889
1892 case DomType::JsFile:
1893 case DomType::QmlFile:
1896
1899
1900 case DomType::LoadInfo:
1902
1905 return true;
1906 default:
1907 return false;
1908 }
1909}
1910
1912{
1913 switch (k) {
1917 return true;
1918 default:
1919 return false;
1920 }
1921}
1922
1924{
1926}
1927
1928template<typename T>
1930 ConstantData::Options options) const
1931{
1932 using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
1933 if constexpr (
1934 std::is_base_of_v<
1935 QCborValue,
1936 BaseT> || std::is_base_of_v<QCborArray, BaseT> || std::is_base_of_v<QCborMap, BaseT>) {
1937 return DomItem(m_top, m_owner, m_ownerPath,
1938 ConstantData(pathFromOwner().withComponent(c), value, options));
1939 } else if constexpr (std::is_same_v<DomItem, BaseT>) {
1940 Q_UNUSED(options);
1941 return value;
1942 } else if constexpr (IsList<T>::value && !std::is_convertible_v<BaseT, QStringView>) {
1943 return subListItem(List::fromQList<typename BaseT::value_type>(
1944 pathFromOwner().withComponent(c), value,
1945 [options](const DomItem &list, const PathEls::PathComponent &p,
1946 const typename T::value_type &v) { return list.subValueItem(p, v, options); }));
1947 } else if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
1948 Q_UNUSED(options);
1949 return subOwnerItem(c, value);
1950 } else {
1951 return subDataItem(c, value, options);
1952 }
1953}
1954
1955template<typename T>
1957 ConstantData::Options options) const
1958{
1959 using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
1960 if constexpr (std::is_same_v<BaseT, ConstantData>) {
1961 return this->copy(value);
1962 } else if constexpr (std::is_base_of_v<QCborValue, BaseT>) {
1963 return DomItem(m_top, m_owner, m_ownerPath,
1964 ConstantData(pathFromOwner().withComponent(c), value, options));
1965 } else {
1966 return DomItem(
1967 m_top, m_owner, m_ownerPath,
1968 ConstantData(pathFromOwner().withComponent(c), QCborValue(value), options));
1969 }
1970}
1971
1972template <typename T>
1973bool DomItem::invokeVisitorOnValue(DirectVisitor visitor, const PathEls::PathComponent &c,
1974 const T &value, ConstantData::Options options) const
1975{
1976 auto lazyWrap = [this, &c, &value, options]() {
1977 return this->subValueItem<T>(c, value, options);
1978 };
1979 return visitor(c, lazyWrap);
1980}
1981
1982template<typename T>
1983DomItem DomItem::wrap(const PathEls::PathComponent &c, const T &obj) const
1984{
1985 using BaseT = std::decay_t<T>;
1986 if constexpr (std::is_same_v<QString, BaseT> || std::is_arithmetic_v<BaseT>) {
1987 return this->subDataItem(c, QCborValue(obj));
1988 } else if constexpr (std::is_same_v<SourceLocation, BaseT>) {
1989 return this->subDataItem(c, sourceLocationToQCborValue(obj));
1990 } else if constexpr (std::is_same_v<BaseT, Reference>) {
1991 Q_ASSERT_X(false, "DomItem::wrap",
1992 "wrapping a reference object, probably an error (wrap the target path instead)");
1993 return this->copy(obj);
1994 } else if constexpr (std::is_same_v<BaseT, ConstantData>) {
1995 return this->subDataItem(c, obj);
1996 } else if constexpr (std::is_same_v<BaseT, Map>) {
1997 return this->subMapItem(obj);
1998 } else if constexpr (std::is_same_v<BaseT, List>) {
1999 return this->subListItem(obj);
2000 } else if constexpr (std::is_base_of_v<ListPBase, BaseT>) {
2001 return this->subListItem(obj);
2002 } else if constexpr (std::is_same_v<BaseT, SimpleObjectWrap>) {
2003 return DomItem(m_top, m_owner, m_ownerPath, obj);
2004 } else if constexpr (IsDomObject<BaseT>::value) {
2005 if constexpr (domTypeIsObjWrap(BaseT::kindValue) || domTypeIsValueWrap(BaseT::kindValue)) {
2006 return DomItem(
2007 m_top, m_owner, m_ownerPath,
2008 SimpleObjectWrap::fromObjectRef(this->pathFromOwner().withComponent(c), obj));
2009 } else if constexpr (domTypeIsDomElement(BaseT::kindValue)) {
2010 return this->copy(&obj);
2011 } else {
2012 qCWarning(domLog) << "Unhandled object of type " << domTypeToString(BaseT::kindValue)
2013 << " in DomItem::wrap, not using a shared_ptr for an "
2014 << "OwningItem, or unexpected wrapped object?";
2015 return DomItem();
2016 }
2017 } else if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
2018 if constexpr (domTypeIsOwningItem(BaseT::element_type::kindValue)) {
2019 return this->subOwnerItem(c, obj);
2020 } else {
2021 Q_ASSERT_X(false, "DomItem::wrap", "shared_ptr with non owning item");
2022 return DomItem();
2023 }
2024 } else if constexpr (IsMultiMap<BaseT>::value) {
2025 if constexpr (std::is_same_v<typename BaseT::key_type, QString>) {
2026 return subMapItem(Map::fromMultiMapRef<typename BaseT::mapped_type>(
2027 pathFromOwner().withComponent(c), obj));
2028 } else {
2029 Q_ASSERT_X(false, "DomItem::wrap", "non string keys not supported (try .toString()?)");
2030 }
2031 } else if constexpr (IsMap<BaseT>::value) {
2032 if constexpr (std::is_same_v<typename BaseT::key_type, QString>) {
2033 return subMapItem(Map::fromMapRef<typename BaseT::mapped_type>(
2034 pathFromOwner().withComponent(c), obj,
2035 [](const DomItem &map, const PathEls::PathComponent &p,
2036 const typename BaseT::mapped_type &el) { return map.wrap(p, el); }));
2037 } else {
2038 Q_ASSERT_X(false, "DomItem::wrap", "non string keys not supported (try .toString()?)");
2039 }
2040 } else if constexpr (IsList<BaseT>::value) {
2041 if constexpr (IsDomObject<typename BaseT::value_type>::value) {
2042 return subListItem(List::fromQListRef<typename BaseT::value_type>(
2043 pathFromOwner().withComponent(c), obj,
2044 [](const DomItem &list, const PathEls::PathComponent &p,
2045 const typename BaseT::value_type &el) { return list.wrap(p, el); }));
2046 } else {
2047 Q_ASSERT_X(false, "DomItem::wrap", "Unsupported list type T");
2048 return DomItem();
2049 }
2050 } else {
2051 qCWarning(domLog) << "Cannot wrap " << typeid(BaseT).name();
2052 Q_ASSERT_X(false, "DomItem::wrap", "Do not know how to wrap type T");
2053 return DomItem();
2054 }
2055}
2056
2057template<typename T>
2058bool ListPT<T>::iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const
2059{
2060 index_type len = index_type(m_pList.size());
2061 for (index_type i = 0; i < len; ++i) {
2062 if (!v(PathEls::Index(i), [this, &self, i] { return this->index(self, i); }))
2063 return false;
2064 }
2065 return true;
2066}
2067
2068template<typename T>
2069DomItem ListPT<T>::index(const DomItem &self, index_type index) const
2070{
2071 if (index >= 0 && index < m_pList.size())
2072 return self.wrap(PathEls::Index(index), *static_cast<const T *>(m_pList.value(index)));
2073 return DomItem();
2074}
2075
2076// allow inlining of DomBase
2077inline DomKind DomBase::domKind() const
2078{
2079 return kind2domKind(kind());
2080}
2081
2082inline DomItem DomBase::containingObject(const DomItem &self) const
2083{
2084 Path path = pathFromOwner();
2085 DomItem base = self.owner();
2086 if (!path) {
2087 path = canonicalPath(self);
2088 base = self;
2089 }
2090 Source source = path.split();
2091 return base.path(source.pathToSource);
2092}
2093
2094inline quintptr DomBase::id() const
2095{
2096 return quintptr(this);
2097}
2098
2099inline QString DomBase::typeName() const
2100{
2101 return domTypeToString(kind());
2102}
2103
2104inline QList<QString> DomBase::fields(const DomItem &self) const
2105{
2106 QList<QString> res;
2107 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2108 if (c.kind() == Path::Kind::Field)
2109 res.append(c.name());
2110 return true;
2111 });
2112 return res;
2113}
2114
2115inline DomItem DomBase::field(const DomItem &self, QStringView name) const
2116{
2117 DomItem res;
2118 self.iterateDirectSubpaths(
2119 [&res, name](const PathEls::PathComponent &c, function_ref<DomItem()> obj) {
2120 if (c.kind() == Path::Kind::Field && c.checkName(name)) {
2121 res = obj();
2122 return false;
2123 }
2124 return true;
2125 });
2126 return res;
2127}
2128
2129inline index_type DomBase::indexes(const DomItem &self) const
2130{
2131 index_type res = 0;
2132 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2133 if (c.kind() == Path::Kind::Index) {
2134 index_type i = c.index() + 1;
2135 if (res < i)
2136 res = i;
2137 }
2138 return true;
2139 });
2140 return res;
2141}
2142
2143inline DomItem DomBase::index(const DomItem &self, qint64 index) const
2144{
2145 DomItem res;
2146 self.iterateDirectSubpaths(
2147 [&res, index](const PathEls::PathComponent &c, function_ref<DomItem()> obj) {
2148 if (c.kind() == Path::Kind::Index && c.index() == index) {
2149 res = obj();
2150 return false;
2151 }
2152 return true;
2153 });
2154 return res;
2155}
2156
2157inline QSet<QString> const DomBase::keys(const DomItem &self) const
2158{
2159 QSet<QString> res;
2160 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2161 if (c.kind() == Path::Kind::Key)
2162 res.insert(c.name());
2163 return true;
2164 });
2165 return res;
2166}
2167
2168inline DomItem DomBase::key(const DomItem &self, const QString &name) const
2169{
2170 DomItem res;
2171 self.iterateDirectSubpaths(
2172 [&res, name](const PathEls::PathComponent &c, function_ref<DomItem()> obj) {
2173 if (c.kind() == Path::Kind::Key && c.checkName(name)) {
2174 res = obj();
2175 return false;
2176 }
2177 return true;
2178 });
2179 return res;
2180}
2181
2182inline DomItem DomItem::subListItem(const List &list) const
2183{
2184 return DomItem(m_top, m_owner, m_ownerPath, list);
2185}
2186
2187inline DomItem DomItem::subMapItem(const Map &map) const
2188{
2189 return DomItem(m_top, m_owner, m_ownerPath, map);
2190}
2191
2192// TODO
2193// refactor this workaround. ExternalOWningItem is not recognized as an owning type
2194// in ownerAs.
2195std::shared_ptr<ExternalOwningItem> getFileItemOwner(const DomItem &fileItem);
2196
2197} // end namespace Dom
2198} // end namespace QQmlJS
2199
2200QT_END_NAMESPACE
2201#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
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
std::function< void(const Path &, const DomItem &, const DomItem &)> Callback
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
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
bool iterateErrors(function_ref< bool(const DomItem &, const ErrorMessage &)> visitor, bool iterate, Path inPath=Path()) const
DomItem pragmas() 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
bool writeOut(const QString &path, const LineWriterOptions &opt=LineWriterOptions(), FileWriter *fw=nullptr, WriteOutChecks extraChecks=WriteOutCheck::Default) 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 > &)
FileWriter::Status dump(const QString &path, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter, int indent=0, FileWriter *fw=nullptr) 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
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
bool invokeVisitorOnField(DirectVisitor visitor, QStringView f, T &obj) 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 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 invokeVisitorOnValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) 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 visitSubSymbolsNamed(const QString &name, function_ref< bool(const DomItem &)> visitor) const
DomItem wrap(const PathEls::PathComponent &c, const 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
friend QMLDOM_EXPORT bool operator==(const DomItem &, const DomItem &)
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
bool invokeVisitorOnLazyField(DirectVisitor visitor, QStringView f, F valueF, 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
DomItem subMapItem(const Map &map) const
bool invokeVisitorOnReference(DirectVisitor visitor, QStringView f, const Path &referencedObject) 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
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
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
bool invokeVisitorOnReferences(DirectVisitor visitor, QStringView f, const QList< Path > &paths) 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
std::shared_ptr< DomEnvironment > environment() 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)
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
std::function< bool(const DomItem &, function_ref< bool(index_type, function_ref< DomItem()>)>)> IteratorFunction
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)
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)
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)
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)
FileWriter::Status dump(const QString &path, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter, int indent=0, FileWriter *fw=nullptr)
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()
bool writeOut(const QString &path, const LineWriterOptions &opt=LineWriterOptions(), FileWriter *fw=nullptr)
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(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 writeOutSortedEnumerations(const QList< DomItem > &descs, OutWriter &ow) const
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)
Path addAnnotation(const QmlObject &annotation, QmlObject **aPtr=nullptr)
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 QStringList &keys) const
Path addPropertyDef(const PropertyDefinition &propertyDef, AddOption option, PropertyDefinition **pDef=nullptr)
void writeOutSortedAttributes(const DomItem &self, OutWriter &ow, const DomItem &component, const Attributes &attribs) const
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 writeOutAttributes(OutWriter &ow, const Attributes &attribs, const QString &code) const
MutableDomItem addMethod(MutableDomItem &self, const MethodInfo &functionDef, AddOption option)
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
QList< std::pair< SourceLocation, DomItem > > Attributes
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.
void addRegion(const Tree &fLoc, FileLocationRegion region, SourceLocation loc)
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)
Path insertUpdatableElementInMultiMap(const Path &mapPathFromOwner, QMultiMap< K, T > &mmap, K key, const T &value, AddOption option=AddOption::KeepExisting, T **valuePtr=nullptr)
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)
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)
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
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).
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
void updatePathFromOwnerMultiMap(QMultiMap< K, T > &mmap, const Path &newPath)
constexpr bool domTypeIsObjWrap(DomType k)
bool emptyChildrenVisitor(Path, const DomItem &, bool)
static ErrorGroups importErrors
std::variant< std::monostate, std::shared_ptr< DomEnvironment >, std::shared_ptr< DomUniverse > > TopT
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
#define QMLDOM_EXPORT
#define Q_SCRIPTELEMENT_EXIT_IF(check)
#define Q_SCRIPTELEMENT_DISABLE()
#define NewErrorGroup(name)
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)