Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
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"
20#include "qqmldom_utils_p.h"
21#include "qqmldomconstants_p.h"
23#include "qqmldompath_p.h"
26#include "qqmldomfilewriter_p.h"
27#include "qqmldomlinewriter_p.h"
29
30#include <QtCore/QMap>
31#include <QtCore/QMultiMap>
32#include <QtCore/QSet>
33#include <QtCore/QString>
34#include <QtCore/QStringView>
35#include <QtCore/QDebug>
36#include <QtCore/QDateTime>
37#include <QtCore/QMutex>
38#include <QtCore/QCborValue>
39#include <QtCore/QTimeZone>
40#include <QtQml/private/qqmljssourcelocation_p.h>
41#include <QtQmlCompiler/private/qqmljsscope_p.h>
42
43#include <memory>
44#include <typeinfo>
45#include <utility>
46#include <type_traits>
47#include <variant>
48#include <optional>
49#include <cstddef>
50
52
53namespace QQmlJS {
54// we didn't have enough 'O's to properly name everything...
55namespace Dom {
56
57class Path;
58
60
61constexpr bool domTypeIsObjWrap(DomType k);
62constexpr bool domTypeIsValueWrap(DomType k);
63constexpr bool domTypeIsDomElement(DomType);
64constexpr bool domTypeIsOwningItem(DomType);
66constexpr bool domTypeIsScriptElement(DomType);
70constexpr bool domTypeCanBeInline(DomType k)
71{
72 switch (k) {
73 case DomType::Empty:
74 case DomType::Map:
75 case DomType::List:
76 case DomType::ListP:
81 return true;
82 default:
83 return false;
84 }
85}
87
88QMLDOM_EXPORT QMap<DomType,QString> domTypeToStringMap();
90QMLDOM_EXPORT QMap<DomKind, QString> domKindToStringMap();
92
93inline bool noFilter(const DomItem &, const PathEls::PathComponent &, const DomItem &)
94{
95 return true;
96}
97
99// using DirectVisitor = function_ref<bool(Path, const DomItem &)>;
100
101namespace {
102template<typename T>
103struct IsMultiMap : std::false_type
104{
105};
106
107template<typename Key, typename T>
108struct IsMultiMap<QMultiMap<Key, T>> : std::true_type
109{
110};
111
112template<typename T>
113struct IsMap : std::false_type
114{
115};
116
117template<typename Key, typename T>
118struct IsMap<QMap<Key, T>> : std::true_type
119{
120};
121
122template<typename... Ts>
123using void_t = void;
124
125template<typename T, typename = void>
126struct IsDomObject : std::false_type
127{
128};
129
130template<typename T>
131struct IsDomObject<T, void_t<decltype(T::kindValue)>> : std::true_type
132{
133};
134
135template<typename T, typename = void>
136struct IsInlineDom : std::false_type
137{
138};
139
140template<typename T>
141struct IsInlineDom<T, void_t<decltype(T::kindValue)>>
142 : std::integral_constant<bool, domTypeCanBeInline(T::kindValue)>
143{
144};
145
146template<typename T>
147struct IsInlineDom<T *, void_t<decltype(T::kindValue)>> : std::true_type
148{
149};
150
151template<typename T>
152struct IsInlineDom<std::shared_ptr<T>, void_t<decltype(T::kindValue)>> : std::true_type
153{
154};
155
156template<typename T>
157struct IsSharedPointerToDomObject : std::false_type
158{
159};
160
161template<typename T>
162struct IsSharedPointerToDomObject<std::shared_ptr<T>> : IsDomObject<T>
163{
164};
165
166template<typename T, typename = void>
167struct IsList : std::false_type
168{
169};
170
171template<typename T>
172struct IsList<T, void_t<typename T::value_type>> : std::true_type
173{
174};
175
176}
177
178template<typename T>
180 int i;
181 T lp;
182
183 // TODO: these are extremely nasty. What is this int doing in here?
184 T *data() { return reinterpret_cast<T *>(this); }
185 const T *data() const { return reinterpret_cast<const T *>(this); }
186
188 SubclassStorage(T &&el) { el.moveTo(data()); }
189 SubclassStorage(const T *el) { el->copyTo(data()); }
193 {
194 data()->~T();
195 o.data()->copyTo(data());
196 return *this;
197 }
198 ~SubclassStorage() { data()->~T(); }
199};
200
202{
203public:
204 using FilterT = function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>;
205
206 virtual ~DomBase() = default;
207
208 DomBase *domBase() { return this; }
209 const DomBase *domBase() const { return this; }
210
211 // minimal overload set:
212 virtual DomType kind() const = 0;
213 virtual DomKind domKind() const;
214 virtual Path pathFromOwner(const DomItem &self) const = 0;
215 virtual Path canonicalPath(const DomItem &self) const = 0;
216 virtual bool
218 DirectVisitor visitor) const = 0; // iterates the *direct* subpaths, returns
219 // false if a quick end was requested
220
221 bool iterateDirectSubpathsConst(const DomItem &self, DirectVisitor)
222 const; // iterates the *direct* subpaths, returns false if a quick end was requested
223
224 virtual DomItem containingObject(
225 const DomItem &self) const; // the DomItem corresponding to the canonicalSource source
226 virtual void dump(const DomItem &, const Sink &sink, int indent, FilterT filter) const;
227 virtual quintptr id() const;
228 QString typeName() const;
229
230 virtual QList<QString> fields(const DomItem &self) const;
231 virtual DomItem field(const DomItem &self, QStringView name) const;
232
233 virtual index_type indexes(const DomItem &self) const;
234 virtual DomItem index(const DomItem &self, index_type index) const;
235
236 virtual QSet<QString> const keys(const DomItem &self) const;
237 virtual DomItem key(const DomItem &self, const QString &name) const;
238
239 virtual QString canonicalFilePath(const DomItem &self) const;
240
241 virtual void writeOut(const DomItem &self, OutWriter &lw) const;
242
243 virtual QCborValue value() const {
244 return QCborValue();
245 }
246};
247
249{
250 switch (k) {
251 case DomType::Empty:
252 return DomKind::Empty;
253 case DomType::List:
254 case DomType::ListP:
255 return DomKind::List;
256 case DomType::Map:
257 return DomKind::Map;
259 return DomKind::Value;
260 default:
261 return DomKind::Object;
262 }
263}
264
265class QMLDOM_EXPORT Empty final : public DomBase
266{
267public:
268 constexpr static DomType kindValue = DomType::Empty;
269 DomType kind() const override { return kindValue; }
270
271 Empty *operator->() { return this; }
272 const Empty *operator->() const { return this; }
273 Empty &operator*() { return *this; }
274 const Empty &operator*() const { return *this; }
275
277 quintptr id() const override { return ~quintptr(0); }
278 Path pathFromOwner(const DomItem &self) const override;
279 Path canonicalPath(const DomItem &self) const override;
280 DomItem containingObject(const DomItem &self) const override;
281 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
282 void dump(const DomItem &, const Sink &s, int indent,
283 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter)
284 const override;
285};
286
288protected:
289 DomElement& operator=(const DomElement&) = default;
290public:
291 DomElement(const Path &pathFromOwner = Path());
292 DomElement(const DomElement &o) = default;
293 Path pathFromOwner(const DomItem &self) const override;
294 Path pathFromOwner() const { return m_pathFromOwner; }
295 Path canonicalPath(const DomItem &self) const override;
296 DomItem containingObject(const DomItem &self) const override;
297 virtual void updatePathFromOwner(const Path &newPath);
298
299private:
300 Path m_pathFromOwner;
301};
302
303class QMLDOM_EXPORT Map final : public DomElement
304{
305public:
306 constexpr static DomType kindValue = DomType::Map;
307 DomType kind() const override { return kindValue; }
308
309 Map *operator->() { return this; }
310 const Map *operator->() const { return this; }
311 Map &operator*() { return *this; }
312 const Map &operator*() const { return *this; }
313
314 using LookupFunction = std::function<DomItem(const DomItem &, QString)>;
315 using Keys = std::function<QSet<QString>(const DomItem &)>;
316 Map(const Path &pathFromOwner, const LookupFunction &lookup,
317 const Keys &keys, const QString &targetType);
318 quintptr id() const override;
319 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
320 QSet<QString> const keys(const DomItem &self) const override;
321 DomItem key(const DomItem &self, const QString &name) const override;
322
323 template<typename T>
324 static Map fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
325 template<typename T>
326 static Map fromMultiMap(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
327 template<typename T>
328 static Map
329 fromMapRef(
330 const Path &pathFromOwner, const QMap<QString, T> &mmap,
331 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper);
332
333 template<typename T>
334 static Map fromFileRegionMap(
335 const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map);
336 template<typename T>
337 static Map fromFileRegionListMap(
338 const Path &pathFromOwner, const QMap<FileLocationRegion, QList<T>> &map);
339
340private:
341 template<typename MapT>
342 static QSet<QString> fileRegionKeysFromMap(const MapT &map);
343 LookupFunction m_lookup;
344 Keys m_keys;
345 QString m_targetType;
346};
347
348class QMLDOM_EXPORT List final : public DomElement
349{
350public:
351 constexpr static DomType kindValue = DomType::List;
352 DomType kind() const override { return kindValue; }
353
354 List *operator->() { return this; }
355 const List *operator->() const { return this; }
356 List &operator*() { return *this; }
357 const List &operator*() const { return *this; }
358
359 using LookupFunction = std::function<DomItem(const DomItem &, index_type)>;
360 using Length = std::function<index_type(const DomItem &)>;
362 std::function<bool(const DomItem &, function_ref<bool(index_type, function_ref<DomItem()>)>)>;
363
364 List(const Path &pathFromOwner, const LookupFunction &lookup, const Length &length,
365 const IteratorFunction &iterator, const QString &elType);
366 quintptr id() const override;
367 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
368 void
369 dump(const DomItem &, const Sink &s, int indent,
370 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>) const override;
371 index_type indexes(const DomItem &self) const override;
372 DomItem index(const DomItem &self, index_type index) const override;
373
374 template<typename T>
375 static List
376 fromQList(const Path &pathFromOwner, const QList<T> &list,
377 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
378 ListOptions options = ListOptions::Normal);
379 template<typename T>
380 static List
381 fromQListRef(const Path &pathFromOwner, const QList<T> &list,
382 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
383 ListOptions options = ListOptions::Normal);
384 void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
385 void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
386
387private:
388 LookupFunction m_lookup;
389 Length m_length;
390 IteratorFunction m_iterator;
391 QString m_elType;
392};
393
395{
396public:
397 constexpr static DomType kindValue = DomType::ListP;
398 DomType kind() const override { return kindValue; }
399
400 ListPBase(const Path &pathFromOwner, const QList<const void *> &pList, const QString &elType)
401 : DomElement(pathFromOwner), m_pList(pList), m_elType(elType)
402 {
403 }
404 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
405 virtual void copyTo(ListPBase *) const { Q_ASSERT(false); };
406 virtual void moveTo(ListPBase *) const { Q_ASSERT(false); };
407 quintptr id() const override { return quintptr(0); }
408 index_type indexes(const DomItem &) const override { return index_type(m_pList.size()); }
409 void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
410 void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
411
412protected:
413 QList<const void *> m_pList;
415};
416
417template<typename T>
418class ListPT final : public ListPBase
419{
420public:
421 constexpr static DomType kindValue = DomType::ListP;
422
423 ListPT(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
426 (elType.isEmpty() ? QLatin1String(typeid(T).name()) : elType))
427 {
428 static_assert(sizeof(ListPBase) == sizeof(ListPT),
429 "ListPT does not have the same size as ListPBase");
430 static_assert(alignof(ListPBase) == alignof(ListPT),
431 "ListPT does not have the same size as ListPBase");
432 m_pList.reserve(pList.size());
433 if (options == ListOptions::Normal) {
434 for (const void *p : pList)
436 } else if (options == ListOptions::Reverse) {
437 for (qsizetype i = pList.size(); i-- != 0;)
438 // probably writing in reverse and reading sequentially would be better
439 m_pList.append(pList.at(i));
440 } else {
441 Q_ASSERT(false);
442 }
443 }
444 void copyTo(ListPBase *t) const override { new (t) ListPT(*this); }
445 void moveTo(ListPBase *t) const override { new (t) ListPT(std::move(*this)); }
446 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
447
448 DomItem index(const DomItem &self, index_type index) const override;
449};
450
452{
453public:
454 constexpr static DomType kindValue = DomType::ListP;
455 template<typename T>
456 ListP(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
457 ListOptions options = ListOptions::Normal)
458 : list(ListPT<T>(pathFromOwner, pList, elType, options))
459 {
460 }
461 ListP() = delete;
462
463 ListPBase *operator->() { return list.data(); }
464 const ListPBase *operator->() const { return list.data(); }
465 ListPBase &operator*() { return *list.data(); }
466 const ListPBase &operator*() const { return *list.data(); }
467
468private:
469 SubclassStorage<ListPBase> list;
470};
471
473{
474public:
475 constexpr static DomType kindValue = DomType::ConstantData;
476 DomType kind() const override { return kindValue; }
477
478 enum class Options {
479 MapIsMap,
480 FirstMapIsFields
481 };
482
483 ConstantData *operator->() { return this; }
484 const ConstantData *operator->() const { return this; }
485 ConstantData &operator*() { return *this; }
486 const ConstantData &operator*() const { return *this; }
487
488 ConstantData(const Path &pathFromOwner, const QCborValue &value,
489 Options options = Options::MapIsMap);
490 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
491 quintptr id() const override;
492 DomKind domKind() const override;
493 QCborValue value() const override { return m_value; }
494 Options options() const { return m_options; }
495private:
496 QCborValue m_value;
498};
499
501{
502public:
503 constexpr static DomType kindValue = DomType::SimpleObjectWrap;
504 DomType kind() const final override { return m_kind; }
505
506 quintptr id() const final override { return m_id; }
507 DomKind domKind() const final override { return m_domKind; }
508
509 template <typename T>
510 T const *as() const
511 {
512 if (m_options & SimpleWrapOption::ValueType) {
513 if (m_value.metaType() == QMetaType::fromType<T>())
514 return static_cast<const T *>(m_value.constData());
515 return nullptr;
516 } else {
517 return m_value.value<const T *>();
518 }
519 }
520
522 virtual void copyTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
523 virtual void moveTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
524 bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
525 {
526 Q_ASSERT(false);
527 return true;
528 }
529
530protected:
531 friend class TestDomItem;
532 SimpleObjectWrapBase(const Path &pathFromOwner, const QVariant &value, quintptr idValue,
533 DomType kind = kindValue,
534 SimpleWrapOptions options = SimpleWrapOption::None)
535 : DomElement(pathFromOwner),
536 m_kind(kind),
537 m_domKind(kind2domKind(kind)),
538 m_value(value),
539 m_id(idValue),
540 m_options(options)
541 {
542 }
543
548 SimpleWrapOptions m_options;
549};
550
551template<typename T>
553{
554public:
556
557 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
558 {
559 return asT()->iterateDirectSubpaths(self, visitor);
560 }
561
562 void writeOut(const DomItem &self, OutWriter &lw) const override;
563
564 const T *asT() const
565 {
566 if constexpr (domTypeIsValueWrap(T::kindValue)) {
567 if (m_value.metaType() == QMetaType::fromType<T>())
568 return static_cast<const T *>(m_value.constData());
569 return nullptr;
570 } else if constexpr (domTypeIsObjWrap(T::kindValue)) {
571 return m_value.value<const T *>();
572 } else {
573 // need dependent static assert to not unconditially trigger
574 static_assert(!std::is_same_v<T, T>, "wrapping of unexpected type");
575 return nullptr; // necessary to avoid warnings on INTEGRITY
576 }
577 }
578
579 void copyTo(SimpleObjectWrapBase *target) const override
580 {
581 static_assert(sizeof(SimpleObjectWrapBase) == sizeof(SimpleObjectWrapT),
582 "Size mismatch in SimpleObjectWrapT");
583 static_assert(alignof(SimpleObjectWrapBase) == alignof(SimpleObjectWrapT),
584 "Size mismatch in SimpleObjectWrapT");
585 new (target) SimpleObjectWrapT(*this);
586 }
587
588 void moveTo(SimpleObjectWrapBase *target) const override
589 {
590 static_assert(sizeof(SimpleObjectWrapBase) == sizeof(SimpleObjectWrapT),
591 "Size mismatch in SimpleObjectWrapT");
592 static_assert(alignof(SimpleObjectWrapBase) == alignof(SimpleObjectWrapT),
593 "Size mismatch in SimpleObjectWrapT");
594 new (target) SimpleObjectWrapT(std::move(*this));
595 }
596
598 quintptr idValue, SimpleWrapOptions o)
600 {
602 }
603};
604
606{
607public:
608 constexpr static DomType kindValue = DomType::SimpleObjectWrap;
609
611 const SimpleObjectWrapBase *operator->() const { return wrap.data(); }
612 SimpleObjectWrapBase &operator*() { return *wrap.data(); }
613 const SimpleObjectWrapBase &operator*() const { return *wrap.data(); }
614
615 template<typename T>
616 static SimpleObjectWrap fromObjectRef(const Path &pathFromOwner, T &value)
617 {
618 return SimpleObjectWrap(pathFromOwner, value);
619 }
621
622private:
623 template<typename T>
624 SimpleObjectWrap(const Path &pathFromOwner, T &value)
625 {
626 using BaseT = std::decay_t<T>;
627 if constexpr (domTypeIsObjWrap(BaseT::kindValue)) {
628 new (wrap.data()) SimpleObjectWrapT<BaseT>(pathFromOwner, QVariant::fromValue(&value),
629 quintptr(&value), SimpleWrapOption::None);
630 } else if constexpr (domTypeIsValueWrap(BaseT::kindValue)) {
631 new (wrap.data()) SimpleObjectWrapT<BaseT>(pathFromOwner, QVariant::fromValue(value),
632 quintptr(0), SimpleWrapOption::ValueType);
633 } else {
634 qCWarning(domLog) << "Unexpected object to wrap in SimpleObjectWrap: "
635 << domTypeToString(BaseT::kindValue);
636 Q_ASSERT_X(false, "SimpleObjectWrap",
637 "simple wrap of unexpected object"); // allow? (mocks for testing,...)
638 new (wrap.data())
639 SimpleObjectWrapT<BaseT>(pathFromOwner, nullptr, 0, SimpleWrapOption::None);
640 }
641 }
642 SubclassStorage<SimpleObjectWrapBase> wrap;
643};
644
646{
648public:
649 constexpr static DomType kindValue = DomType::Reference;
650 DomType kind() const override { return kindValue; }
651
652 Reference *operator->() { return this; }
653 const Reference *operator->() const { return this; }
654 Reference &operator*() { return *this; }
655 const Reference &operator*() const { return *this; }
656
657 bool shouldCache() const;
658 Reference(const Path &referredObject = Path(), const Path &pathFromOwner = Path(),
659 const SourceLocation &loc = SourceLocation());
660 quintptr id() const override;
661 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
662 DomItem field(const DomItem &self, QStringView name) const override;
663 QList<QString> fields(const DomItem &self) const override;
664 index_type indexes(const DomItem &) const override { return 0; }
665 DomItem index(const DomItem &, index_type) const override;
666 QSet<QString> const keys(const DomItem &) const override { return {}; }
667 DomItem key(const DomItem &, const QString &) const override;
668
669 DomItem get(const DomItem &self, const ErrorHandler &h = nullptr,
670 QList<Path> *visitedRefs = nullptr) const;
671 QList<DomItem> getAll(const DomItem &self, const ErrorHandler &h = nullptr,
672 QList<Path> *visitedRefs = nullptr) const;
673
675};
676
677template<typename Info>
678class AttachedInfoT;
679class FileLocations;
680
689// TODO: do we need another marker struct like this one to differentiate expressions from
690// statements? This would allow to avoid mismatchs between script expressions and script statements,
691// using type-safety.
693{
694 template<typename T>
695 using PointerType = std::shared_ptr<T>;
696
699 const std::shared_ptr<AttachedInfoT<FileLocations>> &fileLocationOfOwner) = 0;
700
703
704private:
705 QQmlJSScope::ConstPtr m_scope;
706};
707
713{
714private:
715 template<typename... T>
716 using VariantOfPointer = std::variant<ScriptElement::PointerType<T>...>;
717
718 template<typename T, typename Variant>
719 struct TypeIsInVariant;
720
721 template<typename T, typename... Ts>
722 struct TypeIsInVariant<T, std::variant<Ts...>> : public std::disjunction<std::is_same<T, Ts>...>
723 {
724 };
725
726public:
733
734 template<typename T>
735 static ScriptElementVariant fromElement(const T &element)
736 {
737 static_assert(TypeIsInVariant<T, ScriptElementT>::value,
738 "Cannot construct ScriptElementVariant from T, as it is missing from the "
739 "ScriptElementT.");
741 p.m_data = element;
742 return p;
743 }
744
746
747 operator bool() const { return m_data.has_value(); }
748
749 template<typename F>
750 void visitConst(F &&visitor) const
751 {
752 if (m_data)
753 std::visit(std::forward<F>(visitor), *m_data);
754 }
755
756 template<typename F>
757 void visit(F &&visitor)
758 {
759 if (m_data)
760 std::visit(std::forward<F>(visitor), *m_data);
761 }
762 std::optional<ScriptElementT> data() { return m_data; }
763 void setData(const ScriptElementT &data) { m_data = data; }
764
765private:
766 std::optional<ScriptElementT> m_data;
767};
768
777{
778public:
780
782
783 DomBase *operator->() { return m_element.base().get(); }
784 const DomBase *operator->() const { return m_element.base().get(); }
785 DomBase &operator*() { return *m_element.base(); }
786 const DomBase &operator*() const { return *m_element.base(); }
787
788 ScriptElementVariant element() const { return m_element; }
789
790private:
791 ScriptElementVariant m_element;
792};
793
794// TODO: create more "groups" to simplify this variant? Maybe into Internal, ScriptExpression, ???
795using ElementT =
796 std::variant<
798 Empty,
799 List,
800 ListP,
801 Map,
802 Reference,
805 const AstComments *,
806 const AttachedInfo *,
807 const DomEnvironment *,
808 const DomUniverse *,
809 const EnumDecl *,
810 const ExternalItemInfoBase *,
811 const ExternalItemPairBase *,
812 const GlobalComponent *,
813 const GlobalScope *,
814 const JsFile *,
815 const JsResource *,
816 const LoadInfo *,
817 const MockObject *,
818 const MockOwner *,
819 const ModuleIndex *,
820 const ModuleScope *,
821 const QmlComponent *,
822 const QmlDirectory *,
823 const QmlFile *,
824 const QmlObject *,
825 const QmldirFile *,
826 const QmltypesComponent *,
827 const QmltypesFile *,
828 const ScriptExpression *
829 >;
830
831using TopT = std::variant<
832 std::monostate,
833 std::shared_ptr<DomEnvironment>,
834 std::shared_ptr<DomUniverse>>;
835
836using OwnerT = std::variant<
837 std::monostate,
838 std::shared_ptr<ModuleIndex>,
839 std::shared_ptr<MockOwner>,
840 std::shared_ptr<ExternalItemInfoBase>,
841 std::shared_ptr<ExternalItemPairBase>,
842 std::shared_ptr<QmlDirectory>,
843 std::shared_ptr<QmldirFile>,
844 std::shared_ptr<JsFile>,
845 std::shared_ptr<QmlFile>,
846 std::shared_ptr<QmltypesFile>,
847 std::shared_ptr<GlobalScope>,
848 std::shared_ptr<ScriptExpression>,
849 std::shared_ptr<AstComments>,
850 std::shared_ptr<LoadInfo>,
851 std::shared_ptr<AttachedInfo>,
852 std::shared_ptr<DomEnvironment>,
853 std::shared_ptr<DomUniverse>>;
854
855inline bool emptyChildrenVisitor(Path, const DomItem &, bool)
856{
857 return true;
858}
859
860class MutableDomItem;
861
863{
864public:
870
871 FileToLoad(const std::weak_ptr<DomEnvironment> &environment, const QString &canonicalPath,
872 const QString &logicalPath, const std::optional<InMemoryContents> &content);
873 FileToLoad() = default;
874
875 static FileToLoad fromMemory(const std::weak_ptr<DomEnvironment> &environment,
876 const QString &path, const QString &data);
877 static FileToLoad fromFileSystem(const std::weak_ptr<DomEnvironment> &environment,
878 const QString &canonicalPath);
879
880 std::weak_ptr<DomEnvironment> environment() const { return m_environment; }
881 QString canonicalPath() const { return m_canonicalPath; }
882 QString logicalPath() const { return m_logicalPath; }
883 std::optional<InMemoryContents> content() const { return m_content; }
884
885private:
886 std::weak_ptr<DomEnvironment> m_environment;
887 QString m_canonicalPath;
888 QString m_logicalPath;
889 std::optional<InMemoryContents> m_content;
890};
891
894public:
895 using Callback = function<void(const Path &, const DomItem &, const DomItem &)>;
896
898 using Visitor = function_ref<bool(const Path &, const DomItem &)>;
899 using ChildrenVisitor = function_ref<bool(const Path &, const DomItem &, bool)>;
900
905
906 enum class CopyOption { EnvConnected, EnvDisconnected };
907
908 template<typename F>
909 auto visitEl(F f) const
910 {
911 return std::visit(f, this->m_element);
912 }
913
914 explicit operator bool() const { return m_kind != DomType::Empty; }
916 return m_kind;
917 }
918 QString internalKindStr() const { return domTypeToString(internalKind()); }
920 {
921 if (m_kind == DomType::ConstantData)
922 return std::get<ConstantData>(m_element).domKind();
923 else
924 return kind2domKind(m_kind);
925 }
926
928
932 DomItem owner() const;
933 DomItem top() const;
938 DomItem goToFile(const QString &filePath) const;
939 DomItem goUp(int) const;
941
942 DomItem qmlObject(GoTo option = GoTo::Strict,
943 FilterUpOptions options = FilterUpOptions::ReturnOuter) const;
944 DomItem fileObject(GoTo option = GoTo::Strict) const;
945 DomItem rootQmlObject(GoTo option = GoTo::Strict) const;
947 DomItem component(GoTo option = GoTo::Strict) const;
948 DomItem scope(FilterUpOptions options = FilterUpOptions::ReturnOuter) const;
951
952 // convenience getters
953 DomItem get(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
954 QList<DomItem> getAll(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
955 bool isOwningItem() const { return domTypeIsOwningItem(internalKind()); }
956 bool isExternalItem() const { return domTypeIsExternalItem(internalKind()); }
957 bool isTopItem() const { return domTypeIsTopItem(internalKind()); }
958 bool isContainer() const { return domTypeIsContainer(internalKind()); }
959 bool isScope() const { return domTypeIsScope(internalKind()); }
960 bool isCanonicalChild(const DomItem &child) const;
961 bool hasAnnotations() const;
962 QString name() const { return field(Fields::name).value().toString(); }
963 DomItem pragmas() const { return field(Fields::pragmas); }
964 DomItem ids() const { return field(Fields::ids); }
965 QString idStr() const { return field(Fields::idStr).value().toString(); }
966 DomItem propertyInfos() const { return field(Fields::propertyInfos); }
968 QSet<QString> propertyInfoNames() const;
969 DomItem propertyDefs() const { return field(Fields::propertyDefs); }
970 DomItem bindings() const { return field(Fields::bindings); }
971 DomItem methods() const { return field(Fields::methods); }
972 DomItem enumerations() const { return field(Fields::enumerations); }
973 DomItem children() const { return field(Fields::children); }
974 DomItem child(index_type i) const { return field(Fields::children).index(i); }
976 {
977 if (hasAnnotations())
978 return field(Fields::annotations);
979 else
980 return DomItem();
981 }
982
983 bool resolve(const Path &path, Visitor visitor, const ErrorHandler &errorHandler,
984 ResolveOptions options = ResolveOption::None, const Path &fullPath = Path(),
985 QList<Path> *visitedRefs = nullptr) const;
986
990 DomItem operator[](const char16_t *component) const
991 {
992 return (*this)[QStringView(component)];
993 } // to avoid clash with stupid builtin ptrdiff_t[DomItem&], coming from C
994 DomItem operator[](index_type i) const { return index(i); }
995 DomItem operator[](int i) const { return index(i); }
996 index_type size() const { return indexes() + keys().size(); }
997 index_type length() const { return size(); }
998
999 DomItem path(const Path &p, const ErrorHandler &h = &defaultErrorHandler) const;
1000 DomItem path(const QString &p, const ErrorHandler &h = &defaultErrorHandler) const;
1001 DomItem path(QStringView p, const ErrorHandler &h = &defaultErrorHandler) const;
1002
1003 QList<QString> fields() const;
1005
1008 bool visitIndexes(function_ref<bool(const DomItem &)> visitor) const;
1009
1010 QSet<QString> keys() const;
1012 DomItem key(const QString &name) const;
1013 DomItem key(QStringView name) const { return key(name.toString()); }
1014 bool visitKeys(function_ref<bool(const QString &, const DomItem &)> visitor) const;
1015
1016 QList<DomItem> values() const;
1017 void writeOutPre(OutWriter &lw) const;
1018 void writeOut(OutWriter &lw) const;
1019 void writeOutPost(OutWriter &lw) const;
1020 bool writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks) const;
1021 bool writeOut(const QString &path, int nBackups = 2,
1022 const LineWriterOptions &opt = LineWriterOptions(), FileWriter *fw = nullptr,
1023 WriteOutChecks extraChecks = WriteOutCheck::Default) const;
1024
1025 bool visitTree(const Path &basePath, ChildrenVisitor visitor,
1026 VisitOptions options = VisitOption::Default,
1027 ChildrenVisitor openingVisitor = emptyChildrenVisitor,
1028 ChildrenVisitor closingVisitor = emptyChildrenVisitor,
1029 const FieldFilter &filter = FieldFilter::noFilter()) const;
1030 bool visitPrototypeChain(function_ref<bool(const DomItem &)> visitor,
1031 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
1032 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1033 QList<Path> *visitedRefs = nullptr) const;
1035 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
1036 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1037 QList<Path> *visitedRefs = nullptr) const;
1038 bool
1040 VisitPrototypesOptions options = VisitPrototypesOption::Normal,
1041 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1042 QList<Path> *visitedRefs = nullptr) const;
1043
1044 bool visitUp(function_ref<bool(const DomItem &)> visitor) const;
1046 function_ref<bool(const DomItem &)> visitor, LookupOptions = LookupOption::Normal,
1047 const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
1048 QList<Path> *visitedRefs = nullptr) const;
1050 const QString &name, function_ref<bool(const DomItem &)> visitor) const;
1052 const QString &symbolName, function_ref<bool(const DomItem &)> visitor,
1053 LookupOptions = LookupOption::Normal, const ErrorHandler &h = nullptr,
1054 QSet<quintptr> *visited = nullptr, QList<Path> *visitedRefs = nullptr) const;
1056 const QString &symbolName, function_ref<bool(const DomItem &)> visitor,
1057 LookupType type = LookupType::Symbol, LookupOptions = LookupOption::Normal,
1058 const ErrorHandler &errorHandler = nullptr, QSet<quintptr> *visited = nullptr,
1059 QList<Path> *visitedRefs = nullptr) const;
1061 const QString &name, function_ref<bool(const DomItem &)> visitor) const;
1063 const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
1064 QList<DomItem> lookup(
1065 const QString &symbolName, LookupType type = LookupType::Symbol,
1066 LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
1068 const QString &symbolName, LookupType type = LookupType::Symbol,
1069 LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
1070
1071 quintptr id() const;
1076 MutableDomItem makeCopy(CopyOption option = CopyOption::EnvConnected) const;
1077 bool commitToBase(const std::shared_ptr<DomEnvironment> &validPtr = nullptr) const;
1078 DomItem refreshed() const { return top().path(canonicalPath()); }
1080
1081 void dumpPtr(const Sink &sink) const;
1082 void dump(const Sink &, int indent = 0,
1083 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter =
1084 noFilter) const;
1087 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter,
1088 int nBackups = 2, int indent = 0, FileWriter *fw = nullptr) const;
1090
1091 // OwnigItem elements
1092 int derivedFrom() const;
1093 int revision() const;
1097
1098 void addError(ErrorMessage &&msg) const;
1100 void clearErrors(const ErrorGroups &groups = ErrorGroups({}), bool iterate = true) const;
1101 // return false if a quick exit was requested
1103 function_ref<bool (const DomItem &, const ErrorMessage &)> visitor, bool iterate,
1104 Path inPath = Path()) const;
1105
1106 bool iterateSubOwners(function_ref<bool(const DomItem &owner)> visitor) const;
1108
1109 template<typename T>
1110 DomItem subDataItem(const PathEls::PathComponent &c, const T &value,
1111 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1112 template<typename T>
1114 ConstantData::Options options = ConstantData::Options::MapIsMap) const
1115 {
1116 return subDataItem(PathEls::Field(f), value, options);
1117 }
1118 template<typename T>
1119 DomItem subValueItem(const PathEls::PathComponent &c, const T &value,
1120 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1121 template<typename T>
1122 bool dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value,
1123 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1124 template<typename T>
1126 ConstantData::Options options = ConstantData::Options::MapIsMap) const
1127 {
1128 return this->dvValue<T>(std::move(visitor), PathEls::Field(f), value, options);
1129 }
1130 template<typename F>
1131 bool dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c, F valueF,
1132 ConstantData::Options options = ConstantData::Options::MapIsMap) const;
1133 template<typename F>
1135 ConstantData::Options options = ConstantData::Options::MapIsMap) const
1136 {
1137 return this->dvValueLazy(std::move(visitor), PathEls::Field(f), valueF, options);
1138 }
1140 {
1141 return this->subDataItem(c, sourceLocationToQCborValue(loc));
1142 }
1143 // bool dvSubReference(DirectVisitor visitor, const PathEls::PathComponent &c, Path
1144 // referencedObject);
1145 DomItem subReferencesItem(const PathEls::PathComponent &c, const QList<Path> &paths) const;
1146 DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const;
1147 bool dvReference(DirectVisitor visitor, const PathEls::PathComponent &c, const Path &referencedObject) const
1148 {
1149 return dvItem(std::move(visitor), c, [c, this, referencedObject]() {
1150 return this->subReferenceItem(c, referencedObject);
1151 });
1152 }
1154 DirectVisitor visitor, const PathEls::PathComponent &c, const QList<Path> &paths) const
1155 {
1156 return dvItem(std::move(visitor), c, [c, this, paths]() {
1157 return this->subReferencesItem(c, paths);
1158 });
1159 }
1160 bool dvReferenceField(DirectVisitor visitor, QStringView f, const Path &referencedObject) const
1161 {
1162 return dvReference(std::move(visitor), PathEls::Field(f), referencedObject);
1163 }
1164 bool dvReferencesField(DirectVisitor visitor, QStringView f, const QList<Path> &paths) const
1165 {
1166 return dvReferences(std::move(visitor), PathEls::Field(f), paths);
1167 }
1169 {
1170 return visitor(c, it);
1171 }
1173 {
1174 return dvItem(std::move(visitor), PathEls::Field(f), it);
1175 }
1176 DomItem subListItem(const List &list) const;
1177 DomItem subMapItem(const Map &map) const;
1179 {
1180 return DomItem(m_top, m_owner, m_ownerPath, obj);
1181 }
1182
1184 {
1185 Q_ASSERT(obj);
1186 return DomItem(m_top, m_owner, m_ownerPath, ScriptElementDomWrapper(obj));
1187 }
1188
1189 template<typename Owner>
1191 {
1192 if constexpr (domTypeIsUnattachedOwningItem(Owner::element_type::kindValue))
1193 return DomItem(m_top, o, canonicalPath().appendComponent(c), o.get());
1194 else
1195 return DomItem(m_top, o, Path(), o.get());
1196 }
1197 template<typename T>
1198 DomItem wrap(const PathEls::PathComponent &c, const T &obj) const;
1199 template<typename T>
1201 {
1202 return wrap<T>(PathEls::Field(f), obj);
1203 }
1204 template<typename T>
1205 bool dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj) const;
1206 template<typename T>
1207 bool dvWrapField(DirectVisitor visitor, QStringView f, T &obj) const
1208 {
1209 return dvWrap<T>(std::move(visitor), PathEls::Field(f), obj);
1210 }
1211
1212 DomItem() = default;
1213 DomItem(const std::shared_ptr<DomEnvironment> &);
1214 DomItem(const std::shared_ptr<DomUniverse> &);
1215
1216 // TODO move to DomEnvironment?
1217 static DomItem fromCode(const QString &code, DomType fileType = DomType::QmlFile);
1218
1219 // --- start of potentially dangerous stuff, make private? ---
1220
1221 std::shared_ptr<DomTop> topPtr() const;
1222 std::shared_ptr<OwningItem> owningItemPtr() const;
1223
1224 // keep the DomItem around to ensure that it doesn't get deleted
1225 template<typename T, typename std::enable_if<std::is_base_of_v<DomBase, T>, bool>::type = true>
1226 T const *as() const
1227 {
1228 if (m_kind == T::kindValue) {
1229 if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
1230 return std::get<SimpleObjectWrap>(m_element)->as<T>();
1231 else
1232 return static_cast<T const *>(base());
1233 }
1234 return nullptr;
1235 }
1236
1237 template<typename T, typename std::enable_if<!std::is_base_of_v<DomBase, T>, bool>::type = true>
1238 T const *as() const
1239 {
1240 if (m_kind == T::kindValue) {
1241 Q_ASSERT(domTypeIsObjWrap(m_kind) || domTypeIsValueWrap(m_kind));
1242 return std::get<SimpleObjectWrap>(m_element)->as<T>();
1243 }
1244 return nullptr;
1245 }
1246
1247 template<typename T>
1248 std::shared_ptr<T> ownerAs() const;
1249
1250 template<typename Owner, typename T>
1251 DomItem copy(const Owner &owner, const Path &ownerPath, const T &base) const
1252 {
1253 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1254 static_assert(IsInlineDom<std::decay_t<T>>::value, "Expected an inline item or pointer");
1255 return DomItem(m_top, owner, ownerPath, base);
1256 }
1257
1258 template<typename Owner>
1259 DomItem copy(const Owner &owner, const Path &ownerPath) const
1260 {
1261 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1262 return DomItem(m_top, owner, ownerPath, owner.get());
1263 }
1264
1265 template<typename T>
1266 DomItem copy(const T &base) const
1267 {
1268 Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
1269 using BaseT = std::decay_t<T>;
1270 static_assert(!std::is_same_v<BaseT, ElementT>,
1271 "variant not supported, pass in the stored types");
1272 static_assert(IsInlineDom<BaseT>::value || std::is_same_v<BaseT, std::monostate>,
1273 "expected either a pointer or an inline item");
1274
1275 if constexpr (IsSharedPointerToDomObject<BaseT>::value)
1276 return DomItem(m_top, base, Path(), base.get());
1277 else if constexpr (IsInlineDom<BaseT>::value)
1278 return DomItem(m_top, m_owner, m_ownerPath, base);
1279
1280 Q_UNREACHABLE_RETURN(DomItem(m_top, m_owner, m_ownerPath, nullptr));
1281 }
1282
1283private:
1284 enum class WriteOutCheckResult { Success, Failed };
1285 WriteOutCheckResult performWriteOutChecks(const DomItem &, const DomItem &, OutWriter &, WriteOutChecks) const;
1286 const DomBase *base() const;
1287
1288 template<typename Env, typename Owner>
1289 DomItem(Env, Owner, Path, std::nullptr_t) : DomItem()
1290 {
1291 }
1292
1293 template<typename Env, typename Owner, typename T,
1294 typename = std::enable_if_t<IsInlineDom<std::decay_t<T>>::value>>
1295 DomItem(Env env, Owner owner, const Path &ownerPath, const T &el)
1296 : m_top(env), m_owner(owner), m_ownerPath(ownerPath), m_element(el)
1297 {
1298 using BaseT = std::decay_t<T>;
1299 if constexpr (std::is_pointer_v<BaseT>) {
1300 if (!el || el->kind() == DomType::Empty) { // avoid null ptr, and allow only a
1301 // single kind of Empty
1302 m_kind = DomType::Empty;
1303 m_top = std::monostate();
1304 m_owner = std::monostate();
1305 m_ownerPath = Path();
1306 m_element = Empty();
1307 } else {
1308 using DomT = std::remove_pointer_t<BaseT>;
1309 m_element = el;
1310 m_kind = DomT::kindValue;
1311 }
1312 } else {
1313 static_assert(!std::is_same_v<BaseT, ElementT>,
1314 "variant not supported, pass in the internal type");
1315 m_kind = el->kind();
1316 }
1317 }
1318 friend class DomBase;
1319 friend class DomElement;
1320 friend class Map;
1321 friend class List;
1322 friend class QmlObject;
1323 friend class DomUniverse;
1324 friend class DomEnvironment;
1326 friend class ConstantData;
1327 friend class MutableDomItem;
1328 friend class ScriptExpression;
1329 friend class AstComments;
1330 friend class AttachedInfo;
1331 friend class TestDomItem;
1332 friend QMLDOM_EXPORT bool operator==(const DomItem &, const DomItem &);
1333 DomType m_kind = DomType::Empty;
1334 TopT m_top;
1335 OwnerT m_owner;
1336 Path m_ownerPath;
1337 ElementT m_element = Empty();
1338};
1339
1340QMLDOM_EXPORT bool operator==(const DomItem &o1, const DomItem &o2);
1341
1342inline bool operator!=(const DomItem &o1, const DomItem &o2)
1343{
1344 return !(o1 == o2);
1345}
1346
1347template<typename T>
1348static DomItem keyMultiMapHelper(const DomItem &self, const QString &key,
1349 const QMultiMap<QString, T> &mmap)
1350{
1351 auto it = mmap.find(key);
1352 auto end = mmap.cend();
1353 if (it == end)
1354 return DomItem();
1355 else {
1356 // special case single element (++it == end || it.key() != key)?
1357 QList<const T *> values;
1358 while (it != end && it.key() == key)
1359 values.append(&(*it++));
1360 ListP ll(self.pathFromOwner().appendComponent(PathEls::Key(key)), values, QString(),
1362 return self.copy(ll);
1363 }
1364}
1365
1366template<typename T>
1367Map Map::fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap)
1368{
1369 return Map(
1371 [&mmap](const DomItem &self, const QString &key) {
1372 return keyMultiMapHelper(self, key, mmap);
1373 },
1374 [&mmap](const DomItem &) { return QSet<QString>(mmap.keyBegin(), mmap.keyEnd()); },
1375 QLatin1String(typeid(T).name()));
1376}
1377
1378template<typename T>
1379Map Map::fromMapRef(
1380 const Path &pathFromOwner, const QMap<QString, T> &map,
1381 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper)
1382{
1383 return Map(
1385 [&map, elWrapper](const DomItem &self, const QString &key) {
1386 const auto it = map.constFind(key);
1387 if (it == map.constEnd())
1388 return DomItem();
1389 return elWrapper(self, PathEls::Key(key), it.value());
1390 },
1391 [&map](const DomItem &) { return QSet<QString>(map.keyBegin(), map.keyEnd()); },
1392 QLatin1String(typeid(T).name()));
1393}
1394
1395template<typename MapT>
1396QSet<QString> Map::fileRegionKeysFromMap(const MapT &map)
1397{
1398 QSet<QString> keys;
1399 std::transform(map.keyBegin(), map.keyEnd(), std::inserter(keys, keys.begin()), fileLocationRegionName);
1400 return keys;
1401}
1402
1403template<typename T>
1404Map Map::fromFileRegionMap(const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map)
1405{
1406 auto result = Map(
1408 [&map](const DomItem &mapItem, const QString &key) -> DomItem {
1410 if (it == map.constEnd())
1411 return {};
1412
1413 return mapItem.wrap(PathEls::Key(key), *it);
1414 },
1415 [&map](const DomItem &) { return fileRegionKeysFromMap(map); },
1416 QString::fromLatin1(typeid(T).name()));
1417 return result;
1418}
1419
1420template<typename T>
1421Map Map::fromFileRegionListMap(const Path &pathFromOwner,
1422 const QMap<FileLocationRegion, QList<T>> &map)
1423{
1424 using namespace Qt::StringLiterals;
1425 auto result = Map(
1427 [&map](const DomItem &mapItem, const QString &key) -> DomItem {
1428 const QList<SourceLocation> locations = map.value(fileLocationRegionValue(key));
1429 if (locations.empty())
1430 return {};
1431
1432 auto list = List::fromQList<SourceLocation>(
1433 mapItem.pathFromOwner(), locations,
1434 [](const DomItem &self, const PathEls::PathComponent &path,
1435 const SourceLocation &location) {
1436 return self.subLocationItem(path, location);
1437 });
1438 return mapItem.subListItem(list);
1439 },
1440 [&map](const DomItem &) { return fileRegionKeysFromMap(map); },
1441 u"QList<%1>"_s.arg(QString::fromLatin1(typeid(T).name())));
1442 return result;
1443}
1444
1445template<typename T>
1447 const Path &pathFromOwner, const QList<T> &list,
1448 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
1449 ListOptions options)
1450{
1451 index_type len = list.size();
1452 if (options == ListOptions::Reverse) {
1453 return List(
1455 [list, elWrapper](const DomItem &self, index_type i) mutable {
1456 if (i < 0 || i >= list.size())
1457 return DomItem();
1458 return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
1459 },
1460 [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
1461 } else {
1462 return List(
1464 [list, elWrapper](const DomItem &self, index_type i) mutable {
1465 if (i < 0 || i >= list.size())
1466 return DomItem();
1467 return elWrapper(self, PathEls::Index(i), list[i]);
1468 },
1469 [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
1470 }
1471}
1472
1473template<typename T>
1475 const Path &pathFromOwner, const QList<T> &list,
1476 const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
1477 ListOptions options)
1478{
1479 if (options == ListOptions::Reverse) {
1480 return List(
1482 [&list, elWrapper](const DomItem &self, index_type i) {
1483 if (i < 0 || i >= list.size())
1484 return DomItem();
1485 return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
1486 },
1487 [&list](const DomItem &) { return list.size(); }, nullptr,
1488 QLatin1String(typeid(T).name()));
1489 } else {
1490 return List(
1492 [&list, elWrapper](const DomItem &self, index_type i) {
1493 if (i < 0 || i >= list.size())
1494 return DomItem();
1495 return elWrapper(self, PathEls::Index(i), list[i]);
1496 },
1497 [&list](const DomItem &) { return list.size(); }, nullptr,
1498 QLatin1String(typeid(T).name()));
1499 }
1500}
1501
1503protected:
1504 virtual std::shared_ptr<OwningItem> doCopy(const DomItem &self) const = 0;
1505
1506public:
1508 OwningItem(int derivedFrom=0);
1509 OwningItem(int derivedFrom, const QDateTime &lastDataUpdateAt);
1510 OwningItem(const OwningItem &&) = delete;
1511 OwningItem &operator=(const OwningItem &&) = delete;
1512 static int nextRevision();
1513
1514 Path canonicalPath(const DomItem &self) const override = 0;
1515
1516 bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
1517 std::shared_ptr<OwningItem> makeCopy(const DomItem &self) const { return doCopy(self); }
1518 Path pathFromOwner() const { return Path(); }
1519 Path pathFromOwner(const DomItem &) const override final { return Path(); }
1520 DomItem containingObject(const DomItem &self) const override;
1521 int derivedFrom() const;
1522 virtual int revision() const;
1523
1526 virtual void refreshedDataAt(QDateTime tNew);
1527
1528 // explicit freeze handling needed?
1529 virtual bool frozen() const;
1530 virtual bool freeze();
1532
1533 virtual void addError(const DomItem &self, ErrorMessage &&msg);
1536 // return false if a quick exit was requested
1538 const DomItem &self,
1539 function_ref<bool(const DomItem &source, const ErrorMessage &msg)> visitor,
1540 const Path &inPath = Path());
1541 QMultiMap<Path, ErrorMessage> localErrors() const {
1542 QMutexLocker l(mutex());
1543 return m_errors;
1544 }
1545
1546 virtual bool iterateSubOwners(const DomItem &self, function_ref<bool(const DomItem &owner)> visitor);
1547
1548 QBasicMutex *mutex() const { return &m_mutex; }
1549private:
1550 mutable QBasicMutex m_mutex;
1551 int m_derivedFrom;
1552 int m_revision;
1553 QDateTime m_createdAt;
1554 QDateTime m_lastDataUpdateAt;
1555 QDateTime m_frozenAt;
1556 QMultiMap<Path, ErrorMessage> m_errors;
1557 QMap<ErrorMessage, quint32> m_errorsCounts;
1558};
1559
1560template<typename T>
1561std::shared_ptr<T> DomItem::ownerAs() const
1562{
1563 if constexpr (domTypeIsOwningItem(T::kindValue)) {
1564 if (!std::holds_alternative<std::monostate>(m_owner)) {
1565 if constexpr (T::kindValue == DomType::AttachedInfo) {
1566 if (std::holds_alternative<std::shared_ptr<AttachedInfo>>(m_owner))
1567 return std::static_pointer_cast<T>(
1568 std::get<std::shared_ptr<AttachedInfo>>(m_owner));
1569 } else if constexpr (T::kindValue == DomType::ExternalItemInfo) {
1570 if (std::holds_alternative<std::shared_ptr<ExternalItemInfoBase>>(m_owner))
1571 return std::static_pointer_cast<T>(
1572 std::get<std::shared_ptr<ExternalItemInfoBase>>(m_owner));
1573 } else if constexpr (T::kindValue == DomType::ExternalItemPair) {
1574 if (std::holds_alternative<std::shared_ptr<ExternalItemPairBase>>(m_owner))
1575 return std::static_pointer_cast<T>(
1576 std::get<std::shared_ptr<ExternalItemPairBase>>(m_owner));
1577 } else {
1578 if (std::holds_alternative<std::shared_ptr<T>>(m_owner)) {
1579 return std::get<std::shared_ptr<T>>(m_owner);
1580 }
1581 }
1582 }
1583 } else {
1584 Q_ASSERT_X(false, "DomItem::ownerAs", "unexpected non owning value in ownerAs");
1585 }
1586 return std::shared_ptr<T> {};
1587}
1588
1589template<int I>
1590struct rank : rank<I - 1>
1591{
1592 static_assert(I > 0, "");
1593};
1594template<>
1595struct rank<0>
1596{
1597};
1598
1599template<typename T>
1600auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw, rank<1>)
1601 -> decltype(t.writeOut(self, lw))
1602{
1603 t.writeOut(self, lw);
1604}
1605
1606template<typename T>
1607auto writeOutWrap(const T &, const DomItem &, OutWriter &, rank<0>) -> void
1608{
1609 qCWarning(writeOutLog) << "Ignoring writeout to wrapped object not supporting it ("
1610 << typeid(T).name();
1611}
1612template<typename T>
1613auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw) -> void
1614{
1615 writeOutWrap(t, self, lw, rank<1>());
1616}
1617
1618template<typename T>
1620{
1621 writeOutWrap<T>(*asT(), self, lw);
1622}
1623
1625
1627public:
1629
1630 explicit operator bool() const
1631 {
1632 return bool(m_owner);
1633 } // this is weaker than item(), but normally correct
1634 DomType internalKind() { return item().internalKind(); }
1635 QString internalKindStr() { return domTypeToString(internalKind()); }
1636 DomKind domKind() { return kind2domKind(internalKind()); }
1637
1638 Path canonicalPath() const { return m_owner.canonicalPath().path(m_pathFromOwner); }
1640 {
1641 if (m_pathFromOwner)
1642 return MutableDomItem(m_owner, m_pathFromOwner.split().pathToSource);
1643 else {
1644 DomItem cObj = m_owner.containingObject();
1645 return MutableDomItem(cObj.owner(), (domTypeIsOwningItem(cObj.internalKind()) ? Path() :cObj.pathFromOwner()));
1646 }
1647 }
1648
1650 {
1651 if (m_pathFromOwner)
1652 return MutableDomItem(m_owner, m_pathFromOwner.dropTail());
1653 else {
1654 return MutableDomItem(item().container());
1655 }
1656 }
1657
1659 FilterUpOptions fOptions = FilterUpOptions::ReturnOuter)
1660 {
1661 return MutableDomItem(item().qmlObject(option, fOptions));
1662 }
1664 {
1665 return MutableDomItem(item().fileObject(option));
1666 }
1668 {
1669 return MutableDomItem(item().rootQmlObject(option));
1670 }
1673
1675 {
1676 return MutableDomItem { item().component(option) };
1677 }
1678 MutableDomItem owner() { return MutableDomItem(m_owner); }
1682 Path pathFromOwner() { return m_pathFromOwner; }
1690 {
1691 // to avoid clash with stupid builtin ptrdiff_t[MutableDomItem&], coming from C
1693 }
1695
1697 MutableDomItem path(const QString &p) { return path(Path::fromString(p)); }
1698 MutableDomItem path(QStringView p) { return path(Path::fromString(p)); }
1699
1700 QList<QString> const fields() { return item().fields(); }
1702 index_type indexes() { return item().indexes(); }
1704
1705 QSet<QString> const keys() { return item().keys(); }
1707 MutableDomItem key(QStringView name) { return key(name.toString()); }
1708
1709 void
1710 dump(const Sink &s, int indent = 0,
1711 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter)
1712 {
1713 item().dump(s, indent, filter);
1714 }
1717 function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter,
1718 int nBackups = 2, int indent = 0, FileWriter *fw = nullptr)
1719 {
1720 return item().dump(path, filter, nBackups, indent, fw);
1721 }
1722 void writeOut(OutWriter &lw) { return item().writeOut(lw); }
1723 bool writeOut(const QString &path, int nBackups = 2,
1724 const LineWriterOptions &opt = LineWriterOptions(), FileWriter *fw = nullptr)
1725 {
1726 return item().writeOut(path, nBackups, opt, fw);
1727 }
1728
1730 MutableDomItem makeCopy(CopyOption option = CopyOption::EnvConnected)
1731 {
1732 return item().makeCopy(option);
1733 }
1734 bool commitToBase(const std::shared_ptr<DomEnvironment> &validEnvPtr = nullptr)
1735 {
1736 return item().commitToBase(validEnvPtr);
1737 }
1738 QString canonicalFilePath() const { return item().canonicalFilePath(); }
1739
1741
1742 QCborValue value() { return item().value(); }
1743
1744 QString toString() { return item().toString(); }
1745
1746 // convenience getters
1747 QString name() { return item().name(); }
1748 MutableDomItem pragmas() { return item().pragmas(); }
1749 MutableDomItem ids() { return MutableDomItem::item().ids(); }
1750 QString idStr() { return item().idStr(); }
1757
1758 // // OwnigItem elements
1759 int derivedFrom() { return m_owner.derivedFrom(); }
1760 int revision() { return m_owner.revision(); }
1761 QDateTime createdAt() { return m_owner.createdAt(); }
1762 QDateTime frozenAt() { return m_owner.frozenAt(); }
1763 QDateTime lastDataUpdateAt() { return m_owner.lastDataUpdateAt(); }
1764
1765 void addError(ErrorMessage &&msg) { item().addError(std::move(msg)); }
1767
1768 // convenience setters
1769 MutableDomItem addPrototypePath(const Path &prototypePath);
1770 MutableDomItem setNextScopePath(const Path &nextScopePath);
1771 MutableDomItem setPropertyDefs(QMultiMap<QString, PropertyDefinition> propertyDefs);
1772 MutableDomItem setBindings(QMultiMap<QString, Binding> bindings);
1773 MutableDomItem setMethods(QMultiMap<QString, MethodInfo> functionDefs);
1774 MutableDomItem setChildren(const QList<QmlObject> &children);
1775 MutableDomItem setAnnotations(const QList<QmlObject> &annotations);
1776 MutableDomItem setScript(const std::shared_ptr<ScriptExpression> &exp);
1779 AddOption option = AddOption::Overwrite);
1780 MutableDomItem addBinding(Binding binding, AddOption option = AddOption::Overwrite);
1782 const MethodInfo &functionDef, AddOption option = AddOption::Overwrite);
1789
1790 MutableDomItem() = default;
1791 MutableDomItem(const DomItem &owner, const Path &pathFromOwner):
1792 m_owner(owner), m_pathFromOwner(pathFromOwner)
1793 {}
1795 m_owner(item.owner()), m_pathFromOwner(item.pathFromOwner())
1796 {}
1797
1798 std::shared_ptr<DomTop> topPtr() { return m_owner.topPtr(); }
1799 std::shared_ptr<OwningItem> owningItemPtr() { return m_owner.owningItemPtr(); }
1800
1801 template<typename T>
1802 T const *as()
1803 {
1804 return item().as<T>();
1805 }
1806
1807 template <typename T>
1809 Q_ASSERT(!m_owner || !m_owner.owningItemPtr()->frozen());
1810
1811 DomItem self = item();
1812 if (self.m_kind != T::kindValue)
1813 return nullptr;
1814
1815 const T *t = nullptr;
1816 if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
1817 t = static_cast<const SimpleObjectWrapBase *>(self.base())->as<T>();
1818 else if constexpr (std::is_base_of<DomBase, T>::value)
1819 t = static_cast<const T *>(self.base());
1820 else
1821 Q_UNREACHABLE_RETURN(nullptr);
1822
1823 // Nasty. But since ElementT has to store the const pointers, we allow it in this one place.
1824 return const_cast<T *>(t);
1825 }
1826
1827 template<typename T>
1828 std::shared_ptr<T> ownerAs() const
1829 {
1830 return m_owner.ownerAs<T>();
1831 }
1832 // it is dangerous to assume it stays valid when updates are preformed...
1833 DomItem item() const { return m_owner.path(m_pathFromOwner); }
1834
1835 friend bool operator==(const MutableDomItem &o1, const MutableDomItem &o2)
1836 {
1837 return o1.m_owner == o2.m_owner && o1.m_pathFromOwner == o2.m_pathFromOwner;
1838 }
1839 friend bool operator!=(const MutableDomItem &o1, const MutableDomItem &o2)
1840 {
1841 return !(o1 == o2);
1842 }
1843
1844private:
1845 DomItem m_owner;
1846 Path m_pathFromOwner;
1847};
1848
1850
1851template<typename K, typename T>
1852Path insertUpdatableElementInMultiMap(const Path &mapPathFromOwner, QMultiMap<K, T> &mmap, K key,
1854 T **valuePtr = nullptr)
1855{
1857 auto it = mmap.find(key);
1858 if (it != mmap.end()) {
1859 T &v = *it;
1860 v = value;
1861 if (++it != mmap.end() && it.key() == key) {
1862 qWarning() << " requested overwrite of " << key
1863 << " that contains aleready multiple entries in" << mapPathFromOwner;
1864 }
1865 Path newPath = mapPathFromOwner.key(key).index(0);
1866 v.updatePathFromOwner(newPath);
1867 if (valuePtr)
1868 *valuePtr = &v;
1869 return newPath;
1870 }
1871 }
1872 mmap.insert(key, value);
1873 auto it = mmap.find(key);
1874 auto it2 = it;
1875 int nVal = 0;
1876 while (it2 != mmap.end() && it2.key() == key) {
1877 ++nVal;
1878 ++it2;
1879 }
1880 Path newPath = mapPathFromOwner.key(key).index(nVal-1);
1881 T &v = *it;
1882 v.updatePathFromOwner(newPath);
1883 if (valuePtr)
1884 *valuePtr = &v;
1885 return newPath;
1886}
1887
1888template<typename T>
1889Path appendUpdatableElementInQList(const Path &listPathFromOwner, QList<T> &list, const T &value,
1890 T **vPtr = nullptr)
1891{
1892 int idx = list.size();
1893 list.append(value);
1894 Path newPath = listPathFromOwner.index(idx);
1895 T &targetV = list[idx];
1896 targetV.updatePathFromOwner(newPath);
1897 if (vPtr)
1898 *vPtr = &targetV;
1899 return newPath;
1900}
1901
1902template <typename T, typename K = QString>
1903void updatePathFromOwnerMultiMap(QMultiMap<K, T> &mmap, const Path &newPath)
1904{
1905 auto it = mmap.begin();
1906 auto end = mmap.end();
1907 index_type i = 0;
1908 K name;
1909 QList<T*> els;
1910 while (it != end) {
1911 if (i > 0 && name != it.key()) {
1912 Path pName = newPath.key(QString(name));
1913 for (T *el : els)
1914 el->updatePathFromOwner(pName.index(--i));
1915 els.clear();
1916 els.append(&(*it));
1917 name = it.key();
1918 i = 1;
1919 } else {
1920 els.append(&(*it));
1921 name = it.key();
1922 ++i;
1923 }
1924 ++it;
1925 }
1926 Path pName = newPath.key(name);
1927 for (T *el : els)
1928 el->updatePathFromOwner(pName.index(--i));
1929}
1930
1931template <typename T>
1932void updatePathFromOwnerQList(QList<T> &list, const Path &newPath)
1933{
1934 auto it = list.begin();
1935 auto end = list.end();
1936 index_type i = 0;
1937 while (it != end)
1938 (it++)->updatePathFromOwner(newPath.index(i++));
1939}
1940
1941constexpr bool domTypeIsObjWrap(DomType k)
1942{
1943 switch (k) {
1944 case DomType::Binding:
1945 case DomType::EnumItem:
1947 case DomType::Export:
1948 case DomType::Id:
1949 case DomType::Import:
1954 case DomType::Pragma:
1956 case DomType::Version:
1957 case DomType::Comment:
1962 return true;
1963 default:
1964 return false;
1965 }
1966}
1967
1969{
1970 switch (k) {
1972 return true;
1973 default:
1974 return false;
1975 }
1976}
1977
1979{
1980 switch (k) {
1982 case DomType::QmlObject:
1985 case DomType::Reference:
1986 case DomType::Map:
1987 case DomType::List:
1988 case DomType::ListP:
1989 case DomType::EnumDecl:
1995 return true;
1996 default:
1997 return false;
1998 }
1999}
2000
2002{
2003 switch (k) {
2005
2006 case DomType::MockOwner:
2007
2010
2013 case DomType::JsFile:
2014 case DomType::QmlFile:
2017
2020
2021 case DomType::LoadInfo:
2023
2026 return true;
2027 default:
2028 return false;
2029 }
2030}
2031
2033{
2034 switch (k) {
2038 return true;
2039 default:
2040 return false;
2041 }
2042}
2043
2045{
2047}
2048
2049template<typename T>
2051 ConstantData::Options options) const
2052{
2053 using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
2054 if constexpr (
2055 std::is_base_of_v<
2056 QCborValue,
2057 BaseT> || std::is_base_of_v<QCborArray, BaseT> || std::is_base_of_v<QCborMap, BaseT>) {
2058 return DomItem(m_top, m_owner, m_ownerPath,
2059 ConstantData(pathFromOwner().appendComponent(c), value, options));
2060 } else if constexpr (std::is_same_v<DomItem, BaseT>) {
2061 Q_UNUSED(options);
2062 return value;
2063 } else if constexpr (IsList<T>::value && !std::is_convertible_v<BaseT, QStringView>) {
2064 return subListItem(List::fromQList<typename BaseT::value_type>(
2065 pathFromOwner().appendComponent(c), value,
2066 [options](const DomItem &list, const PathEls::PathComponent &p,
2067 const typename T::value_type &v) { return list.subValueItem(p, v, options); }));
2068 } else if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
2069 Q_UNUSED(options);
2070 return subOwnerItem(c, value);
2071 } else {
2072 return subDataItem(c, value, options);
2073 }
2074}
2075
2076template<typename T>
2078 ConstantData::Options options) const
2079{
2080 using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
2081 if constexpr (std::is_same_v<BaseT, ConstantData>) {
2082 return this->copy(value);
2083 } else if constexpr (std::is_base_of_v<QCborValue, BaseT>) {
2084 return DomItem(m_top, m_owner, m_ownerPath,
2085 ConstantData(pathFromOwner().appendComponent(c), value, options));
2086 } else {
2087 return DomItem(
2088 m_top, m_owner, m_ownerPath,
2089 ConstantData(pathFromOwner().appendComponent(c), QCborValue(value), options));
2090 }
2091}
2092
2093template<typename T>
2095 ConstantData::Options options) const
2096{
2097 auto lazyWrap = [this, &c, &value, options]() {
2098 return this->subValueItem<T>(c, value, options);
2099 };
2100 return visitor(c, lazyWrap);
2101}
2102
2103template<typename F>
2105 ConstantData::Options options) const
2106{
2107 auto lazyWrap = [this, &c, &valueF, options]() {
2108 return this->subValueItem<decltype(valueF())>(c, valueF(), options);
2109 };
2110 return visitor(c, lazyWrap);
2111}
2112
2113template<typename T>
2115{
2116 using BaseT = std::decay_t<T>;
2117 if constexpr (std::is_same_v<QString, BaseT> || std::is_arithmetic_v<BaseT>) {
2118 return this->subDataItem(c, QCborValue(obj));
2119 } else if constexpr (std::is_same_v<SourceLocation, BaseT>) {
2120 return this->subLocationItem(c, obj);
2121 } else if constexpr (std::is_same_v<BaseT, Reference>) {
2122 Q_ASSERT_X(false, "DomItem::wrap",
2123 "wrapping a reference object, probably an error (wrap the target path instead)");
2124 return this->copy(obj);
2125 } else if constexpr (std::is_same_v<BaseT, ConstantData>) {
2126 return this->subDataItem(c, obj);
2127 } else if constexpr (std::is_same_v<BaseT, Map>) {
2128 return this->subMapItem(obj);
2129 } else if constexpr (std::is_same_v<BaseT, List>) {
2130 return this->subListItem(obj);
2131 } else if constexpr (std::is_base_of_v<ListPBase, BaseT>) {
2132 return this->subListItem(obj);
2133 } else if constexpr (std::is_same_v<BaseT, SimpleObjectWrap>) {
2134 return this->subObjectWrapItem(obj);
2135 } else if constexpr (IsDomObject<BaseT>::value) {
2136 if constexpr (domTypeIsObjWrap(BaseT::kindValue) || domTypeIsValueWrap(BaseT::kindValue)) {
2137 return this->subObjectWrapItem(
2138 SimpleObjectWrap::fromObjectRef(this->pathFromOwner().appendComponent(c), obj));
2139 } else if constexpr (domTypeIsDomElement(BaseT::kindValue)) {
2140 return this->copy(&obj);
2141 } else {
2142 qCWarning(domLog) << "Unhandled object of type " << domTypeToString(BaseT::kindValue)
2143 << " in DomItem::wrap, not using a shared_ptr for an "
2144 << "OwningItem, or unexpected wrapped object?";
2145 return DomItem();
2146 }
2147 } else if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
2148 if constexpr (domTypeIsOwningItem(BaseT::element_type::kindValue)) {
2149 return this->subOwnerItem(c, obj);
2150 } else {
2151 Q_ASSERT_X(false, "DomItem::wrap", "shared_ptr with non owning item");
2152 return DomItem();
2153 }
2154 } else if constexpr (IsMultiMap<BaseT>::value) {
2155 if constexpr (std::is_same_v<typename BaseT::key_type, QString>) {
2156 return subMapItem(Map::fromMultiMapRef<typename BaseT::mapped_type>(
2157 pathFromOwner().appendComponent(c), obj));
2158 } else {
2159 Q_ASSERT_X(false, "DomItem::wrap", "non string keys not supported (try .toString()?)");
2160 }
2161 } else if constexpr (IsMap<BaseT>::value) {
2162 if constexpr (std::is_same_v<typename BaseT::key_type, QString>) {
2163 return subMapItem(Map::fromMapRef<typename BaseT::mapped_type>(
2164 pathFromOwner().appendComponent(c), obj,
2165 [](const DomItem &map, const PathEls::PathComponent &p,
2166 const typename BaseT::mapped_type &el) { return map.wrap(p, el); }));
2167 } else {
2168 Q_ASSERT_X(false, "DomItem::wrap", "non string keys not supported (try .toString()?)");
2169 }
2170 } else if constexpr (IsList<BaseT>::value) {
2171 if constexpr (IsDomObject<typename BaseT::value_type>::value) {
2172 return subListItem(List::fromQListRef<typename BaseT::value_type>(
2173 pathFromOwner().appendComponent(c), obj,
2174 [](const DomItem &list, const PathEls::PathComponent &p,
2175 const typename BaseT::value_type &el) { return list.wrap(p, el); }));
2176 } else {
2177 Q_ASSERT_X(false, "DomItem::wrap", "Unsupported list type T");
2178 return DomItem();
2179 }
2180 } else {
2181 qCWarning(domLog) << "Cannot wrap " << typeid(BaseT).name();
2182 Q_ASSERT_X(false, "DomItem::wrap", "Do not know how to wrap type T");
2183 return DomItem();
2184 }
2185}
2186
2187template<typename T>
2189{
2190 auto lazyWrap = [this, &c, &obj]() { return this->wrap<T>(c, obj); };
2191 return visitor(c, lazyWrap);
2192}
2193
2194template<typename T>
2196{
2197 index_type len = index_type(m_pList.size());
2198 for (index_type i = 0; i < len; ++i) {
2199 if (!v(PathEls::Index(i), [this, &self, i] { return this->index(self, i); }))
2200 return false;
2201 }
2202 return true;
2203}
2204
2205template<typename T>
2207{
2208 if (index >= 0 && index < m_pList.size())
2209 return self.wrap(PathEls::Index(index), *static_cast<const T *>(m_pList.value(index)));
2210 return DomItem();
2211}
2212
2213// allow inlining of DomBase
2215{
2216 return kind2domKind(kind());
2217}
2218
2219inline bool DomBase::iterateDirectSubpathsConst(const DomItem &self, DirectVisitor visitor) const
2220{
2221 Q_ASSERT(self.base() == this);
2222 return self.iterateDirectSubpaths(std::move(visitor));
2223}
2224
2226{
2227 Path path = pathFromOwner(self);
2228 DomItem base = self.owner();
2229 if (!path) {
2230 path = canonicalPath(self);
2231 base = self;
2232 }
2233 Source source = path.split();
2234 return base.path(source.pathToSource);
2235}
2236
2237inline quintptr DomBase::id() const
2238{
2239 return quintptr(this);
2240}
2241
2243{
2244 return domTypeToString(kind());
2245}
2246
2247inline QList<QString> DomBase::fields(const DomItem &self) const
2248{
2249 QList<QString> res;
2250 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2251 if (c.kind() == Path::Kind::Field)
2252 res.append(c.name());
2253 return true;
2254 });
2255 return res;
2256}
2257
2259{
2260 DomItem res;
2261 self.iterateDirectSubpaths(
2263 if (c.kind() == Path::Kind::Field && c.checkName(name)) {
2264 res = obj();
2265 return false;
2266 }
2267 return true;
2268 });
2269 return res;
2270}
2271
2272inline index_type DomBase::indexes(const DomItem &self) const
2273{
2274 index_type res = 0;
2275 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2276 if (c.kind() == Path::Kind::Index) {
2277 index_type i = c.index() + 1;
2278 if (res < i)
2279 res = i;
2280 }
2281 return true;
2282 });
2283 return res;
2284}
2285
2286inline DomItem DomBase::index(const DomItem &self, qint64 index) const
2287{
2288 DomItem res;
2289 self.iterateDirectSubpaths(
2291 if (c.kind() == Path::Kind::Index && c.index() == index) {
2292 res = obj();
2293 return false;
2294 }
2295 return true;
2296 });
2297 return res;
2298}
2299
2300inline QSet<QString> const DomBase::keys(const DomItem &self) const
2301{
2302 QSet<QString> res;
2303 self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
2304 if (c.kind() == Path::Kind::Key)
2305 res.insert(c.name());
2306 return true;
2307 });
2308 return res;
2309}
2310
2311inline DomItem DomBase::key(const DomItem &self, const QString &name) const
2312{
2313 DomItem res;
2314 self.iterateDirectSubpaths(
2316 if (c.kind() == Path::Kind::Key && c.checkName(name)) {
2317 res = obj();
2318 return false;
2319 }
2320 return true;
2321 });
2322 return res;
2323}
2324
2326{
2327 return DomItem(m_top, m_owner, m_ownerPath, list);
2328}
2329
2331{
2332 return DomItem(m_top, m_owner, m_ownerPath, map);
2333}
2334
2335} // end namespace Dom
2336} // end namespace QQmlJS
2337
2339#endif // QMLDOMITEM_H
\inmodule QtCore\reentrant
Definition qcborvalue.h:47
\inmodule QtCore\reentrant
Definition qdatetime.h:283
static QDateTime currentDateTimeUtc()
\inmodule QtCore
qsizetype size() const noexcept
Definition qlist.h:397
iterator end()
Definition qlist.h:626
iterator begin()
Definition qlist.h:625
void reserve(qsizetype size)
Definition qlist.h:753
pointer data()
Definition qlist.h:431
void append(parameter_type t)
Definition qlist.h:458
Definition qmap.h:187
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
const_iterator constFind(const Key &key) const
Definition qmap.h:655
key_iterator keyBegin() const
Definition qmap.h:606
const_iterator constEnd() const
Definition qmap.h:604
key_iterator keyEnd() const
Definition qmap.h:607
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:281
Associates comments with AST::Node *.
Attached info creates a tree to attach extra info to DomItems.
Represents a comment.
DomKind domKind() const override
ConstantData(const Path &pathFromOwner, const QCborValue &value, Options options=Options::MapIsMap)
QCborValue value() const override
quintptr id() const override
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
bool iterateDirectSubpathsConst(const DomItem &self, DirectVisitor) const
virtual DomType kind() const =0
virtual DomKind domKind() const
virtual Path canonicalPath(const DomItem &self) const =0
virtual Path pathFromOwner(const DomItem &self) 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 void writeOut(const DomItem &self, OutWriter &lw) const
virtual DomItem containingObject(const DomItem &self) const
virtual QString canonicalFilePath(const DomItem &self) 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 ~DomBase()=default
virtual DomItem key(const DomItem &self, const QString &name) const
virtual DomItem index(const DomItem &self, index_type index) const
virtual void dump(const DomItem &, const Sink &sink, int indent, FilterT filter) const
DomElement & operator=(const DomElement &)=default
Path canonicalPath(const DomItem &self) const override
DomElement(const DomElement &o)=default
DomElement(const Path &pathFromOwner=Path())
virtual void updatePathFromOwner(const Path &newPath)
Path pathFromOwner(const DomItem &self) const override
DomItem containingObject(const DomItem &self) const override
Represents a consistent set of types organized in modules, it is the top level of the DOM.
DomItem fileLocations() const
DomItem bindings() const
bool dvReferences(DirectVisitor visitor, const PathEls::PathComponent &c, const QList< Path > &paths) const
T const * as() const
DomItem fileLocationsTree() const
bool visitKeys(function_ref< bool(const QString &, const DomItem &)> visitor) const
static ErrorGroup domErrorGroup
bool isCanonicalChild(const DomItem &child) const
DomItem operator[](int i) const
QSet< QString > propertyInfoNames() const
QSet< QString > keys() 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 owner() const
int revision() const
DomItem operator[](index_type i) const
static ErrorGroups myResolveErrors()
DomItem methods() const
QString internalKindStr() const
DomItem enumerations() const
DomItem subOwnerItem(const PathEls::PathComponent &c, Owner o) const
DomItem child(index_type i) const
static ErrorGroups myErrors()
DomItem goUp(int) const
DomItem fileObject(GoTo option=GoTo::Strict) const
bool dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem environment() const
DomItem key(QStringView name) const
std::shared_ptr< T > ownerAs() const
DomItem directParent() const
bool commitToBase(const std::shared_ptr< DomEnvironment > &validPtr=nullptr) const
DomItem container() const
index_type indexes() const
DomItem operator[](const char16_t *component) const
DomItem field(QStringView name) const
Path pathFromOwner() const
QDateTime createdAt() const
QStringList sortedKeys() const
DomItem refreshed() const
function< void(const Path &, const DomItem &, const DomItem &)> Callback
DomItem pragmas() const
bool dvItem(DirectVisitor visitor, const PathEls::PathComponent &c, function_ref< DomItem()> it) const
bool visitIndexes(function_ref< bool(const DomItem &)> visitor) 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
QString idStr() const
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 containingObject() const
DomItem(const std::shared_ptr< DomEnvironment > &)
bool dvReferenceField(DirectVisitor visitor, QStringView f, const Path &referencedObject) const
bool dvWrapField(DirectVisitor visitor, QStringView f, T &obj) const
DomItem subDataItemField(QStringView f, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem path(QStringView p, const ErrorHandler &h=&defaultErrorHandler) const
bool writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks) const
DomItem copy(const T &base) const
QString toString() 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
index_type size() const
DomItem path(const QString &p, const ErrorHandler &h=&defaultErrorHandler) const
DomItem rootQmlObject(GoTo option=GoTo::Strict) const
DomItem operator[](const QString &component) const
bool dvReferencesField(DirectVisitor visitor, QStringView f, const QList< Path > &paths) const
DomItem get(const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
DomItem subListItem(const List &list) const
void addError(ErrorMessage &&msg) const
DomItem path(const Path &p, const ErrorHandler &h=&defaultErrorHandler) const
std::shared_ptr< OwningItem > owningItemPtr() const
FileWriter::Status dump(const QString &path, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter, int nBackups=2, int indent=0, FileWriter *fw=nullptr) const
bool dvReference(DirectVisitor visitor, const PathEls::PathComponent &c, const Path &referencedObject) const
function_ref< bool(const Path &, const DomItem &)> Visitor
bool iterateDirectSubpaths(DirectVisitor v) const
quintptr id() const
std::shared_ptr< DomTop > topPtr() const
DomItem lookupFirst(const QString &symbolName, LookupType type=LookupType::Symbol, LookupOptions=LookupOption::Normal, const ErrorHandler &errorHandler=nullptr) const
DomItem operator[](const Path &path) const
DomItem ids() const
DomItem filterUp(function_ref< bool(DomType k, const DomItem &)> filter, FilterUpOptions options) const
DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const
DomItem copy(const Owner &owner, const Path &ownerPath) const
bool dvItemField(DirectVisitor visitor, QStringView f, function_ref< DomItem()> it) const
bool visitSubSymbolsNamed(const QString &name, function_ref< bool(const DomItem &)> visitor) const
bool dvValueLazyField(DirectVisitor visitor, QStringView f, F valueF, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem operator[](QStringView component) const
DomItem containingScriptExpression() const
DomItem wrap(const PathEls::PathComponent &c, const T &obj) const
DomItem top() const
void clearErrors(const ErrorGroups &groups=ErrorGroups({}), bool iterate=true) const
bool dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj) const
int derivedFrom() const
QQmlJSScope::ConstPtr nearestSemanticScope() const
MutableDomItem makeCopy(CopyOption option=CopyOption::EnvConnected) 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
bool dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c, F valueF, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem wrapField(QStringView f, const T &obj) const
DomItem scope(FilterUpOptions options=FilterUpOptions::ReturnOuter) const
QDateTime lastDataUpdateAt() const
friend QMLDOM_EXPORT bool operator==(const DomItem &, const DomItem &)
friend class ConstantData
index_type length() const
QCborValue value() 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 subValueItem(const PathEls::PathComponent &c, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem globalScope() const
QString canonicalFilePath() const
DomItem annotations() const
bool visitTree(const Path &basePath, ChildrenVisitor visitor, VisitOptions options=VisitOption::Default, ChildrenVisitor openingVisitor=emptyChildrenVisitor, ChildrenVisitor closingVisitor=emptyChildrenVisitor, const FieldFilter &filter=FieldFilter::noFilter()) const
bool resolve(const Path &path, Visitor visitor, const ErrorHandler &errorHandler, ResolveOptions options=ResolveOption::None, const Path &fullPath=Path(), QList< Path > *visitedRefs=nullptr) const
bool iterateSubOwners(function_ref< bool(const DomItem &owner)> visitor) const
QDateTime frozenAt() const
DomItem(const std::shared_ptr< DomUniverse > &)
QList< DomItem > getAll(const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
DomKind domKind() const
bool isContainer() const
bool dvValueField(DirectVisitor visitor, QStringView f, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
DomItem universe() const
DomItem subMapItem(const Map &map) const
DomItem proceedToScope(const ErrorHandler &h=nullptr, QList< Path > *visitedRefs=nullptr) const
QList< DomItem > values() const
bool isExternalItem() const
bool writeOut(const QString &path, int nBackups=2, const LineWriterOptions &opt=LineWriterOptions(), FileWriter *fw=nullptr, WriteOutChecks extraChecks=WriteOutCheck::Default) const
ErrorHandler errorHandler() const
DomItem index(index_type) const
auto visitEl(F f) const
InternalKind internalKind() const
bool isOwningItem() const
Path canonicalPath() const
bool hasAnnotations() const
DomItem subObjectWrapItem(SimpleObjectWrap obj) const
DomItem subDataItem(const PathEls::PathComponent &c, const T &value, ConstantData::Options options=ConstantData::Options::MapIsMap) const
static DomItem empty
void writeOut(OutWriter &lw) const
bool visitUp(function_ref< bool(const DomItem &)> visitor) const
QList< DomItem > lookup(const QString &symbolName, LookupType type=LookupType::Symbol, LookupOptions=LookupOption::Normal, const ErrorHandler &errorHandler=nullptr) const
static DomItem fromCode(const QString &code, DomType fileType=DomType::QmlFile)
DomItem containingFile() const
void dump(const Sink &, int indent=0, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter) const
function_ref< bool(const Path &, const DomItem &, bool)> ChildrenVisitor
DomItem subScriptElementWrapperItem(const ScriptElementVariant &obj) const
DomItem copy(const Owner &owner, const Path &ownerPath, const T &base) const
QList< QString > fields() const
DomItem goToFile(const QString &filePath) const
DomItem component(GoTo option=GoTo::Strict) const
void writeOutPost(OutWriter &lw) const
void writeOutPre(OutWriter &lw) const
bool iterateErrors(function_ref< bool(const DomItem &, const ErrorMessage &)> visitor, bool iterate, Path inPath=Path()) const
QString name() const
DomItem children() const
PropertyInfo propertyInfoWithName(const QString &name) const
bool visitLocalSymbolsNamed(const QString &name, function_ref< bool(const DomItem &)> visitor) const
DomItem propertyDefs() const
DomItem subLocationItem(const PathEls::PathComponent &c, SourceLocation loc) const
DomItem subReferencesItem(const PathEls::PathComponent &c, const QList< Path > &paths) const
void dumpPtr(const Sink &sink) const
DomItem qmlObject(GoTo option=GoTo::Strict, FilterUpOptions options=FilterUpOptions::ReturnOuter) const
DomItem key(const QString &name) const
QQmlJSScope::ConstPtr semanticScope() const
DomItem propertyInfos() const
Represents a set of parsed/loaded modules libraries and a plugins.
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
Path pathFromOwner(const DomItem &self) 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
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.
Represents and maintains a mapping between elements and their location in a file.
QString logicalPath() const
QString canonicalPath() 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)
std::optional< InMemoryContents > content() const
FileToLoad(const std::weak_ptr< DomEnvironment > &environment, const QString &canonicalPath, const QString &logicalPath, const std::optional< InMemoryContents > &content)
std::weak_ptr< DomEnvironment > environment() const
quintptr id() const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override
void writeOut(const DomItem &self, OutWriter &ow, bool compact) const
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
ListPBase & operator*()
ListPBase * operator->()
const ListPBase * operator->() const
ListP(const Path &pathFromOwner, const QList< T * > &pList, const QString &elType=QString(), ListOptions options=ListOptions::Normal)
const ListPBase & operator*() const
void writeOut(const DomItem &self, OutWriter &ow, bool compact) const
List(const Path &pathFromOwner, const LookupFunction &lookup, const Length &length, const IteratorFunction &iterator, const QString &elType)
DomType kind() const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
const List & operator*() const
static List fromQList(const Path &pathFromOwner, const QList< T > &list, const std::function< DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper, ListOptions options=ListOptions::Normal)
std::function< bool(const DomItem &, function_ref< bool(index_type, function_ref< DomItem()>)>)> IteratorFunction
static List fromQListRef(const Path &pathFromOwner, const QList< T > &list, const std::function< DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper, ListOptions options=ListOptions::Normal)
void dump(const DomItem &, const Sink &s, int indent, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>) const override
std::function< DomItem(const DomItem &, index_type)> LookupFunction
void writeOut(const DomItem &self, OutWriter &ow) const override
quintptr id() const override
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
const Map * operator->() const
QSet< QString > const keys(const DomItem &self) const override
Map(const Path &pathFromOwner, const LookupFunction &lookup, const Keys &keys, const QString &targetType)
const Map & operator*() const
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
quintptr id() const override
DomItem key(const DomItem &self, const QString &name) const override
DomType kind() const override
MutableDomItem setCode(const QString &code)
std::shared_ptr< T > ownerAs() const
MutableDomItem addChild(QmlObject child)
MutableDomItem setMethods(QMultiMap< QString, MethodInfo > functionDefs)
QQmlJSScope::ConstPtr semanticScope()
MutableDomItem setBindings(QMultiMap< QString, Binding > bindings)
FileWriter::Status dump(const QString &path, function_ref< bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter=noFilter, int nBackups=2, int indent=0, FileWriter *fw=nullptr)
bool writeOut(const QString &path, int nBackups=2, const LineWriterOptions &opt=LineWriterOptions(), FileWriter *fw=nullptr)
friend bool operator==(const MutableDomItem &o1, const MutableDomItem &o2)
MutableDomItem addPropertyDef(const PropertyDefinition &propertyDef, AddOption option=AddOption::Overwrite)
void setSemanticScope(const QQmlJSScope::ConstPtr &scope)
bool commitToBase(const std::shared_ptr< DomEnvironment > &validEnvPtr=nullptr)
MutableDomItem addPrototypePath(const Path &prototypePath)
QString canonicalFilePath() const
MutableDomItem fileObject(GoTo option=GoTo::Strict)
MutableDomItem operator[](const char16_t *component)
MutableDomItem addAnnotation(QmlObject child)
MutableDomItem setPropertyDefs(QMultiMap< QString, PropertyDefinition > propertyDefs)
MutableDomItem key(QStringView name)
MutableDomItem operator[](const QString &component)
MutableDomItem setNextScopePath(const Path &nextScopePath)
MutableDomItem addMethod(const MethodInfo &functionDef, AddOption option=AddOption::Overwrite)
MutableDomItem operator[](index_type i)
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 setAnnotations(const QList< QmlObject > &annotations)
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 setChildren(const QList< QmlObject > &children)
MutableDomItem index(index_type i)
MutableDomItem child(index_type i)
MutableDomItem addPreComment(const Comment &comment, FileLocationRegion region)
MutableDomItem(const DomItem &item)
std::shared_ptr< OwningItem > owningItemPtr()
friend bool operator!=(const MutableDomItem &o1, const MutableDomItem &o2)
MutableDomItem rootQmlObject(GoTo option=GoTo::Strict)
MutableDomItem operator[](QStringView component)
MutableDomItem path(QStringView p)
MutableDomItem setScript(const std::shared_ptr< ScriptExpression > &exp)
MutableDomItem addBinding(Binding binding, AddOption option=AddOption::Overwrite)
MutableDomItem addPostComment(const Comment &comment, FileLocationRegion region)
virtual void addError(const DomItem &self, ErrorMessage &&msg)
QDateTime createdAt() const
virtual QDateTime lastDataUpdateAt() const
Path pathFromOwner(const DomItem &) const override final
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
virtual bool frozen() const
OwningItem(const OwningItem &&)=delete
bool iterateErrors(const DomItem &self, function_ref< bool(const DomItem &source, const ErrorMessage &msg)> visitor, const Path &inPath=Path())
virtual int revision() const
QDateTime frozenAt() const
void addErrorLocal(ErrorMessage &&msg)
virtual bool freeze()
void clearErrors(const ErrorGroups &groups=ErrorGroups({}))
Path canonicalPath(const DomItem &self) const override=0
QMultiMap< Path, ErrorMessage > localErrors() const
OwningItem & operator=(const OwningItem &&)=delete
virtual void refreshedDataAt(QDateTime tNew)
OwningItem(int derivedFrom, const QDateTime &lastDataUpdateAt)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
static int nextRevision()
virtual bool iterateSubOwners(const DomItem &self, function_ref< bool(const DomItem &owner)> visitor)
OwningItem(int derivedFrom=0)
OwningItem(const OwningItem &o)
Path key(const QString &name) const
Path path(const Path &toAdd, bool avoidToAddAsBase=false) const
Path index(index_type i) const
A QmlFile, when loaded in a DomEnvironment that has the DomCreationOption::WithSemanticAnalysis,...
QList< QString > fields(const DomItem &self) const override
quintptr id() const override
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
bool shouldCache() const
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
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
static ScriptElementVariant fromElement(const T &element)
void setData(const ScriptElementT &data)
VariantOfPointer< ScriptElements::BlockStatement, ScriptElements::IdentifierExpression, ScriptElements::ForStatement, ScriptElements::BinaryExpression, ScriptElements::VariableDeclarationEntry, ScriptElements::Literal, ScriptElements::IfStatement, ScriptElements::GenericScriptElement, ScriptElements::VariableDeclaration, ScriptElements::ReturnStatement > ScriptElementT
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
SimpleObjectWrapBase * operator->()
iterator begin()
Definition qset.h:136
iterator end()
Definition qset.h:140
iterator find(const T &value)
Definition qset.h:159
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
\inmodule QtCore
Definition qvariant.h:65
T value() const &
Definition qvariant.h:516
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
QMetaType metaType() const
const void * constData() const
Definition qvariant.h:451
QMap< QString, QString > map
[6]
list append(new Employee("Blackpool", "Stephen"))
QSet< QString >::iterator it
QStyleOptionButton opt
constexpr bool domTypeIsOwningItem(DomType)
Path appendUpdatableElementInQList(const Path &listPathFromOwner, QList< T > &list, const T &value, T **vPtr=nullptr)
constexpr bool domTypeIsValueWrap(DomType k)
QDebug operator<<(QDebug d, AST::Node *n)
Path insertUpdatableElementInMultiMap(const Path &mapPathFromOwner, QMultiMap< K, T > &mmap, K key, const T &value, AddOption option=AddOption::KeepExisting, T **valuePtr=nullptr)
bool operator!=(const Version &v1, const Version &v2)
std::variant< std::monostate, std::shared_ptr< DomEnvironment >, std::shared_ptr< DomUniverse > > TopT
bool noFilter(const DomItem &, const PathEls::PathComponent &, const DomItem &)
qint64 index_type
DomKind kind2domKind(DomType k)
static DomItem keyMultiMapHelper(const DomItem &self, const QString &key, const QMultiMap< QString, T > &mmap)
constexpr bool domTypeIsUnattachedOwningItem(DomType)
QMLDOM_EXPORT QString domTypeToString(DomType k)
std::variant< ConstantData, Empty, List, ListP, Map, Reference, ScriptElementDomWrapper, SimpleObjectWrap, const AstComments *, const AttachedInfo *, 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
constexpr bool domTypeIsScriptElement(DomType)
QMLDOM_EXPORT bool domTypeIsScope(DomType k)
constexpr bool domTypeIsDomElement(DomType)
QMLDOM_EXPORT bool domTypeIsExternalItem(DomType k)
QString fileLocationRegionName(FileLocationRegion region)
void updatePathFromOwnerQList(QList< T > &list, const Path &newPath)
constexpr bool domTypeCanBeInline(DomType k)
FileLocationRegion fileLocationRegionValue(QStringView region)
QMLDOM_EXPORT QMap< DomType, QString > domTypeToStringMap()
auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw, rank< 1 >) -> decltype(t.writeOut(self, lw))
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< AttachedInfo >, std::shared_ptr< DomEnvironment >, std::shared_ptr< DomUniverse > > OwnerT
QMLDOM_EXPORT bool domTypeIsTopItem(DomType k)
std::function< void(const ErrorMessage &)> ErrorHandler
bool operator==(const Version &v1, const Version &v2)
void updatePathFromOwnerMultiMap(QMultiMap< K, T > &mmap, const Path &newPath)
constexpr bool domTypeIsObjWrap(DomType k)
QMLDOM_EXPORT QString domKindToString(DomKind k)
bool emptyChildrenVisitor(Path, const DomItem &, bool)
QMLDOM_EXPORT bool domTypeIsContainer(DomType k)
QCborValue sourceLocationToQCborValue(QQmlJS::SourceLocation loc)
QMLDOM_EXPORT QMap< DomKind, QString > domKindToStringMap()
Combined button and popup list for selecting options.
SharedPointerFileDialogOptions m_options
#define Q_DECLARE_TR_FUNCTIONS(context)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
#define qCWarning(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
const char * typeName
GLint location
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
GLsizei GLuint * groups
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLenum GLuint id
[7]
GLdouble GLdouble GLdouble GLdouble top
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLenum type
GLsizei const GLuint * paths
GLenum target
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint name
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
GLuint res
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei const GLchar *const * path
GLsizei GLenum GLboolean sink
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint GLenum option
GLenum GLsizei len
GLuint const GLint * locations
static qreal component(const QPointF &point, unsigned int i)
#define QMLDOM_EXPORT
QQmlJS::Dom::DomItem DomItem
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
static QT_BEGIN_NAMESPACE QAsn1Element wrap(quint8 type, const QAsn1Element &child)
static QString canonicalPath(const QString &rootPath)
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
static FileType fileType(const QFileInfo &fi)
@ Success
Definition main.cpp:3325
#define Q_GADGET
#define Q_UNUSED(x)
size_t quintptr
Definition qtypes.h:167
ptrdiff_t qsizetype
Definition qtypes.h:165
long long qint64
Definition qtypes.h:60
static const uint base
Definition qurlidna.cpp:20
QList< int > list
[14]
QStringList keys
QVariant variant
[1]
QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9))
[0]
QMutex mutex
[2]
QGraphicsItem * item
QLayoutItem * child
[0]
QStringView el
A common base class for all the script elements.
void setSemanticScope(const QQmlJSScope::ConstPtr &scope)
std::shared_ptr< T > PointerType
virtual void createFileLocations(const std::shared_ptr< AttachedInfoT< FileLocations > > &fileLocationOfOwner)=0
QQmlJSScope::ConstPtr semanticScope()
SubclassStorage & operator=(const SubclassStorage &o)
SubclassStorage(const SubclassStorage &&o)
SubclassStorage(const SubclassStorage &o)