aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmldom/qqmldomitem_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmldom/qqmldomitem_p.h')
-rw-r--r--src/qmldom/qqmldomitem_p.h1288
1 files changed, 773 insertions, 515 deletions
diff --git a/src/qmldom/qqmldomitem_p.h b/src/qmldom/qqmldomitem_p.h
index 631a0ff335..50775a1db2 100644
--- a/src/qmldom/qqmldomitem_p.h
+++ b/src/qmldom/qqmldomitem_p.h
@@ -17,6 +17,7 @@
#include "qqmldom_global.h"
#include "qqmldom_fwd_p.h"
+#include "qqmldom_utils_p.h"
#include "qqmldomconstants_p.h"
#include "qqmldomstringdumper_p.h"
#include "qqmldompath_p.h"
@@ -24,6 +25,7 @@
#include "qqmldomfunctionref_p.h"
#include "qqmldomfilewriter_p.h"
#include "qqmldomlinewriter_p.h"
+#include "qqmldomfieldfilter_p.h"
#include <QtCore/QMap>
#include <QtCore/QMultiMap>
@@ -36,6 +38,7 @@
#include <QtCore/QCborValue>
#include <QtCore/QTimeZone>
#include <QtQml/private/qqmljssourcelocation_p.h>
+#include <QtQmlCompiler/private/qqmljsscope_p.h>
#include <memory>
#include <typeinfo>
@@ -60,6 +63,7 @@ constexpr bool domTypeIsValueWrap(DomType k);
constexpr bool domTypeIsDomElement(DomType);
constexpr bool domTypeIsOwningItem(DomType);
constexpr bool domTypeIsUnattachedOwningItem(DomType);
+constexpr bool domTypeIsScriptElement(DomType);
QMLDOM_EXPORT bool domTypeIsExternalItem(DomType k);
QMLDOM_EXPORT bool domTypeIsTopItem(DomType k);
QMLDOM_EXPORT bool domTypeIsContainer(DomType k);
@@ -72,6 +76,7 @@ constexpr bool domTypeCanBeInline(DomType k)
case DomType::ListP:
case DomType::ConstantData:
case DomType::SimpleObjectWrap:
+ case DomType::ScriptElementWrap:
case DomType::Reference:
return true;
default:
@@ -85,15 +90,13 @@ QMLDOM_EXPORT QString domTypeToString(DomType k);
QMLDOM_EXPORT QMap<DomKind, QString> domKindToStringMap();
QMLDOM_EXPORT QString domKindToString(DomKind k);
-QMLDOM_EXPORT QCborValue locationToData(SourceLocation loc, QStringView strValue=u"");
-
-inline bool noFilter(DomItem &, const PathEls::PathComponent &, DomItem &)
+inline bool noFilter(const DomItem &, const PathEls::PathComponent &, const DomItem &)
{
return true;
}
using DirectVisitor = function_ref<bool(const PathEls::PathComponent &, function_ref<DomItem()>)>;
-// using DirectVisitor = function_ref<bool(Path, DomItem &)>;
+// using DirectVisitor = function_ref<bool(Path, const DomItem &)>;
namespace {
template<typename T>
@@ -176,8 +179,11 @@ template<typename T>
union SubclassStorage {
int i;
T lp;
+
+ // TODO: these are extremely nasty. What is this int doing in here?
T *data() { return reinterpret_cast<T *>(this); }
const T *data() const { return reinterpret_cast<const T *>(this); }
+
SubclassStorage() { }
SubclassStorage(T &&el) { el.moveTo(data()); }
SubclassStorage(const T *el) { el->copyTo(data()); }
@@ -192,42 +198,47 @@ union SubclassStorage {
~SubclassStorage() { data()->~T(); }
};
-class QMLDOM_EXPORT DomBase{
+class QMLDOM_EXPORT DomBase
+{
public:
+ using FilterT = function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>;
+
virtual ~DomBase() = default;
+ DomBase *domBase() { return this; }
+ const DomBase *domBase() const { return this; }
+
// minimal overload set:
virtual DomType kind() const = 0;
virtual DomKind domKind() const;
- virtual Path pathFromOwner(DomItem &self) const = 0;
- virtual Path canonicalPath(DomItem &self) const = 0;
+ virtual Path pathFromOwner(const DomItem &self) const = 0;
+ virtual Path canonicalPath(const DomItem &self) const = 0;
virtual bool
- iterateDirectSubpaths(DomItem &self,
- DirectVisitor visitor) = 0; // iterates the *direct* subpaths, returns
- // false if a quick end was requested
- bool iterateDirectSubpathsConst(DomItem &self, DirectVisitor)
+ iterateDirectSubpaths(const DomItem &self,
+ DirectVisitor visitor) const = 0; // iterates the *direct* subpaths, returns
+ // false if a quick end was requested
+
+ bool iterateDirectSubpathsConst(const DomItem &self, DirectVisitor)
const; // iterates the *direct* subpaths, returns false if a quick end was requested
virtual DomItem containingObject(
- DomItem &self) const; // the DomItem corresponding to the canonicalSource source
- virtual void
- dump(DomItem &, Sink sink, int indent,
- function_ref<bool(DomItem &, const PathEls::PathComponent &, DomItem &)> filter) const;
+ const DomItem &self) const; // the DomItem corresponding to the canonicalSource source
+ virtual void dump(const DomItem &, const Sink &sink, int indent, FilterT filter) const;
virtual quintptr id() const;
QString typeName() const;
- virtual QList<QString> fields(DomItem &self) const;
- virtual DomItem field(DomItem &self, QStringView name) const;
+ virtual QList<QString> fields(const DomItem &self) const;
+ virtual DomItem field(const DomItem &self, QStringView name) const;
- virtual index_type indexes(DomItem &self) const;
- virtual DomItem index(DomItem &self, index_type index) const;
+ virtual index_type indexes(const DomItem &self) const;
+ virtual DomItem index(const DomItem &self, index_type index) const;
- virtual QSet<QString> const keys(DomItem &self) const;
- virtual DomItem key(DomItem &self, QString name) const;
+ virtual QSet<QString> const keys(const DomItem &self) const;
+ virtual DomItem key(const DomItem &self, const QString &name) const;
- virtual QString canonicalFilePath(DomItem &self) const;
+ virtual QString canonicalFilePath(const DomItem &self) const;
- virtual void writeOut(DomItem &self, OutWriter &lw) const;
+ virtual void writeOut(const DomItem &self, OutWriter &lw) const;
virtual QCborValue value() const {
return QCborValue();
@@ -264,12 +275,12 @@ public:
Empty();
quintptr id() const override { return ~quintptr(0); }
- Path pathFromOwner(DomItem &self) const override;
- Path canonicalPath(DomItem &self) const override;
- DomItem containingObject(DomItem &self) const override;
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
- void dump(DomItem &, Sink s, int indent,
- function_ref<bool(DomItem &, const PathEls::PathComponent &, DomItem &)> filter)
+ Path pathFromOwner(const DomItem &self) const override;
+ Path canonicalPath(const DomItem &self) const override;
+ DomItem containingObject(const DomItem &self) const override;
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
+ void dump(const DomItem &, const Sink &s, int indent,
+ function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter)
const override;
};
@@ -277,13 +288,14 @@ class QMLDOM_EXPORT DomElement: public DomBase {
protected:
DomElement& operator=(const DomElement&) = default;
public:
- DomElement(Path pathFromOwner = Path());
+ DomElement(const Path &pathFromOwner = Path());
DomElement(const DomElement &o) = default;
- Path pathFromOwner(DomItem &self) const override;
+ Path pathFromOwner(const DomItem &self) const override;
Path pathFromOwner() const { return m_pathFromOwner; }
- Path canonicalPath(DomItem &self) const override;
- DomItem containingObject(DomItem &self) const override;
- virtual void updatePathFromOwner(Path newPath);
+ Path canonicalPath(const DomItem &self) const override;
+ DomItem containingObject(const DomItem &self) const override;
+ virtual void updatePathFromOwner(const Path &newPath);
+
private:
Path m_pathFromOwner;
};
@@ -299,22 +311,35 @@ public:
Map &operator*() { return *this; }
const Map &operator*() const { return *this; }
- using LookupFunction = std::function<DomItem(DomItem &, QString)>;
- using Keys = std::function<QSet<QString>(DomItem &)>;
- Map(Path pathFromOwner, LookupFunction lookup, Keys keys, QString targetType);
+ using LookupFunction = std::function<DomItem(const DomItem &, QString)>;
+ using Keys = std::function<QSet<QString>(const DomItem &)>;
+ Map(const Path &pathFromOwner, const LookupFunction &lookup,
+ const Keys &keys, const QString &targetType);
quintptr id() const override;
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
- QSet<QString> const keys(DomItem &self) const override;
- DomItem key(DomItem &self, QString name) const override;
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
+ QSet<QString> const keys(const DomItem &self) const override;
+ DomItem key(const DomItem &self, const QString &name) const override;
template<typename T>
- static Map fromMultiMapRef(Path pathFromOwner, QMultiMap<QString, T> &mmap);
+ static Map fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
+ template<typename T>
+ static Map fromMultiMap(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap);
template<typename T>
static Map
- fromMapRef(Path pathFromOwner, QMap<QString, T> &mmap,
- std::function<DomItem(DomItem &, const PathEls::PathComponent &, T &)> elWrapper);
+ fromMapRef(
+ const Path &pathFromOwner, const QMap<QString, T> &mmap,
+ const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper);
+
+ template<typename T>
+ static Map fromFileRegionMap(
+ const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map);
+ template<typename T>
+ static Map fromFileRegionListMap(
+ const Path &pathFromOwner, const QMap<FileLocationRegion, QList<T>> &map);
private:
+ template<typename MapT>
+ static QSet<QString> fileRegionKeysFromMap(const MapT &map);
LookupFunction m_lookup;
Keys m_keys;
QString m_targetType;
@@ -331,32 +356,33 @@ public:
List &operator*() { return *this; }
const List &operator*() const { return *this; }
- using LookupFunction = std::function<DomItem(DomItem &, index_type)>;
- using Length = std::function<index_type(DomItem &)>;
+ using LookupFunction = std::function<DomItem(const DomItem &, index_type)>;
+ using Length = std::function<index_type(const DomItem &)>;
using IteratorFunction =
- std::function<bool(DomItem &, function_ref<bool(index_type, function_ref<DomItem()>)>)>;
+ std::function<bool(const DomItem &, function_ref<bool(index_type, function_ref<DomItem()>)>)>;
- List(Path pathFromOwner, LookupFunction lookup, Length length, IteratorFunction iterator, QString elType);
+ List(const Path &pathFromOwner, const LookupFunction &lookup, const Length &length,
+ const IteratorFunction &iterator, const QString &elType);
quintptr id() const override;
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
void
- dump(DomItem &, Sink s, int indent,
- function_ref<bool(DomItem &, const PathEls::PathComponent &, DomItem &)>) const override;
- index_type indexes(DomItem &self) const override;
- DomItem index(DomItem &self, index_type index) const override;
+ dump(const DomItem &, const Sink &s, int indent,
+ function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)>) const override;
+ index_type indexes(const DomItem &self) const override;
+ DomItem index(const DomItem &self, index_type index) const override;
template<typename T>
static List
- fromQList(Path pathFromOwner, QList<T> list,
- std::function<DomItem(DomItem &, const PathEls::PathComponent &, T &)> elWrapper,
+ fromQList(const Path &pathFromOwner, const QList<T> &list,
+ const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
ListOptions options = ListOptions::Normal);
template<typename T>
static List
- fromQListRef(Path pathFromOwner, QList<T> &list,
- std::function<DomItem(DomItem &, const PathEls::PathComponent &, T &)> elWrapper,
+ 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 writeOut(DomItem &self, OutWriter &ow, bool compact) const;
- void writeOut(DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
+ void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
+ void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
private:
LookupFunction m_lookup;
@@ -371,20 +397,20 @@ public:
constexpr static DomType kindValue = DomType::ListP;
DomType kind() const override { return kindValue; }
- ListPBase(Path pathFromOwner, const QList<void *> &pList, QString elType)
+ ListPBase(const Path &pathFromOwner, const QList<const void *> &pList, const QString &elType)
: DomElement(pathFromOwner), m_pList(pList), m_elType(elType)
{
}
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor v) override;
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
virtual void copyTo(ListPBase *) const { Q_ASSERT(false); };
virtual void moveTo(ListPBase *) const { Q_ASSERT(false); };
quintptr id() const override { return quintptr(0); }
- index_type indexes(DomItem &) const override { return index_type(m_pList.size()); }
- void writeOut(DomItem &self, OutWriter &ow, bool compact) const;
- void writeOut(DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
+ index_type indexes(const DomItem &) const override { return index_type(m_pList.size()); }
+ void writeOut(const DomItem &self, OutWriter &ow, bool compact) const;
+ void writeOut(const DomItem &self, OutWriter &ow) const override { writeOut(self, ow, true); }
protected:
- QList<void *> m_pList;
+ QList<const void *> m_pList;
QString m_elType;
};
@@ -394,7 +420,7 @@ class ListPT final : public ListPBase
public:
constexpr static DomType kindValue = DomType::ListP;
- ListPT(Path pathFromOwner, QList<T *> pList, QString elType = QString(),
+ ListPT(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
ListOptions options = ListOptions::Normal)
: ListPBase(pathFromOwner, {},
(elType.isEmpty() ? QLatin1String(typeid(T).name()) : elType))
@@ -405,7 +431,7 @@ public:
"ListPT does not have the same size as ListPBase");
m_pList.reserve(pList.size());
if (options == ListOptions::Normal) {
- for (void *p : pList)
+ for (const void *p : pList)
m_pList.append(p);
} else if (options == ListOptions::Reverse) {
for (qsizetype i = pList.size(); i-- != 0;)
@@ -417,9 +443,9 @@ public:
}
void copyTo(ListPBase *t) const override { new (t) ListPT(*this); }
void moveTo(ListPBase *t) const override { new (t) ListPT(std::move(*this)); }
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor v) override;
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const override;
- DomItem index(DomItem &self, index_type index) const override;
+ DomItem index(const DomItem &self, index_type index) const override;
};
class QMLDOM_EXPORT ListP
@@ -427,7 +453,7 @@ class QMLDOM_EXPORT ListP
public:
constexpr static DomType kindValue = DomType::ListP;
template<typename T>
- ListP(Path pathFromOwner, QList<T *> pList, QString elType = QString(),
+ ListP(const Path &pathFromOwner, const QList<T *> &pList, const QString &elType = QString(),
ListOptions options = ListOptions::Normal)
: list(ListPT<T>(pathFromOwner, pList, elType, options))
{
@@ -459,8 +485,9 @@ public:
ConstantData &operator*() { return *this; }
const ConstantData &operator*() const { return *this; }
- ConstantData(Path pathFromOwner, QCborValue value, Options options = Options::MapIsMap);
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
+ ConstantData(const Path &pathFromOwner, const QCborValue &value,
+ Options options = Options::MapIsMap);
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
quintptr id() const override;
DomKind domKind() const override;
QCborValue value() const override { return m_value; }
@@ -484,27 +511,17 @@ public:
{
if (m_options & SimpleWrapOption::ValueType) {
if (m_value.metaType() == QMetaType::fromType<T>())
- return reinterpret_cast<const T *>(m_value.constData());
- return nullptr;
- } else {
- return m_value.value<T *>();
- }
- }
- template <typename T>
- T *mutableAs()
- {
- if (m_options & SimpleWrapOption::ValueType) {
- if (m_value.metaType() == QMetaType::fromType<T>())
- return reinterpret_cast<T *>(m_value.data());
+ return static_cast<const T *>(m_value.constData());
return nullptr;
} else {
- return m_value.value<T *>();
+ return m_value.value<const T *>();
}
}
+
SimpleObjectWrapBase() = delete;
virtual void copyTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
virtual void moveTo(SimpleObjectWrapBase *) const { Q_ASSERT(false); }
- bool iterateDirectSubpaths(DomItem &, DirectVisitor) override
+ bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
{
Q_ASSERT(false);
return true;
@@ -512,7 +529,7 @@ public:
protected:
friend class TestDomItem;
- SimpleObjectWrapBase(Path pathFromOwner, QVariant value, quintptr idValue,
+ SimpleObjectWrapBase(const Path &pathFromOwner, const QVariant &value, quintptr idValue,
DomType kind = kindValue,
SimpleWrapOptions options = SimpleWrapOption::None)
: DomElement(pathFromOwner),
@@ -537,21 +554,21 @@ class SimpleObjectWrapT final : public SimpleObjectWrapBase
public:
constexpr static DomType kindValue = DomType::SimpleObjectWrap;
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
{
- return mutableAsT()->iterateDirectSubpaths(self, visitor);
+ return asT()->iterateDirectSubpaths(self, visitor);
}
- void writeOut(DomItem &self, OutWriter &lw) const override;
+ void writeOut(const DomItem &self, OutWriter &lw) const override;
- T const *asT() const
+ const T *asT() const
{
if constexpr (domTypeIsValueWrap(T::kindValue)) {
if (m_value.metaType() == QMetaType::fromType<T>())
- return reinterpret_cast<const T *>(m_value.constData());
+ return static_cast<const T *>(m_value.constData());
return nullptr;
} else if constexpr (domTypeIsObjWrap(T::kindValue)) {
- return m_value.value<T *>();
+ return m_value.value<const T *>();
} else {
// need dependent static assert to not unconditially trigger
static_assert(!std::is_same_v<T, T>, "wrapping of unexpected type");
@@ -559,20 +576,6 @@ public:
}
}
- T *mutableAsT()
- {
- if (domTypeIsValueWrap(T::kindValue)) {
- if (m_value.metaType() == QMetaType::fromType<T>())
- return reinterpret_cast<T *>(m_value.data());
- return nullptr;
- } else if constexpr (domTypeIsObjWrap(T::kindValue)) {
- return m_value.value<T *>();
- } else {
- Q_ASSERT_X(false, "SimpleObjectWrap", "wrapping of unexpected type");
- return nullptr;
- }
- }
-
void copyTo(SimpleObjectWrapBase *target) const override
{
static_assert(sizeof(SimpleObjectWrapBase) == sizeof(SimpleObjectWrapT),
@@ -591,7 +594,8 @@ public:
new (target) SimpleObjectWrapT(std::move(*this));
}
- SimpleObjectWrapT(Path pathFromOwner, QVariant v, quintptr idValue, SimpleWrapOptions o)
+ SimpleObjectWrapT(const Path &pathFromOwner, const QVariant &v,
+ quintptr idValue, SimpleWrapOptions o)
: SimpleObjectWrapBase(pathFromOwner, v, idValue, T::kindValue, o)
{
Q_ASSERT(domTypeIsValueWrap(T::kindValue) == bool(o & SimpleWrapOption::ValueType));
@@ -609,7 +613,7 @@ public:
const SimpleObjectWrapBase &operator*() const { return *wrap.data(); }
template<typename T>
- static SimpleObjectWrap fromObjectRef(Path pathFromOwner, T &value)
+ static SimpleObjectWrap fromObjectRef(const Path &pathFromOwner, T &value)
{
return SimpleObjectWrap(pathFromOwner, value);
}
@@ -617,7 +621,7 @@ public:
private:
template<typename T>
- SimpleObjectWrap(Path pathFromOwner, T &value)
+ SimpleObjectWrap(const Path &pathFromOwner, T &value)
{
using BaseT = std::decay_t<T>;
if constexpr (domTypeIsObjWrap(BaseT::kindValue)) {
@@ -651,57 +655,248 @@ public:
const Reference &operator*() const { return *this; }
bool shouldCache() const;
- Reference(Path referredObject = Path(), Path pathFromOwner = Path(), const SourceLocation & loc = SourceLocation());
+ Reference(const Path &referredObject = Path(), const Path &pathFromOwner = Path(),
+ const SourceLocation &loc = SourceLocation());
quintptr id() const override;
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
- DomItem field(DomItem &self, QStringView name) const override;
- QList<QString> fields(DomItem &self) const override;
- index_type indexes(DomItem &) const override { return 0; }
- DomItem index(DomItem &, index_type) const override;
- QSet<QString> const keys(DomItem &) const override { return {}; }
- DomItem key(DomItem &, QString) const override;
-
- DomItem get(DomItem &self, ErrorHandler h = nullptr, QList<Path> *visitedRefs = nullptr) const;
- QList<DomItem> getAll(DomItem &self, ErrorHandler h = nullptr,
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
+ DomItem field(const DomItem &self, QStringView name) const override;
+ QList<QString> fields(const DomItem &self) const override;
+ index_type indexes(const DomItem &) const override { return 0; }
+ DomItem index(const DomItem &, index_type) const override;
+ QSet<QString> const keys(const DomItem &) const override { return {}; }
+ DomItem key(const DomItem &, const QString &) 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;
Path referredObjectPath;
};
-using ElementT = std::variant<
- Empty, Map, List, ListP, ConstantData, SimpleObjectWrap, Reference, GlobalComponent *,
- JsResource *, QmlComponent *, QmltypesComponent *, EnumDecl *, MockObject *, ModuleScope *,
- AstComments *, AttachedInfo *, DomEnvironment *, DomUniverse *, ExternalItemInfoBase *,
- ExternalItemPairBase *, GlobalScope *, JsFile *, QmlDirectory *, QmlFile *, QmldirFile *,
- QmlObject *, QmltypesFile *, LoadInfo *, MockOwner *, ModuleIndex *, ScriptExpression *>;
+template<typename Info>
+class AttachedInfoT;
+class FileLocations;
+
+/*!
+ \internal
+ \brief A common base class for all the script elements.
+
+ This marker class allows to use all the script elements as a ScriptElement*, using virtual
+ dispatch. For now, it does not add any extra functionality, compared to a DomElement, but allows
+ to forbid DomElement* at the places where only script elements are required.
+ */
+// TODO: do we need another marker struct like this one to differentiate expressions from
+// statements? This would allow to avoid mismatchs between script expressions and script statements,
+// using type-safety.
+struct ScriptElement : public DomElement
+{
+ template<typename T>
+ using PointerType = std::shared_ptr<T>;
+
+ using DomElement::DomElement;
+ virtual void createFileLocations(
+ const std::shared_ptr<AttachedInfoT<FileLocations>> &fileLocationOfOwner) = 0;
+
+ QQmlJSScope::ConstPtr semanticScope();
+ void setSemanticScope(const QQmlJSScope::ConstPtr &scope);
+
+private:
+ QQmlJSScope::ConstPtr m_scope;
+};
+
+/*!
+ \internal
+ \brief Use this to contain any script element.
+ */
+class ScriptElementVariant
+{
+private:
+ template<typename... T>
+ using VariantOfPointer = std::variant<ScriptElement::PointerType<T>...>;
+
+ template<typename T, typename Variant>
+ struct TypeIsInVariant;
+
+ template<typename T, typename... Ts>
+ struct TypeIsInVariant<T, std::variant<Ts...>> : public std::disjunction<std::is_same<T, Ts>...>
+ {
+ };
+
+public:
+ using ScriptElementT =
+ VariantOfPointer<ScriptElements::BlockStatement, ScriptElements::IdentifierExpression,
+ ScriptElements::ForStatement, ScriptElements::BinaryExpression,
+ ScriptElements::VariableDeclarationEntry, ScriptElements::Literal,
+ ScriptElements::IfStatement, ScriptElements::GenericScriptElement,
+ ScriptElements::VariableDeclaration, ScriptElements::ReturnStatement>;
+
+ template<typename T>
+ static ScriptElementVariant fromElement(const T &element)
+ {
+ static_assert(TypeIsInVariant<T, ScriptElementT>::value,
+ "Cannot construct ScriptElementVariant from T, as it is missing from the "
+ "ScriptElementT.");
+ ScriptElementVariant p;
+ p.m_data = element;
+ return p;
+ }
+
+ ScriptElement::PointerType<ScriptElement> base() const;
+
+ operator bool() const { return m_data.has_value(); }
+
+ template<typename F>
+ void visitConst(F &&visitor) const
+ {
+ if (m_data)
+ std::visit(std::forward<F>(visitor), *m_data);
+ }
+
+ template<typename F>
+ void visit(F &&visitor)
+ {
+ if (m_data)
+ std::visit(std::forward<F>(visitor), *m_data);
+ }
+ std::optional<ScriptElementT> data() { return m_data; }
+ void setData(const ScriptElementT &data) { m_data = data; }
+
+private:
+ std::optional<ScriptElementT> m_data;
+};
+
+/*!
+ \internal
+
+ To avoid cluttering the already unwieldy \l ElementT type below with all the types that the
+ different script elements can have, wrap them in an extra class. It will behave like an internal
+ Dom structure (e.g. like a List or a Map) and contain a pointer the the script element.
+ */
+class ScriptElementDomWrapper
+{
+public:
+ ScriptElementDomWrapper(const ScriptElementVariant &element) : m_element(element) { }
+
+ static constexpr DomType kindValue = DomType::ScriptElementWrap;
-using TopT = std::variant<std::shared_ptr<DomEnvironment>, std::shared_ptr<DomUniverse>>;
+ DomBase *operator->() { return m_element.base().get(); }
+ const DomBase *operator->() const { return m_element.base().get(); }
+ DomBase &operator*() { return *m_element.base(); }
+ const DomBase &operator*() const { return *m_element.base(); }
-using OwnerT =
- std::variant<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>>;
+ ScriptElementVariant element() const { return m_element; }
-inline bool emptyChildrenVisitor(Path, DomItem &, bool)
+private:
+ ScriptElementVariant m_element;
+};
+
+// TODO: create more "groups" to simplify this variant? Maybe into Internal, ScriptExpression, ???
+using ElementT =
+ 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 *
+ >;
+
+using TopT = std::variant<
+ std::monostate,
+ std::shared_ptr<DomEnvironment>,
+ std::shared_ptr<DomUniverse>>;
+
+using OwnerT = 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>>;
+
+inline bool emptyChildrenVisitor(Path, const DomItem &, bool)
{
return true;
}
class MutableDomItem;
+class FileToLoad
+{
+public:
+ struct InMemoryContents
+ {
+ QString data;
+ QDateTime date = QDateTime::currentDateTimeUtc();
+ };
+
+ FileToLoad(const std::weak_ptr<DomEnvironment> &environment, const QString &canonicalPath,
+ const QString &logicalPath, const std::optional<InMemoryContents> &content);
+ FileToLoad() = default;
+
+ static FileToLoad fromMemory(const std::weak_ptr<DomEnvironment> &environment,
+ const QString &path, const QString &data);
+ static FileToLoad fromFileSystem(const std::weak_ptr<DomEnvironment> &environment,
+ const QString &canonicalPath);
+
+ std::weak_ptr<DomEnvironment> environment() const { return m_environment; }
+ QString canonicalPath() const { return m_canonicalPath; }
+ QString logicalPath() const { return m_logicalPath; }
+ std::optional<InMemoryContents> content() const { return m_content; }
+
+private:
+ std::weak_ptr<DomEnvironment> m_environment;
+ QString m_canonicalPath;
+ QString m_logicalPath;
+ std::optional<InMemoryContents> m_content;
+};
+
class QMLDOM_EXPORT DomItem {
Q_DECLARE_TR_FUNCTIONS(DomItem);
public:
- using Callback = function<void(Path, DomItem &, DomItem &)>;
+ using Callback = function<void(const Path &, const DomItem &, const DomItem &)>;
using InternalKind = DomType;
- using Visitor = function_ref<bool(Path, DomItem &)>;
- using ChildrenVisitor = function_ref<bool(Path, DomItem &, bool)>;
+ using Visitor = function_ref<bool(const Path &, const DomItem &)>;
+ using ChildrenVisitor = function_ref<bool(const Path &, const DomItem &, bool)>;
static ErrorGroup domErrorGroup;
static ErrorGroups myErrors();
@@ -711,12 +906,7 @@ public:
enum class CopyOption { EnvConnected, EnvDisconnected };
template<typename F>
- auto visitMutableEl(F f)
- {
- return std::visit(f, this->m_element);
- }
- template<typename F>
- auto visitEl(F f)
+ auto visitEl(F f) const
{
return std::visit(f, this->m_element);
}
@@ -734,48 +924,55 @@ public:
return kind2domKind(m_kind);
}
- Path canonicalPath();
+ Path canonicalPath() const;
- DomItem filterUp(function_ref<bool(DomType k, DomItem &)> filter, FilterUpOptions options);
- DomItem containingObject();
- DomItem container();
- DomItem owner();
- DomItem top();
- DomItem environment();
- DomItem universe();
+ DomItem filterUp(function_ref<bool(DomType k, const DomItem &)> filter, FilterUpOptions options) const;
+ DomItem containingObject() const;
+ DomItem container() const;
+ DomItem owner() const;
+ DomItem top() const;
+ DomItem environment() const;
+ DomItem universe() const;
+ DomItem containingFile() const;
+ DomItem containingScriptExpression() const;
+ DomItem goToFile(const QString &filePath) const;
+ DomItem goUp(int) const;
+ DomItem directParent() const;
DomItem qmlObject(GoTo option = GoTo::Strict,
- FilterUpOptions options = FilterUpOptions::ReturnOuter);
- DomItem fileObject(GoTo option = GoTo::Strict);
- DomItem rootQmlObject(GoTo option = GoTo::Strict);
- DomItem globalScope();
- DomItem component(GoTo option = GoTo::Strict);
- DomItem scope(FilterUpOptions options = FilterUpOptions::ReturnOuter);
+ FilterUpOptions options = FilterUpOptions::ReturnOuter) const;
+ DomItem fileObject(GoTo option = GoTo::Strict) const;
+ DomItem rootQmlObject(GoTo option = GoTo::Strict) const;
+ DomItem globalScope() const;
+ DomItem component(GoTo option = GoTo::Strict) const;
+ DomItem scope(FilterUpOptions options = FilterUpOptions::ReturnOuter) const;
+ QQmlJSScope::ConstPtr nearestSemanticScope() const;
+ QQmlJSScope::ConstPtr semanticScope() const;
// convenience getters
- DomItem get(ErrorHandler h = nullptr, QList<Path> *visitedRefs = nullptr);
- QList<DomItem> getAll(ErrorHandler h = nullptr, QList<Path> *visitedRefs = nullptr);
- bool isOwningItem() { return domTypeIsOwningItem(internalKind()); }
- bool isExternalItem() { return domTypeIsExternalItem(internalKind()); }
- bool isTopItem() { return domTypeIsTopItem(internalKind()); }
- bool isContainer() { return domTypeIsContainer(internalKind()); }
- bool isScope() { return domTypeIsScope(internalKind()); }
- bool isCanonicalChild(DomItem &child);
- bool hasAnnotations();
- QString name() { return field(Fields::name).value().toString(); }
- DomItem pragmas() { return field(Fields::pragmas); }
- DomItem ids() { return field(Fields::ids); }
- QString idStr() { return field(Fields::idStr).value().toString(); }
- DomItem propertyInfos() { return field(Fields::propertyInfos); }
- PropertyInfo propertyInfoWithName(QString name);
- QSet<QString> propertyInfoNames();
- DomItem propertyDefs() { return field(Fields::propertyDefs); }
- DomItem bindings() { return field(Fields::bindings); }
- DomItem methods() { return field(Fields::methods); }
- DomItem enumerations() { return field(Fields::enumerations); }
- DomItem children() { return field(Fields::children); }
- DomItem child(index_type i) { return field(Fields::children).index(i); }
- DomItem annotations()
+ DomItem get(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
+ QList<DomItem> getAll(const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
+ bool isOwningItem() const { return domTypeIsOwningItem(internalKind()); }
+ bool isExternalItem() const { return domTypeIsExternalItem(internalKind()); }
+ bool isTopItem() const { return domTypeIsTopItem(internalKind()); }
+ bool isContainer() const { return domTypeIsContainer(internalKind()); }
+ bool isScope() const { return domTypeIsScope(internalKind()); }
+ bool isCanonicalChild(const DomItem &child) const;
+ bool hasAnnotations() const;
+ QString name() const { return field(Fields::name).value().toString(); }
+ DomItem pragmas() const { return field(Fields::pragmas); }
+ DomItem ids() const { return field(Fields::ids); }
+ QString idStr() const { return field(Fields::idStr).value().toString(); }
+ DomItem propertyInfos() const { return field(Fields::propertyInfos); }
+ PropertyInfo propertyInfoWithName(const QString &name) const;
+ QSet<QString> propertyInfoNames() const;
+ DomItem propertyDefs() const { return field(Fields::propertyDefs); }
+ DomItem bindings() const { return field(Fields::bindings); }
+ DomItem methods() const { return field(Fields::methods); }
+ DomItem enumerations() const { return field(Fields::enumerations); }
+ DomItem children() const { return field(Fields::children); }
+ DomItem child(index_type i) const { return field(Fields::children).index(i); }
+ DomItem annotations() const
{
if (hasAnnotations())
return field(Fields::annotations);
@@ -783,200 +980,214 @@ public:
return DomItem();
}
- bool resolve(Path path, Visitor visitor, ErrorHandler errorHandler,
- ResolveOptions options = ResolveOption::None, Path fullPath = Path(),
- QList<Path> *visitedRefs = nullptr);
+ bool resolve(const Path &path, Visitor visitor, const ErrorHandler &errorHandler,
+ ResolveOptions options = ResolveOption::None, const Path &fullPath = Path(),
+ QList<Path> *visitedRefs = nullptr) const;
- DomItem operator[](Path path);
- DomItem operator[](QStringView component);
- DomItem operator[](const QString &component);
- DomItem operator[](const char16_t *component)
+ DomItem operator[](const Path &path) const;
+ DomItem operator[](QStringView component) const;
+ DomItem operator[](const QString &component) const;
+ DomItem operator[](const char16_t *component) const
{
return (*this)[QStringView(component)];
} // to avoid clash with stupid builtin ptrdiff_t[DomItem&], coming from C
- DomItem operator[](index_type i) { return index(i); }
- DomItem operator[](int i) { return index(i); }
- index_type size() { return indexes() + keys().size(); }
- index_type length() { return size(); }
-
- DomItem path(Path p, ErrorHandler h = &defaultErrorHandler);
- DomItem path(QString p, ErrorHandler h = &defaultErrorHandler);
- DomItem path(QStringView p, ErrorHandler h = &defaultErrorHandler);
-
- QList<QString> fields();
- DomItem field(QStringView name);
-
- index_type indexes();
- DomItem index(index_type);
- bool visitIndexes(function_ref<bool(DomItem &)> visitor);
-
- QSet<QString> keys();
- QStringList sortedKeys();
- DomItem key(QString name);
- DomItem key(QStringView name) { return key(name.toString()); }
- bool visitKeys(function_ref<bool(QString, DomItem &)> visitor);
-
- QList<DomItem> values();
- void writeOutPre(OutWriter &lw);
- void writeOut(OutWriter &lw);
- void writeOutPost(OutWriter &lw);
- DomItem writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks);
- DomItem writeOut(QString path, int nBackups = 2,
- const LineWriterOptions &opt = LineWriterOptions(), FileWriter *fw = nullptr,
- WriteOutChecks extraChecks = WriteOutCheck::Default);
-
- bool visitTree(Path basePath, ChildrenVisitor visitor,
+ DomItem operator[](index_type i) const { return index(i); }
+ DomItem operator[](int i) const { return index(i); }
+ index_type size() const { return indexes() + keys().size(); }
+ index_type length() const { return size(); }
+
+ DomItem path(const Path &p, const ErrorHandler &h = &defaultErrorHandler) const;
+ DomItem path(const QString &p, const ErrorHandler &h = &defaultErrorHandler) const;
+ DomItem path(QStringView p, const ErrorHandler &h = &defaultErrorHandler) const;
+
+ QList<QString> fields() const;
+ DomItem field(QStringView name) const;
+
+ index_type indexes() const;
+ DomItem index(index_type) const;
+ bool visitIndexes(function_ref<bool(const DomItem &)> visitor) const;
+
+ QSet<QString> keys() const;
+ QStringList sortedKeys() const;
+ DomItem key(const QString &name) const;
+ DomItem key(QStringView name) const { return key(name.toString()); }
+ bool visitKeys(function_ref<bool(const QString &, const DomItem &)> visitor) const;
+
+ QList<DomItem> values() const;
+ void writeOutPre(OutWriter &lw) const;
+ void writeOut(OutWriter &lw) const;
+ void writeOutPost(OutWriter &lw) const;
+ bool writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks) const;
+ bool writeOut(const QString &path, int nBackups = 2,
+ const LineWriterOptions &opt = LineWriterOptions(), FileWriter *fw = nullptr,
+ WriteOutChecks extraChecks = WriteOutCheck::Default) const;
+
+ bool visitTree(const Path &basePath, ChildrenVisitor visitor,
VisitOptions options = VisitOption::Default,
ChildrenVisitor openingVisitor = emptyChildrenVisitor,
- ChildrenVisitor closingVisitor = emptyChildrenVisitor);
- bool visitPrototypeChain(function_ref<bool(DomItem &)> visitor,
+ ChildrenVisitor closingVisitor = emptyChildrenVisitor,
+ const FieldFilter &filter = FieldFilter::noFilter()) const;
+ bool visitPrototypeChain(function_ref<bool(const DomItem &)> visitor,
VisitPrototypesOptions options = VisitPrototypesOption::Normal,
- ErrorHandler h = nullptr, QSet<quintptr> *visited = nullptr,
- QList<Path> *visitedRefs = nullptr);
- bool visitDirectAccessibleScopes(function_ref<bool(DomItem &)> visitor,
+ const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
+ QList<Path> *visitedRefs = nullptr) const;
+ bool visitDirectAccessibleScopes(function_ref<bool(const DomItem &)> visitor,
VisitPrototypesOptions options = VisitPrototypesOption::Normal,
- ErrorHandler h = nullptr, QSet<quintptr> *visited = nullptr,
- QList<Path> *visitedRefs = nullptr);
+ const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
+ QList<Path> *visitedRefs = nullptr) const;
bool
- visitStaticTypePrototypeChains(function_ref<bool(DomItem &)> visitor,
+ visitStaticTypePrototypeChains(function_ref<bool(const DomItem &)> visitor,
VisitPrototypesOptions options = VisitPrototypesOption::Normal,
- ErrorHandler h = nullptr, QSet<quintptr> *visited = nullptr,
- QList<Path> *visitedRefs = nullptr);
- bool visitScopeChain(function_ref<bool(DomItem &)> visitor,
- LookupOptions = LookupOption::Normal, ErrorHandler h = nullptr,
- QSet<quintptr> *visited = nullptr, QList<Path> *visitedRefs = nullptr);
- bool visitLocalSymbolsNamed(QString name, function_ref<bool(DomItem &)> visitor);
- QSet<QString> localSymbolNames(LocalSymbolsTypes lTypes = LocalSymbolsType::All);
- bool visitLookup1(QString symbolName, function_ref<bool(DomItem &)> visitor,
- LookupOptions = LookupOption::Normal, ErrorHandler h = nullptr,
- QSet<quintptr> *visited = nullptr, QList<Path> *visitedRefs = nullptr);
- bool visitLookup(QString symbolName, function_ref<bool(DomItem &)> visitor,
- LookupType type = LookupType::Symbol, LookupOptions = LookupOption::Normal,
- ErrorHandler errorHandler = nullptr, QSet<quintptr> *visited = nullptr,
- QList<Path> *visitedRefs = nullptr);
- bool visitSubSymbolsNamed(QString name, function_ref<bool(DomItem &)> visitor);
- DomItem proceedToScope(ErrorHandler h = nullptr, QList<Path> *visitedRefs = nullptr);
- QList<DomItem> lookup(QString symbolName, LookupType type = LookupType::Symbol,
- LookupOptions = LookupOption::Normal,
- ErrorHandler errorHandler = nullptr);
- DomItem lookupFirst(QString symbolName, LookupType type = LookupType::Symbol,
- LookupOptions = LookupOption::Normal, ErrorHandler errorHandler = nullptr);
-
- quintptr id();
- Path pathFromOwner();
- QString canonicalFilePath();
- DomItem fileLocationsTree();
- DomItem fileLocations();
- MutableDomItem makeCopy(CopyOption option = CopyOption::EnvConnected);
- bool commitToBase(std::shared_ptr<DomEnvironment> validPtr = nullptr);
- DomItem refreshed() { return top().path(canonicalPath()); }
- QCborValue value();
-
- void dumpPtr(Sink sink);
- void dump(Sink, int indent = 0,
- function_ref<bool(DomItem &, const PathEls::PathComponent &, DomItem &)> filter =
- noFilter);
+ const ErrorHandler &h = nullptr, QSet<quintptr> *visited = nullptr,
+ QList<Path> *visitedRefs = nullptr) const;
+
+ bool visitUp(function_ref<bool(const DomItem &)> visitor) 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 visitLocalSymbolsNamed(
+ const QString &name, function_ref<bool(const DomItem &)> visitor) 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;
+ bool visitLookup(
+ const QString &symbolName, function_ref<bool(const DomItem &)> visitor,
+ LookupType type = LookupType::Symbol, LookupOptions = LookupOption::Normal,
+ const ErrorHandler &errorHandler = nullptr, QSet<quintptr> *visited = nullptr,
+ QList<Path> *visitedRefs = nullptr) const;
+ bool visitSubSymbolsNamed(
+ const QString &name, function_ref<bool(const DomItem &)> visitor) const;
+ DomItem proceedToScope(
+ const ErrorHandler &h = nullptr, QList<Path> *visitedRefs = nullptr) const;
+ QList<DomItem> lookup(
+ const QString &symbolName, LookupType type = LookupType::Symbol,
+ LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
+ DomItem lookupFirst(
+ const QString &symbolName, LookupType type = LookupType::Symbol,
+ LookupOptions = LookupOption::Normal, const ErrorHandler &errorHandler = nullptr) const;
+
+ quintptr id() const;
+ Path pathFromOwner() const;
+ QString canonicalFilePath() const;
+ DomItem fileLocationsTree() const;
+ DomItem fileLocations() const;
+ MutableDomItem makeCopy(CopyOption option = CopyOption::EnvConnected) const;
+ bool commitToBase(const std::shared_ptr<DomEnvironment> &validPtr = nullptr) const;
+ DomItem refreshed() const { return top().path(canonicalPath()); }
+ QCborValue value() const;
+
+ void dumpPtr(const Sink &sink) const;
+ void dump(const Sink &, int indent = 0,
+ function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter =
+ noFilter) const;
FileWriter::Status
- dump(QString path,
- function_ref<bool(DomItem &, const PathEls::PathComponent &, DomItem &)> filter = noFilter,
- int nBackups = 2, int indent = 0, FileWriter *fw = nullptr);
- QString toString();
- QString toString() const
- {
- DomItem self = *this;
- return self.toString();
- }
+ 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;
+ QString toString() const;
// OwnigItem elements
- int derivedFrom();
- int revision();
- QDateTime createdAt();
- QDateTime frozenAt();
- QDateTime lastDataUpdateAt();
+ int derivedFrom() const;
+ int revision() const;
+ QDateTime createdAt() const;
+ QDateTime frozenAt() const;
+ QDateTime lastDataUpdateAt() const;
- void addError(ErrorMessage msg);
- ErrorHandler errorHandler();
- void clearErrors(ErrorGroups groups = ErrorGroups({}), bool iterate = true);
+ void addError(ErrorMessage &&msg) const;
+ ErrorHandler errorHandler() const;
+ void clearErrors(const ErrorGroups &groups = ErrorGroups({}), bool iterate = true) const;
// return false if a quick exit was requested
- bool iterateErrors(function_ref<bool(DomItem source, ErrorMessage msg)> visitor, bool iterate,
- Path inPath = Path());
+ bool iterateErrors(
+ function_ref<bool (const DomItem &, const ErrorMessage &)> visitor, bool iterate,
+ Path inPath = Path()) const;
- bool iterateSubOwners(function_ref<bool(DomItem &owner)> visitor);
- bool iterateDirectSubpaths(DirectVisitor v);
+ bool iterateSubOwners(function_ref<bool(const DomItem &owner)> visitor) const;
+ bool iterateDirectSubpaths(DirectVisitor v) const;
template<typename T>
- DomItem subDataItem(const PathEls::PathComponent &c, T value,
- ConstantData::Options options = ConstantData::Options::MapIsMap);
+ DomItem subDataItem(const PathEls::PathComponent &c, const T &value,
+ ConstantData::Options options = ConstantData::Options::MapIsMap) const;
template<typename T>
- DomItem subDataItemField(QStringView f, T value,
- ConstantData::Options options = ConstantData::Options::MapIsMap)
+ DomItem subDataItemField(QStringView f, const T &value,
+ ConstantData::Options options = ConstantData::Options::MapIsMap) const
{
return subDataItem(PathEls::Field(f), value, options);
}
template<typename T>
- DomItem subValueItem(const PathEls::PathComponent &c, T value,
- ConstantData::Options options = ConstantData::Options::MapIsMap);
+ DomItem subValueItem(const PathEls::PathComponent &c, const T &value,
+ ConstantData::Options options = ConstantData::Options::MapIsMap) const;
template<typename T>
- bool dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, T value,
- ConstantData::Options options = ConstantData::Options::MapIsMap);
+ bool dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value,
+ ConstantData::Options options = ConstantData::Options::MapIsMap) const;
template<typename T>
- bool dvValueField(DirectVisitor visitor, QStringView f, T value,
- ConstantData::Options options = ConstantData::Options::MapIsMap)
+ bool dvValueField(DirectVisitor visitor, QStringView f, const T &value,
+ ConstantData::Options options = ConstantData::Options::MapIsMap) const
{
- return this->dvValue<T>(visitor, PathEls::Field(f), value, options);
+ return this->dvValue<T>(std::move(visitor), PathEls::Field(f), value, options);
}
template<typename F>
bool dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c, F valueF,
- ConstantData::Options options = ConstantData::Options::MapIsMap);
+ ConstantData::Options options = ConstantData::Options::MapIsMap) const;
template<typename F>
bool dvValueLazyField(DirectVisitor visitor, QStringView f, F valueF,
- ConstantData::Options options = ConstantData::Options::MapIsMap)
+ ConstantData::Options options = ConstantData::Options::MapIsMap) const
{
- return this->dvValueLazy(visitor, PathEls::Field(f), valueF, options);
+ return this->dvValueLazy(std::move(visitor), PathEls::Field(f), valueF, options);
}
- DomItem subLocationItem(const PathEls::PathComponent &c, SourceLocation loc,
- QStringView code = QStringView())
+ DomItem subLocationItem(const PathEls::PathComponent &c, SourceLocation loc) const
{
- return this->subDataItem(c, locationToData(loc, code));
+ return this->subDataItem(c, sourceLocationToQCborValue(loc));
}
// bool dvSubReference(DirectVisitor visitor, const PathEls::PathComponent &c, Path
// referencedObject);
- DomItem subReferencesItem(const PathEls::PathComponent &c, QList<Path> paths);
- DomItem subReferenceItem(const PathEls::PathComponent &c, Path referencedObject);
- bool dvReference(DirectVisitor visitor, const PathEls::PathComponent &c, Path referencedObject)
+ DomItem subReferencesItem(const PathEls::PathComponent &c, const QList<Path> &paths) const;
+ DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const;
+ bool dvReference(DirectVisitor visitor, const PathEls::PathComponent &c, const Path &referencedObject) const
{
- return dvItem(visitor, c, [c, this, referencedObject]() {
+ return dvItem(std::move(visitor), c, [c, this, referencedObject]() {
return this->subReferenceItem(c, referencedObject);
});
}
- bool dvReferences(DirectVisitor visitor, const PathEls::PathComponent &c, QList<Path> paths)
+ bool dvReferences(
+ DirectVisitor visitor, const PathEls::PathComponent &c, const QList<Path> &paths) const
{
- return dvItem(visitor, c, [c, this, paths]() { return this->subReferencesItem(c, paths); });
+ return dvItem(std::move(visitor), c, [c, this, paths]() {
+ return this->subReferencesItem(c, paths);
+ });
}
- bool dvReferenceField(DirectVisitor visitor, QStringView f, Path referencedObject)
+ bool dvReferenceField(DirectVisitor visitor, QStringView f, const Path &referencedObject) const
{
- return dvReference(visitor, PathEls::Field(f), referencedObject);
+ return dvReference(std::move(visitor), PathEls::Field(f), referencedObject);
}
- bool dvReferencesField(DirectVisitor visitor, QStringView f, QList<Path> paths)
+ bool dvReferencesField(DirectVisitor visitor, QStringView f, const QList<Path> &paths) const
{
- return dvReferences(visitor, PathEls::Field(f), paths);
+ return dvReferences(std::move(visitor), PathEls::Field(f), paths);
}
- bool dvItem(DirectVisitor visitor, const PathEls::PathComponent &c, function_ref<DomItem()> it)
+ bool dvItem(DirectVisitor visitor, const PathEls::PathComponent &c, function_ref<DomItem()> it) const
{
return visitor(c, it);
}
- bool dvItemField(DirectVisitor visitor, QStringView f, function_ref<DomItem()> it)
+ bool dvItemField(DirectVisitor visitor, QStringView f, function_ref<DomItem()> it) const
{
- return dvItem(visitor, PathEls::Field(f), it);
+ return dvItem(std::move(visitor), PathEls::Field(f), it);
}
- DomItem subListItem(const List &list);
- DomItem subMapItem(const Map &map);
- DomItem subObjectWrapItem(SimpleObjectWrap obj)
+ DomItem subListItem(const List &list) const;
+ DomItem subMapItem(const Map &map) const;
+ DomItem subObjectWrapItem(SimpleObjectWrap obj) const
{
return DomItem(m_top, m_owner, m_ownerPath, obj);
}
+
+ DomItem subScriptElementWrapperItem(const ScriptElementVariant &obj) const
+ {
+ Q_ASSERT(obj);
+ return DomItem(m_top, m_owner, m_ownerPath, ScriptElementDomWrapper(obj));
+ }
+
template<typename Owner>
- DomItem subOwnerItem(const PathEls::PathComponent &c, Owner o)
+ DomItem subOwnerItem(const PathEls::PathComponent &c, Owner o) const
{
if constexpr (domTypeIsUnattachedOwningItem(Owner::element_type::kindValue))
return DomItem(m_top, o, canonicalPath().appendComponent(c), o.get());
@@ -984,46 +1195,35 @@ public:
return DomItem(m_top, o, Path(), o.get());
}
template<typename T>
- DomItem wrap(const PathEls::PathComponent &c, T &obj);
+ DomItem wrap(const PathEls::PathComponent &c, const T &obj) const;
template<typename T>
- DomItem wrapField(QStringView f, T &obj)
+ DomItem wrapField(QStringView f, const T &obj) const
{
return wrap<T>(PathEls::Field(f), obj);
}
template<typename T>
- bool dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj);
+ bool dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj) const;
template<typename T>
- bool dvWrapField(DirectVisitor visitor, QStringView f, T &obj)
+ bool dvWrapField(DirectVisitor visitor, QStringView f, T &obj) const
{
- return dvWrap<T>(visitor, PathEls::Field(f), obj);
+ return dvWrap<T>(std::move(visitor), PathEls::Field(f), obj);
}
DomItem() = default;
- DomItem(std::shared_ptr<DomEnvironment>);
- DomItem(std::shared_ptr<DomUniverse>);
-
- static DomItem fromCode(QString code, DomType fileType = DomType::QmlFile);
- void loadFile(QString filePath, QString logicalPath,
- std::function<void(Path, DomItem &, DomItem &)> callback, LoadOptions loadOptions,
- std::optional<DomType> fileType = std::optional<DomType>());
- void loadFile(QString canonicalFilePath, QString logicalPath, QString code, QDateTime codeDate,
- std::function<void(Path, DomItem &, DomItem &)> callback, LoadOptions loadOptions,
- std::optional<DomType> fileType = std::optional<DomType>());
- void loadModuleDependency(QString uri, Version v,
- std::function<void(Path, DomItem &, DomItem &)> callback = nullptr,
- ErrorHandler = nullptr);
- void loadBuiltins(std::function<void(Path, DomItem &, DomItem &)> callback = nullptr,
- ErrorHandler = nullptr);
- void loadPendingDependencies();
+ DomItem(const std::shared_ptr<DomEnvironment> &);
+ DomItem(const std::shared_ptr<DomUniverse> &);
+
+ // TODO move to DomEnvironment?
+ static DomItem fromCode(const QString &code, DomType fileType = DomType::QmlFile);
// --- start of potentially dangerous stuff, make private? ---
- std::shared_ptr<DomTop> topPtr();
- std::shared_ptr<OwningItem> owningItemPtr();
+ std::shared_ptr<DomTop> topPtr() const;
+ std::shared_ptr<OwningItem> owningItemPtr() const;
// keep the DomItem around to ensure that it doesn't get deleted
template<typename T, typename std::enable_if<std::is_base_of_v<DomBase, T>, bool>::type = true>
- T const *as()
+ T const *as() const
{
if (m_kind == T::kindValue) {
if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
@@ -1035,7 +1235,7 @@ public:
}
template<typename T, typename std::enable_if<!std::is_base_of_v<DomBase, T>, bool>::type = true>
- T const *as()
+ T const *as() const
{
if (m_kind == T::kindValue) {
Q_ASSERT(domTypeIsObjWrap(m_kind) || domTypeIsValueWrap(m_kind));
@@ -1045,67 +1245,54 @@ public:
}
template<typename T>
- std::shared_ptr<T> ownerAs();
+ std::shared_ptr<T> ownerAs() const;
template<typename Owner, typename T>
- DomItem copy(Owner owner, Path ownerPath, T base)
+ DomItem copy(const Owner &owner, const Path &ownerPath, const T &base) const
{
- Q_ASSERT(m_top);
+ Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
static_assert(IsInlineDom<std::decay_t<T>>::value, "Expected an inline item or pointer");
return DomItem(m_top, owner, ownerPath, base);
}
template<typename Owner>
- DomItem copy(Owner owner, Path ownerPath)
+ DomItem copy(const Owner &owner, const Path &ownerPath) const
{
- Q_ASSERT(m_top);
+ Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
return DomItem(m_top, owner, ownerPath, owner.get());
}
template<typename T>
- DomItem copy(T base)
+ DomItem copy(const T &base) const
{
- Q_ASSERT(m_top);
+ Q_ASSERT(!std::holds_alternative<std::monostate>(m_top));
using BaseT = std::decay_t<T>;
static_assert(!std::is_same_v<BaseT, ElementT>,
"variant not supported, pass in the stored types");
- static_assert(IsInlineDom<BaseT>::value, "expected either a pointer or an inline item");
- if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
+ static_assert(IsInlineDom<BaseT>::value || std::is_same_v<BaseT, std::monostate>,
+ "expected either a pointer or an inline item");
+
+ if constexpr (IsSharedPointerToDomObject<BaseT>::value)
return DomItem(m_top, base, Path(), base.get());
- } else {
+ else if constexpr (IsInlineDom<BaseT>::value)
return DomItem(m_top, m_owner, m_ownerPath, base);
- }
+
+ Q_UNREACHABLE_RETURN(DomItem(m_top, m_owner, m_ownerPath, nullptr));
}
private:
- DomBase const *base();
- template <typename T, typename std::enable_if<std::is_base_of<DomBase, T>::value, bool>::type = true>
- T *mutableAs() {
- if (m_kind == T::kindValue) {
- if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
- return static_cast<SimpleObjectWrapBase *>(mutableBase())->mutableAs<T>();
- else
- return static_cast<T *>(mutableBase());
- }
- return nullptr;
- }
+ enum class WriteOutCheckResult { Success, Failed };
+ WriteOutCheckResult performWriteOutChecks(const DomItem &, const DomItem &, OutWriter &, WriteOutChecks) const;
+ const DomBase *base() const;
- template <typename T, typename std::enable_if<!std::is_base_of<DomBase, T>::value, bool>::type = true>
- T *mutableAs() {
- if (m_kind == T::kindValue) {
- Q_ASSERT(domTypeIsObjWrap(m_kind) || domTypeIsValueWrap(m_kind));
- return static_cast<SimpleObjectWrapBase *>(mutableBase())->mutableAs<T>();
- }
- return nullptr;
- }
- DomBase *mutableBase();
template<typename Env, typename Owner>
DomItem(Env, Owner, Path, std::nullptr_t) : DomItem()
{
}
+
template<typename Env, typename Owner, typename T,
typename = std::enable_if_t<IsInlineDom<std::decay_t<T>>::value>>
- DomItem(Env env, Owner owner, Path ownerPath, T el)
+ DomItem(Env env, Owner owner, const Path &ownerPath, const T &el)
: m_top(env), m_owner(owner), m_ownerPath(ownerPath), m_element(el)
{
using BaseT = std::decay_t<T>;
@@ -1113,8 +1300,8 @@ private:
if (!el || el->kind() == DomType::Empty) { // avoid null ptr, and allow only a
// single kind of Empty
m_kind = DomType::Empty;
- m_top.reset();
- m_owner.reset();
+ m_top = std::monostate();
+ m_owner = std::monostate();
m_ownerPath = Path();
m_element = Empty();
} else {
@@ -1144,8 +1331,8 @@ private:
friend class TestDomItem;
friend QMLDOM_EXPORT bool operator==(const DomItem &, const DomItem &);
DomType m_kind = DomType::Empty;
- std::optional<TopT> m_top;
- std::optional<OwnerT> m_owner;
+ TopT m_top;
+ OwnerT m_owner;
Path m_ownerPath;
ElementT m_element = Empty();
};
@@ -1158,123 +1345,179 @@ inline bool operator!=(const DomItem &o1, const DomItem &o2)
}
template<typename T>
-Map Map::fromMultiMapRef(Path pathFromOwner, QMultiMap<QString, T> &mmap)
+static DomItem keyMultiMapHelper(const DomItem &self, const QString &key,
+ const QMultiMap<QString, T> &mmap)
+{
+ auto it = mmap.find(key);
+ auto end = mmap.cend();
+ if (it == end)
+ return DomItem();
+ else {
+ // special case single element (++it == end || it.key() != key)?
+ QList<const T *> values;
+ while (it != end && it.key() == key)
+ values.append(&(*it++));
+ ListP ll(self.pathFromOwner().appendComponent(PathEls::Key(key)), values, QString(),
+ ListOptions::Reverse);
+ return self.copy(ll);
+ }
+}
+
+template<typename T>
+Map Map::fromMultiMapRef(const Path &pathFromOwner, const QMultiMap<QString, T> &mmap)
{
return Map(
pathFromOwner,
- [&mmap](DomItem &self, QString key) {
- auto it = mmap.find(key);
- auto end = mmap.cend();
- if (it == end)
- return DomItem();
- else {
- // special case single element (++it == end || it.key() != key)?
- QList<T *> values;
- while (it != end && it.key() == key)
- values.append(&(*it++));
- ListP ll(self.pathFromOwner().appendComponent(PathEls::Key(key)), values,
- QString(), ListOptions::Reverse);
- return self.copy(ll);
- }
+ [&mmap](const DomItem &self, const QString &key) {
+ return keyMultiMapHelper(self, key, mmap);
},
- [&mmap](DomItem &) { return QSet<QString>(mmap.keyBegin(), mmap.keyEnd()); },
+ [&mmap](const DomItem &) { return QSet<QString>(mmap.keyBegin(), mmap.keyEnd()); },
QLatin1String(typeid(T).name()));
}
template<typename T>
Map Map::fromMapRef(
- Path pathFromOwner, QMap<QString, T> &map,
- std::function<DomItem(DomItem &, const PathEls::PathComponent &, T &)> elWrapper)
+ const Path &pathFromOwner, const QMap<QString, T> &map,
+ const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper)
{
return Map(
pathFromOwner,
- [&map, elWrapper](DomItem &self, QString key) {
- if (!map.contains(key))
+ [&map, elWrapper](const DomItem &self, const QString &key) {
+ const auto it = map.constFind(key);
+ if (it == map.constEnd())
return DomItem();
- else {
- return elWrapper(self, PathEls::Key(key), map[key]);
- }
+ return elWrapper(self, PathEls::Key(key), it.value());
},
- [&map](DomItem &) { return QSet<QString>(map.keyBegin(), map.keyEnd()); },
+ [&map](const DomItem &) { return QSet<QString>(map.keyBegin(), map.keyEnd()); },
QLatin1String(typeid(T).name()));
}
+template<typename MapT>
+QSet<QString> Map::fileRegionKeysFromMap(const MapT &map)
+{
+ QSet<QString> keys;
+ std::transform(map.keyBegin(), map.keyEnd(), std::inserter(keys, keys.begin()), fileLocationRegionName);
+ return keys;
+}
+
+template<typename T>
+Map Map::fromFileRegionMap(const Path &pathFromOwner, const QMap<FileLocationRegion, T> &map)
+{
+ auto result = Map(
+ pathFromOwner,
+ [&map](const DomItem &mapItem, const QString &key) -> DomItem {
+ auto it = map.constFind(fileLocationRegionValue(key));
+ if (it == map.constEnd())
+ return {};
+
+ return mapItem.wrap(PathEls::Key(key), *it);
+ },
+ [&map](const DomItem &) { return fileRegionKeysFromMap(map); },
+ QString::fromLatin1(typeid(T).name()));
+ return result;
+}
+
+template<typename T>
+Map Map::fromFileRegionListMap(const Path &pathFromOwner,
+ const QMap<FileLocationRegion, QList<T>> &map)
+{
+ using namespace Qt::StringLiterals;
+ auto result = Map(
+ pathFromOwner,
+ [&map](const DomItem &mapItem, const QString &key) -> DomItem {
+ const QList<SourceLocation> locations = map.value(fileLocationRegionValue(key));
+ if (locations.empty())
+ return {};
+
+ auto list = List::fromQList<SourceLocation>(
+ mapItem.pathFromOwner(), locations,
+ [](const DomItem &self, const PathEls::PathComponent &path,
+ const SourceLocation &location) {
+ return self.subLocationItem(path, location);
+ });
+ return mapItem.subListItem(list);
+ },
+ [&map](const DomItem &) { return fileRegionKeysFromMap(map); },
+ u"QList<%1>"_s.arg(QString::fromLatin1(typeid(T).name())));
+ return result;
+}
+
template<typename T>
List List::fromQList(
- Path pathFromOwner, QList<T> list,
- std::function<DomItem(DomItem &, const PathEls::PathComponent &, T &)> elWrapper,
+ const Path &pathFromOwner, const QList<T> &list,
+ const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
ListOptions options)
{
index_type len = list.size();
if (options == ListOptions::Reverse) {
return List(
pathFromOwner,
- [list, elWrapper](DomItem &self, index_type i) mutable {
+ [list, elWrapper](const DomItem &self, index_type i) mutable {
if (i < 0 || i >= list.size())
return DomItem();
return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
},
- [len](DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
+ [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
} else {
return List(
pathFromOwner,
- [list, elWrapper](DomItem &self, index_type i) mutable {
+ [list, elWrapper](const DomItem &self, index_type i) mutable {
if (i < 0 || i >= list.size())
return DomItem();
return elWrapper(self, PathEls::Index(i), list[i]);
},
- [len](DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
+ [len](const DomItem &) { return len; }, nullptr, QLatin1String(typeid(T).name()));
}
}
template<typename T>
List List::fromQListRef(
- Path pathFromOwner, QList<T> &list,
- std::function<DomItem(DomItem &, const PathEls::PathComponent &, T &)> elWrapper,
+ const Path &pathFromOwner, const QList<T> &list,
+ const std::function<DomItem(const DomItem &, const PathEls::PathComponent &, const T &)> &elWrapper,
ListOptions options)
{
if (options == ListOptions::Reverse) {
return List(
pathFromOwner,
- [&list, elWrapper](DomItem &self, index_type i) {
+ [&list, elWrapper](const DomItem &self, index_type i) {
if (i < 0 || i >= list.size())
return DomItem();
return elWrapper(self, PathEls::Index(i), list[list.size() - i - 1]);
},
- [&list](DomItem &) { return list.size(); }, nullptr,
+ [&list](const DomItem &) { return list.size(); }, nullptr,
QLatin1String(typeid(T).name()));
} else {
return List(
pathFromOwner,
- [&list, elWrapper](DomItem &self, index_type i) {
+ [&list, elWrapper](const DomItem &self, index_type i) {
if (i < 0 || i >= list.size())
return DomItem();
return elWrapper(self, PathEls::Index(i), list[i]);
},
- [&list](DomItem &) { return list.size(); }, nullptr,
+ [&list](const DomItem &) { return list.size(); }, nullptr,
QLatin1String(typeid(T).name()));
}
}
class QMLDOM_EXPORT OwningItem: public DomBase {
protected:
- virtual std::shared_ptr<OwningItem> doCopy(DomItem &self) const = 0;
+ virtual std::shared_ptr<OwningItem> doCopy(const DomItem &self) const = 0;
public:
OwningItem(const OwningItem &o);
OwningItem(int derivedFrom=0);
- OwningItem(int derivedFrom, QDateTime lastDataUpdateAt);
+ OwningItem(int derivedFrom, const QDateTime &lastDataUpdateAt);
OwningItem(const OwningItem &&) = delete;
OwningItem &operator=(const OwningItem &&) = delete;
static int nextRevision();
- Path canonicalPath(DomItem &self) const override = 0;
+ Path canonicalPath(const DomItem &self) const override = 0;
- bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
- std::shared_ptr<OwningItem> makeCopy(DomItem &self) const { return doCopy(self); }
+ bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override;
+ std::shared_ptr<OwningItem> makeCopy(const DomItem &self) const { return doCopy(self); }
Path pathFromOwner() const { return Path(); }
- Path pathFromOwner(DomItem &) const override final { return Path(); }
- DomItem containingObject(DomItem &self) const override;
+ Path pathFromOwner(const DomItem &) const override final { return Path(); }
+ DomItem containingObject(const DomItem &self) const override;
int derivedFrom() const;
virtual int revision() const;
@@ -1287,18 +1530,20 @@ public:
virtual bool freeze();
QDateTime frozenAt() const;
- virtual void addError(DomItem &self, ErrorMessage msg);
- void addErrorLocal(ErrorMessage msg);
- void clearErrors(ErrorGroups groups = ErrorGroups({}));
+ virtual void addError(const DomItem &self, ErrorMessage &&msg);
+ void addErrorLocal(ErrorMessage &&msg);
+ void clearErrors(const ErrorGroups &groups = ErrorGroups({}));
// return false if a quick exit was requested
- bool iterateErrors(DomItem &self, function_ref<bool(DomItem source, ErrorMessage msg)> visitor,
- Path inPath = Path());
+ bool iterateErrors(
+ const DomItem &self,
+ function_ref<bool(const DomItem &source, const ErrorMessage &msg)> visitor,
+ const Path &inPath = Path());
QMultiMap<Path, ErrorMessage> localErrors() const {
QMutexLocker l(mutex());
return m_errors;
}
- virtual bool iterateSubOwners(DomItem &self, function_ref<bool(DomItem &owner)> visitor);
+ virtual bool iterateSubOwners(const DomItem &self, function_ref<bool(const DomItem &owner)> visitor);
QBasicMutex *mutex() const { return &m_mutex; }
private:
@@ -1313,25 +1558,25 @@ private:
};
template<typename T>
-std::shared_ptr<T> DomItem::ownerAs()
+std::shared_ptr<T> DomItem::ownerAs() const
{
if constexpr (domTypeIsOwningItem(T::kindValue)) {
- if (m_owner) {
+ if (!std::holds_alternative<std::monostate>(m_owner)) {
if constexpr (T::kindValue == DomType::AttachedInfo) {
- if (std::holds_alternative<std::shared_ptr<AttachedInfo>>(*m_owner))
+ if (std::holds_alternative<std::shared_ptr<AttachedInfo>>(m_owner))
return std::static_pointer_cast<T>(
- std::get<std::shared_ptr<AttachedInfo>>(*m_owner));
+ std::get<std::shared_ptr<AttachedInfo>>(m_owner));
} else if constexpr (T::kindValue == DomType::ExternalItemInfo) {
- if (std::holds_alternative<std::shared_ptr<ExternalItemInfoBase>>(*m_owner))
+ if (std::holds_alternative<std::shared_ptr<ExternalItemInfoBase>>(m_owner))
return std::static_pointer_cast<T>(
- std::get<std::shared_ptr<ExternalItemInfoBase>>(*m_owner));
+ std::get<std::shared_ptr<ExternalItemInfoBase>>(m_owner));
} else if constexpr (T::kindValue == DomType::ExternalItemPair) {
- if (std::holds_alternative<std::shared_ptr<ExternalItemPairBase>>(*m_owner))
+ if (std::holds_alternative<std::shared_ptr<ExternalItemPairBase>>(m_owner))
return std::static_pointer_cast<T>(
- std::get<std::shared_ptr<ExternalItemPairBase>>(*m_owner));
+ std::get<std::shared_ptr<ExternalItemPairBase>>(m_owner));
} else {
- if (std::holds_alternative<std::shared_ptr<T>>(*m_owner)) {
- return std::get<std::shared_ptr<T>>(*m_owner);
+ if (std::holds_alternative<std::shared_ptr<T>>(m_owner)) {
+ return std::get<std::shared_ptr<T>>(m_owner);
}
}
}
@@ -1352,26 +1597,26 @@ struct rank<0>
};
template<typename T>
-auto writeOutWrap(const T &t, DomItem &self, OutWriter &lw, rank<1>)
+auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw, rank<1>)
-> decltype(t.writeOut(self, lw))
{
t.writeOut(self, lw);
}
template<typename T>
-auto writeOutWrap(const T &, DomItem &, OutWriter &, rank<0>) -> void
+auto writeOutWrap(const T &, const DomItem &, OutWriter &, rank<0>) -> void
{
qCWarning(writeOutLog) << "Ignoring writeout to wrapped object not supporting it ("
<< typeid(T).name();
}
template<typename T>
-auto writeOutWrap(const T &t, DomItem &self, OutWriter &lw) -> void
+auto writeOutWrap(const T &t, const DomItem &self, OutWriter &lw) -> void
{
writeOutWrap(t, self, lw, rank<1>());
}
template<typename T>
-void SimpleObjectWrapT<T>::writeOut(DomItem &self, OutWriter &lw) const
+void SimpleObjectWrapT<T>::writeOut(const DomItem &self, OutWriter &lw) const
{
writeOutWrap<T>(*asT(), self, lw);
}
@@ -1390,7 +1635,7 @@ public:
QString internalKindStr() { return domTypeToString(internalKind()); }
DomKind domKind() { return kind2domKind(internalKind()); }
- Path canonicalPath() { return m_owner.canonicalPath().path(m_pathFromOwner); }
+ Path canonicalPath() const { return m_owner.canonicalPath().path(m_pathFromOwner); }
MutableDomItem containingObject()
{
if (m_pathFromOwner)
@@ -1458,28 +1703,27 @@ public:
MutableDomItem index(index_type i) { return MutableDomItem(item().index(i)); }
QSet<QString> const keys() { return item().keys(); }
- MutableDomItem key(QString name) { return MutableDomItem(item().key(name)); }
+ MutableDomItem key(const QString &name) { return MutableDomItem(item().key(name)); }
MutableDomItem key(QStringView name) { return key(name.toString()); }
void
- dump(Sink s, int indent = 0,
- function_ref<bool(DomItem &, const PathEls::PathComponent &, DomItem &)> filter = noFilter)
+ dump(const Sink &s, int indent = 0,
+ function_ref<bool(const DomItem &, const PathEls::PathComponent &, const DomItem &)> filter = noFilter)
{
item().dump(s, indent, filter);
}
FileWriter::Status
- dump(QString path,
- function_ref<bool(DomItem &, const PathEls::PathComponent &, DomItem &)> filter = noFilter,
+ 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)
{
return item().dump(path, filter, nBackups, indent, fw);
}
void writeOut(OutWriter &lw) { return item().writeOut(lw); }
- MutableDomItem writeOut(QString path, int nBackups = 2,
- const LineWriterOptions &opt = LineWriterOptions(),
- FileWriter *fw = nullptr)
+ bool writeOut(const QString &path, int nBackups = 2,
+ const LineWriterOptions &opt = LineWriterOptions(), FileWriter *fw = nullptr)
{
- return MutableDomItem(item().writeOut(path, nBackups, opt, fw));
+ return item().writeOut(path, nBackups, opt, fw);
}
MutableDomItem fileLocations() { return MutableDomItem(item().fileLocations()); }
@@ -1487,11 +1731,11 @@ public:
{
return item().makeCopy(option);
}
- bool commitToBase(std::shared_ptr<DomEnvironment> validEnvPtr = nullptr)
+ bool commitToBase(const std::shared_ptr<DomEnvironment> &validEnvPtr = nullptr)
{
return item().commitToBase(validEnvPtr);
}
- QString canonicalFilePath() { return item().canonicalFilePath(); }
+ QString canonicalFilePath() const { return item().canonicalFilePath(); }
MutableDomItem refreshed() { return MutableDomItem(item().refreshed()); }
@@ -1518,41 +1762,36 @@ public:
QDateTime frozenAt() { return m_owner.frozenAt(); }
QDateTime lastDataUpdateAt() { return m_owner.lastDataUpdateAt(); }
- void addError(ErrorMessage msg) { item().addError(msg); }
+ void addError(ErrorMessage &&msg) { item().addError(std::move(msg)); }
ErrorHandler errorHandler();
// convenience setters
- MutableDomItem addPrototypePath(Path prototypePath);
- MutableDomItem setNextScopePath(Path nextScopePath);
+ MutableDomItem addPrototypePath(const Path &prototypePath);
+ MutableDomItem setNextScopePath(const Path &nextScopePath);
MutableDomItem setPropertyDefs(QMultiMap<QString, PropertyDefinition> propertyDefs);
MutableDomItem setBindings(QMultiMap<QString, Binding> bindings);
MutableDomItem setMethods(QMultiMap<QString, MethodInfo> functionDefs);
- MutableDomItem setChildren(QList<QmlObject> children);
- MutableDomItem setAnnotations(QList<QmlObject> annotations);
- MutableDomItem setScript(std::shared_ptr<ScriptExpression> exp);
- MutableDomItem setCode(QString code);
- MutableDomItem addPropertyDef(PropertyDefinition propertyDef,
+ MutableDomItem setChildren(const QList<QmlObject> &children);
+ MutableDomItem setAnnotations(const QList<QmlObject> &annotations);
+ MutableDomItem setScript(const std::shared_ptr<ScriptExpression> &exp);
+ MutableDomItem setCode(const QString &code);
+ MutableDomItem addPropertyDef(const PropertyDefinition &propertyDef,
AddOption option = AddOption::Overwrite);
MutableDomItem addBinding(Binding binding, AddOption option = AddOption::Overwrite);
- MutableDomItem addMethod(MethodInfo functionDef, AddOption option = AddOption::Overwrite);
+ MutableDomItem addMethod(
+ const MethodInfo &functionDef, AddOption option = AddOption::Overwrite);
MutableDomItem addChild(QmlObject child);
MutableDomItem addAnnotation(QmlObject child);
- MutableDomItem addPreComment(const Comment &comment, QString regionName = QString());
- MutableDomItem addPreComment(const Comment &comment, QStringView regionName)
- {
- return addPreComment(comment, regionName.toString());
- }
- MutableDomItem addPostComment(const Comment &comment, QString regionName = QString());
- MutableDomItem addPostComment(const Comment &comment, QStringView regionName)
- {
- return addPostComment(comment, regionName.toString());
- }
+ MutableDomItem addPreComment(const Comment &comment, FileLocationRegion region);
+ MutableDomItem addPostComment(const Comment &comment, FileLocationRegion region);
+ QQmlJSScope::ConstPtr semanticScope();
+ void setSemanticScope(const QQmlJSScope::ConstPtr &scope);
MutableDomItem() = default;
- MutableDomItem(DomItem owner, Path pathFromOwner):
+ MutableDomItem(const DomItem &owner, const Path &pathFromOwner):
m_owner(owner), m_pathFromOwner(pathFromOwner)
{}
- MutableDomItem(DomItem item):
+ MutableDomItem(const DomItem &item):
m_owner(item.owner()), m_pathFromOwner(item.pathFromOwner())
{}
@@ -1568,18 +1807,32 @@ public:
template <typename T>
T *mutableAs() {
Q_ASSERT(!m_owner || !m_owner.owningItemPtr()->frozen());
- return item().mutableAs<T>();
+
+ DomItem self = item();
+ if (self.m_kind != T::kindValue)
+ return nullptr;
+
+ const T *t = nullptr;
+ if constexpr (domTypeIsObjWrap(T::kindValue) || domTypeIsValueWrap(T::kindValue))
+ t = static_cast<const SimpleObjectWrapBase *>(self.base())->as<T>();
+ else if constexpr (std::is_base_of<DomBase, T>::value)
+ t = static_cast<const T *>(self.base());
+ else
+ Q_UNREACHABLE_RETURN(nullptr);
+
+ // Nasty. But since ElementT has to store the const pointers, we allow it in this one place.
+ return const_cast<T *>(t);
}
template<typename T>
- std::shared_ptr<T> ownerAs()
+ std::shared_ptr<T> ownerAs() const
{
return m_owner.ownerAs<T>();
}
// it is dangerous to assume it stays valid when updates are preformed...
- DomItem item() { return m_owner.path(m_pathFromOwner); }
+ DomItem item() const { return m_owner.path(m_pathFromOwner); }
- friend bool operator==(const MutableDomItem o1, const MutableDomItem &o2)
+ friend bool operator==(const MutableDomItem &o1, const MutableDomItem &o2)
{
return o1.m_owner == o2.m_owner && o1.m_pathFromOwner == o2.m_pathFromOwner;
}
@@ -1596,7 +1849,7 @@ private:
QMLDOM_EXPORT QDebug operator<<(QDebug debug, const MutableDomItem &c);
template<typename K, typename T>
-Path insertUpdatableElementInMultiMap(Path mapPathFromOwner, QMultiMap<K, T> &mmap, K key,
+Path insertUpdatableElementInMultiMap(const Path &mapPathFromOwner, QMultiMap<K, T> &mmap, K key,
const T &value, AddOption option = AddOption::KeepExisting,
T **valuePtr = nullptr)
{
@@ -1633,7 +1886,7 @@ Path insertUpdatableElementInMultiMap(Path mapPathFromOwner, QMultiMap<K, T> &mm
}
template<typename T>
-Path appendUpdatableElementInQList(Path listPathFromOwner, QList<T> &list, const T &value,
+Path appendUpdatableElementInQList(const Path &listPathFromOwner, QList<T> &list, const T &value,
T **vPtr = nullptr)
{
int idx = list.size();
@@ -1647,7 +1900,7 @@ Path appendUpdatableElementInQList(Path listPathFromOwner, QList<T> &list, const
}
template <typename T, typename K = QString>
-void updatePathFromOwnerMultiMap(QMultiMap<K, T> &mmap, Path newPath)
+void updatePathFromOwnerMultiMap(QMultiMap<K, T> &mmap, const Path &newPath)
{
auto it = mmap.begin();
auto end = mmap.end();
@@ -1676,7 +1929,7 @@ void updatePathFromOwnerMultiMap(QMultiMap<K, T> &mmap, Path newPath)
}
template <typename T>
-void updatePathFromOwnerQList(QList<T> &list, Path newPath)
+void updatePathFromOwnerQList(QList<T> &list, const Path &newPath)
{
auto it = list.begin();
auto end = list.end();
@@ -1788,9 +2041,14 @@ constexpr bool domTypeIsUnattachedOwningItem(DomType k)
}
}
+constexpr bool domTypeIsScriptElement(DomType k)
+{
+ return DomType::ScriptElementStart <= k && k <= DomType::ScriptElementStop;
+}
+
template<typename T>
-DomItem DomItem::subValueItem(const PathEls::PathComponent &c, T value,
- ConstantData::Options options)
+DomItem DomItem::subValueItem(const PathEls::PathComponent &c, const T &value,
+ ConstantData::Options options) const
{
using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
if constexpr (
@@ -1805,8 +2063,8 @@ DomItem DomItem::subValueItem(const PathEls::PathComponent &c, T value,
} else if constexpr (IsList<T>::value && !std::is_convertible_v<BaseT, QStringView>) {
return subListItem(List::fromQList<typename BaseT::value_type>(
pathFromOwner().appendComponent(c), value,
- [options](DomItem &list, const PathEls::PathComponent &p,
- typename T::value_type &v) { return list.subValueItem(p, v, options); }));
+ [options](const DomItem &list, const PathEls::PathComponent &p,
+ const typename T::value_type &v) { return list.subValueItem(p, v, options); }));
} else if constexpr (IsSharedPointerToDomObject<BaseT>::value) {
Q_UNUSED(options);
return subOwnerItem(c, value);
@@ -1816,8 +2074,8 @@ DomItem DomItem::subValueItem(const PathEls::PathComponent &c, T value,
}
template<typename T>
-DomItem DomItem::subDataItem(const PathEls::PathComponent &c, T value,
- ConstantData::Options options)
+DomItem DomItem::subDataItem(const PathEls::PathComponent &c, const T &value,
+ ConstantData::Options options) const
{
using BaseT = std::remove_cv_t<std::remove_reference_t<T>>;
if constexpr (std::is_same_v<BaseT, ConstantData>) {
@@ -1833,8 +2091,8 @@ DomItem DomItem::subDataItem(const PathEls::PathComponent &c, T value,
}
template<typename T>
-bool DomItem::dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, T value,
- ConstantData::Options options)
+bool DomItem::dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, const T &value,
+ ConstantData::Options options) const
{
auto lazyWrap = [this, &c, &value, options]() {
return this->subValueItem<T>(c, value, options);
@@ -1844,7 +2102,7 @@ bool DomItem::dvValue(DirectVisitor visitor, const PathEls::PathComponent &c, T
template<typename F>
bool DomItem::dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c, F valueF,
- ConstantData::Options options)
+ ConstantData::Options options) const
{
auto lazyWrap = [this, &c, &valueF, options]() {
return this->subValueItem<decltype(valueF())>(c, valueF(), options);
@@ -1853,7 +2111,7 @@ bool DomItem::dvValueLazy(DirectVisitor visitor, const PathEls::PathComponent &c
}
template<typename T>
-DomItem DomItem::wrap(const PathEls::PathComponent &c, T &obj)
+DomItem DomItem::wrap(const PathEls::PathComponent &c, const T &obj) const
{
using BaseT = std::decay_t<T>;
if constexpr (std::is_same_v<QString, BaseT> || std::is_arithmetic_v<BaseT>) {
@@ -1904,8 +2162,8 @@ DomItem DomItem::wrap(const PathEls::PathComponent &c, T &obj)
if constexpr (std::is_same_v<typename BaseT::key_type, QString>) {
return subMapItem(Map::fromMapRef<typename BaseT::mapped_type>(
pathFromOwner().appendComponent(c), obj,
- [](DomItem &map, const PathEls::PathComponent &p,
- typename BaseT::mapped_type &el) { return map.wrap(p, el); }));
+ [](const DomItem &map, const PathEls::PathComponent &p,
+ const typename BaseT::mapped_type &el) { return map.wrap(p, el); }));
} else {
Q_ASSERT_X(false, "DomItem::wrap", "non string keys not supported (try .toString()?)");
}
@@ -1913,8 +2171,8 @@ DomItem DomItem::wrap(const PathEls::PathComponent &c, T &obj)
if constexpr (IsDomObject<typename BaseT::value_type>::value) {
return subListItem(List::fromQListRef<typename BaseT::value_type>(
pathFromOwner().appendComponent(c), obj,
- [](DomItem &list, const PathEls::PathComponent &p,
- typename BaseT::value_type &el) { return list.wrap(p, el); }));
+ [](const DomItem &list, const PathEls::PathComponent &p,
+ const typename BaseT::value_type &el) { return list.wrap(p, el); }));
} else {
Q_ASSERT_X(false, "DomItem::wrap", "Unsupported list type T");
return DomItem();
@@ -1927,14 +2185,14 @@ DomItem DomItem::wrap(const PathEls::PathComponent &c, T &obj)
}
template<typename T>
-bool DomItem::dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj)
+bool DomItem::dvWrap(DirectVisitor visitor, const PathEls::PathComponent &c, T &obj) const
{
auto lazyWrap = [this, &c, &obj]() { return this->wrap<T>(c, obj); };
return visitor(c, lazyWrap);
}
template<typename T>
-bool ListPT<T>::iterateDirectSubpaths(DomItem &self, DirectVisitor v)
+bool ListPT<T>::iterateDirectSubpaths(const DomItem &self, DirectVisitor v) const
{
index_type len = index_type(m_pList.size());
for (index_type i = 0; i < len; ++i) {
@@ -1945,10 +2203,10 @@ bool ListPT<T>::iterateDirectSubpaths(DomItem &self, DirectVisitor v)
}
template<typename T>
-DomItem ListPT<T>::index(DomItem &self, index_type index) const
+DomItem ListPT<T>::index(const DomItem &self, index_type index) const
{
if (index >= 0 && index < m_pList.size())
- return self.wrap(PathEls::Index(index), *reinterpret_cast<T *>(m_pList.value(index)));
+ return self.wrap(PathEls::Index(index), *static_cast<const T *>(m_pList.value(index)));
return DomItem();
}
@@ -1958,13 +2216,13 @@ inline DomKind DomBase::domKind() const
return kind2domKind(kind());
}
-inline bool DomBase::iterateDirectSubpathsConst(DomItem &self, DirectVisitor visitor) const
+inline bool DomBase::iterateDirectSubpathsConst(const DomItem &self, DirectVisitor visitor) const
{
Q_ASSERT(self.base() == this);
- return self.iterateDirectSubpaths(visitor);
+ return self.iterateDirectSubpaths(std::move(visitor));
}
-inline DomItem DomBase::containingObject(DomItem &self) const
+inline DomItem DomBase::containingObject(const DomItem &self) const
{
Path path = pathFromOwner(self);
DomItem base = self.owner();
@@ -1986,7 +2244,7 @@ inline QString DomBase::typeName() const
return domTypeToString(kind());
}
-inline QList<QString> DomBase::fields(DomItem &self) const
+inline QList<QString> DomBase::fields(const DomItem &self) const
{
QList<QString> res;
self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
@@ -1997,7 +2255,7 @@ inline QList<QString> DomBase::fields(DomItem &self) const
return res;
}
-inline DomItem DomBase::field(DomItem &self, QStringView name) const
+inline DomItem DomBase::field(const DomItem &self, QStringView name) const
{
DomItem res;
self.iterateDirectSubpaths(
@@ -2011,7 +2269,7 @@ inline DomItem DomBase::field(DomItem &self, QStringView name) const
return res;
}
-inline index_type DomBase::indexes(DomItem &self) const
+inline index_type DomBase::indexes(const DomItem &self) const
{
index_type res = 0;
self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
@@ -2025,7 +2283,7 @@ inline index_type DomBase::indexes(DomItem &self) const
return res;
}
-inline DomItem DomBase::index(DomItem &self, qint64 index) const
+inline DomItem DomBase::index(const DomItem &self, qint64 index) const
{
DomItem res;
self.iterateDirectSubpaths(
@@ -2039,7 +2297,7 @@ inline DomItem DomBase::index(DomItem &self, qint64 index) const
return res;
}
-inline QSet<QString> const DomBase::keys(DomItem &self) const
+inline QSet<QString> const DomBase::keys(const DomItem &self) const
{
QSet<QString> res;
self.iterateDirectSubpaths([&res](const PathEls::PathComponent &c, function_ref<DomItem()>) {
@@ -2050,7 +2308,7 @@ inline QSet<QString> const DomBase::keys(DomItem &self) const
return res;
}
-inline DomItem DomBase::key(DomItem &self, QString name) const
+inline DomItem DomBase::key(const DomItem &self, const QString &name) const
{
DomItem res;
self.iterateDirectSubpaths(
@@ -2064,12 +2322,12 @@ inline DomItem DomBase::key(DomItem &self, QString name) const
return res;
}
-inline DomItem DomItem::subListItem(const List &list)
+inline DomItem DomItem::subListItem(const List &list) const
{
return DomItem(m_top, m_owner, m_ownerPath, list);
}
-inline DomItem DomItem::subMapItem(const Map &map)
+inline DomItem DomItem::subMapItem(const Map &map) const
{
return DomItem(m_top, m_owner, m_ownerPath, map);
}