aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmldom/qqmldompath_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmldom/qqmldompath_p.h')
-rw-r--r--src/qmldom/qqmldompath_p.h880
1 files changed, 464 insertions, 416 deletions
diff --git a/src/qmldom/qqmldompath_p.h b/src/qmldom/qqmldompath_p.h
index 839a34a233..1a5af85e8e 100644
--- a/src/qmldom/qqmldompath_p.h
+++ b/src/qmldom/qqmldompath_p.h
@@ -1,40 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
#ifndef QMLDOM_PATH_H
#define QMLDOM_PATH_H
@@ -103,82 +69,72 @@ class Filter;
class Base {
public:
- virtual ~Base() = default;
- virtual Kind kind() const = 0;
- virtual QString name() const = 0;
- virtual bool checkName(QStringView s) const = 0;
- virtual QStringView stringView() const { return QStringView(); }
- virtual index_type index(index_type defaultValue=-1) const { return defaultValue; }
-
- virtual void dump(Sink sink) const;
- virtual bool hasSquareBrackets() const { return false; }
-
- // casting, could use optional, but that is c++17...
- virtual const Empty *asEmpty() const { return nullptr; }
- virtual const Field *asField() const { return nullptr; }
- virtual const Index *asIndex() const { return nullptr; }
- virtual const Key *asKey() const { return nullptr; }
- virtual const Root *asRoot() const { return nullptr; }
- virtual const Current *asCurrent() const { return nullptr; }
- virtual const Any *asAny() const { return nullptr; }
- virtual const Filter *asFilter() const { return nullptr; }
+ QStringView stringView() const { return QStringView(); }
+ index_type index(index_type defaultValue = -1) const { return defaultValue; }
+ bool hasSquareBrackets() const { return false; }
+
+protected:
+ void dump(const Sink &sink, const QString &name, bool hasSquareBrackets) const;
};
-class Empty: public Base {
+class Empty final : public Base
+{
public:
- Kind kind() const override { return Kind::Empty; }
- QString name() const override { return QString(); }
- bool checkName(QStringView s) const override { return s.isEmpty(); }
- const Empty * asEmpty() const override { return this; }
+ Empty() = default;
+ QString name() const { return QString(); }
+ bool checkName(QStringView s) const { return s.isEmpty(); }
+ void dump(const Sink &sink) const { Base::dump(sink, name(), hasSquareBrackets()); }
};
-class Field: public Base {
+class Field final : public Base
+{
public:
+ Field() = default;
Field(QStringView n): fieldName(n) {}
- Kind kind() const override { return Kind::Field; }
- QString name() const override { return fieldName.toString(); }
- bool checkName(QStringView s) const override { return s == fieldName; }
- QStringView stringView() const override { return fieldName; }
- const Field * asField() const override { return this; }
- void dump(Sink sink) const override { sink(fieldName); }
+ QString name() const { return fieldName.toString(); }
+ bool checkName(QStringView s) const { return s == fieldName; }
+ QStringView stringView() const { return fieldName; }
+ void dump(const Sink &sink) const { sink(fieldName); }
QStringView fieldName;
};
-class Index: public Base {
+class Index final : public Base
+{
public:
+ Index() = default;
Index(index_type i): indexValue(i) {}
- Kind kind() const override { return Kind::Index; }
- QString name() const override { return QString::number(indexValue); }
- bool checkName(QStringView s) const override { return s == name(); }
- index_type index(index_type = -1) const override { return indexValue; }
- bool hasSquareBrackets() const override { return true; }
- const Index * asIndex() const override { return this; }
-
- index_type indexValue;
+ QString name() const { return QString::number(indexValue); }
+ bool checkName(QStringView s) const { return s == name(); }
+ index_type index(index_type = -1) const { return indexValue; }
+ void dump(const Sink &sink) const { Base::dump(sink, name(), hasSquareBrackets()); }
+ bool hasSquareBrackets() const { return true; }
+
+ index_type indexValue = -1;
};
-class Key: public Base {
+class Key final : public Base
+{
public:
- Key(QStringView n): keyValue(n) {}
- Kind kind() const override { return Kind::Key; }
- QString name() const override { return keyValue.toString(); }
- bool checkName(QStringView s) const override { return s == keyValue; }
- QStringView stringView() const override { return keyValue; }
- void dump(Sink sink) const override {
+ Key() = default;
+ Key(const QString &n) : keyValue(n) { }
+ QString name() const { return keyValue; }
+ bool checkName(QStringView s) const { return s == keyValue; }
+ QStringView stringView() const { return keyValue; }
+ void dump(const Sink &sink) const {
sink(u"[");
sinkEscaped(sink, keyValue);
sink(u"]");
}
- bool hasSquareBrackets() const override { return true; }
- const Key * asKey() const override { return this; }
+ bool hasSquareBrackets() const { return true; }
- QStringView keyValue;
+ QString keyValue;
};
-class Root: public Base {
+class Root final : public Base
+{
public:
- Root(): contextKind(PathRoot::Other), contextName() {}
+ Root() = default;
Root(PathRoot r): contextKind(r), contextName() {}
Root(QStringView n) {
QMetaEnum metaEnum = QMetaEnum::fromType<PathRoot>();
@@ -189,8 +145,7 @@ public:
if (contextKind == PathRoot::Other)
contextName = n;
}
- Kind kind() const override { return Kind::Root; }
- QString name() const override {
+ QString name() const {
switch (contextKind) {
case PathRoot::Modules:
return QStringLiteral(u"$modules");
@@ -210,24 +165,22 @@ public:
Q_ASSERT(false && "Unexpected contextKind in name");
return QString();
}
- bool checkName(QStringView s) const override {
+ bool checkName(QStringView s) const {
if (contextKind != PathRoot::Other)
return s.compare(name(), Qt::CaseInsensitive) == 0;
return s.startsWith(QChar::fromLatin1('$')) && s.mid(1) == contextName;
}
- QStringView stringView() const override { return contextName; }
- void dump(Sink sink) const override {
- sink(name());
- }
- const Root *asRoot() const override { return this; }
+ QStringView stringView() const { return contextName; }
+ void dump(const Sink &sink) const { sink(name()); }
- PathRoot contextKind;
+ PathRoot contextKind = PathRoot::Other;
QStringView contextName;
};
-class Current: public Base {
+class Current final : public Base
+{
public:
- Current(): contextName() {}
+ Current() = default;
Current(PathCurrent c): contextKind(c) {}
Current(QStringView n) {
QMetaEnum metaEnum = QMetaEnum::fromType<PathCurrent>();
@@ -238,8 +191,7 @@ public:
if (contextKind == PathCurrent::Other)
contextName = n;
}
- Kind kind() const override { return Kind::Current; }
- QString name() const override {
+ QString name() const {
switch (contextKind) {
case PathCurrent::Other:
return QString::fromUtf8("@").append(contextName.toString());
@@ -267,172 +219,126 @@ public:
Q_ASSERT(false && "Unexpected contextKind in Current::name");
return QString();
}
- bool checkName(QStringView s) const override {
+ bool checkName(QStringView s) const {
if (contextKind != PathCurrent::Other)
return s.compare(name(), Qt::CaseInsensitive) == 0;
return s.startsWith(QChar::fromLatin1('@')) && s.mid(1) == contextName;
}
- QStringView stringView() const override { return contextName; }
- const Current *asCurrent() const override { return this; }
+ QStringView stringView() const { return contextName; }
+ void dump(const Sink &sink) const { Base::dump(sink, name(), hasSquareBrackets()); }
- PathCurrent contextKind;
+ PathCurrent contextKind = PathCurrent::Other;
QStringView contextName;
};
-class Any: public Base {
+class Any final : public Base
+{
public:
- Kind kind() const override { return Kind::Any; }
- QString name() const override { return QLatin1String("*"); }
- bool checkName(QStringView s) const override { return s == u"*"; }
- bool hasSquareBrackets() const override { return true; }
- const Any *asAny() const override { return this; }
+ Any() = default;
+ QString name() const { return QLatin1String("*"); }
+ bool checkName(QStringView s) const { return s == u"*"; }
+ void dump(const Sink &sink) const { Base::dump(sink, name(), hasSquareBrackets()); }
+ bool hasSquareBrackets() const { return true; }
};
-class QMLDOM_EXPORT Filter: public Base {
+class QMLDOM_EXPORT Filter final : public Base
+{
public:
- Filter(std::function<bool(DomItem)> f, QStringView filterDescription = u"<native code filter>");
- Kind kind() const override { return Kind::Filter; }
- QString name() const override;
- bool checkName(QStringView s) const override;
- QStringView stringView() const override { return filterDescription; }
- bool hasSquareBrackets() const override { return true; }
- const Filter *asFilter() const override { return this; }
-
- std::function<bool(DomItem)> filterFunction;
+ Filter() = default;
+ Filter(const std::function<bool(const DomItem &)> &f,
+ QStringView filterDescription = u"<native code filter>");
+ QString name() const;
+ bool checkName(QStringView s) const;
+ QStringView stringView() const { return filterDescription; }
+ void dump(const Sink &sink) const { Base::dump(sink, name(), hasSquareBrackets()); }
+ bool hasSquareBrackets() const { return true; }
+
+ std::function<bool(const DomItem &)> filterFunction;
QStringView filterDescription;
};
class QMLDOM_EXPORT PathComponent {
public:
- PathComponent(): data() {}
- ~PathComponent();
-
- Kind kind() const { return base()->kind(); }
- QString name() const { return base()->name(); };
- bool checkName(QStringView s) const { return base()->checkName(s); }
- QStringView stringView() const { return base()->stringView(); };
- index_type index(index_type defaultValue=-1) const { return base()->index(defaultValue); }
- void dump(Sink sink) const { base()->dump(sink); }
- bool hasSquareBrackets() const { return base()->hasSquareBrackets(); }
-
- const Empty *asEmpty() const { return base()->asEmpty(); }
- const Field *asField() const { return base()->asField(); }
- const Index *asIndex() const { return base()->asIndex(); }
- const Key *asKey() const { return base()->asKey(); }
- const Root *asRoot() const { return base()->asRoot(); }
- const Current *asCurrent() const { return base()->asCurrent(); }
- const Any *asAny() const { return base()->asAny(); }
+ PathComponent() = default;
+ PathComponent(const PathComponent &) = default;
+ PathComponent(PathComponent &&) = default;
+ PathComponent &operator=(const PathComponent &) = default;
+ PathComponent &operator=(PathComponent &&) = default;
+ ~PathComponent() = default;
+
+ Kind kind() const { return Kind(m_data.index()); }
+
+ QString name() const
+ {
+ return std::visit([](auto &&d) { return d.name(); }, m_data);
+ }
+
+ bool checkName(QStringView s) const
+ {
+ return std::visit([s](auto &&d) { return d.checkName(s); }, m_data);
+ }
+
+ QStringView stringView() const
+ {
+ return std::visit([](auto &&d) { return d.stringView(); }, m_data);
+ }
+
+ index_type index(index_type defaultValue=-1) const
+ {
+ return std::visit([defaultValue](auto &&d) { return d.index(defaultValue); }, m_data);
+ }
+
+ void dump(const Sink &sink) const
+ {
+ return std::visit([sink](auto &&d) { return d.dump(sink); }, m_data);
+ }
+
+ bool hasSquareBrackets() const
+ {
+ return std::visit([](auto &&d) { return d.hasSquareBrackets(); }, m_data);
+ }
+
+ const Empty *asEmpty() const { return std::get_if<Empty>(&m_data); }
+ const Field *asField() const { return std::get_if<Field>(&m_data); }
+ const Index *asIndex() const { return std::get_if<Index>(&m_data); }
+ const Key *asKey() const { return std::get_if<Key>(&m_data); }
+ const Root *asRoot() const { return std::get_if<Root>(&m_data); }
+ const Current *asCurrent() const { return std::get_if<Current>(&m_data); }
+ const Any *asAny() const { return std::get_if<Any>(&m_data); }
+ const Filter *asFilter() const { return std::get_if<Filter>(&m_data); }
+
static int cmp(const PathComponent &p1, const PathComponent &p2);
+
+ PathComponent(Empty &&o): m_data(std::move(o)) {}
+ PathComponent(Field &&o): m_data(std::move(o)) {}
+ PathComponent(Index &&o): m_data(std::move(o)) {}
+ PathComponent(Key &&o): m_data(std::move(o)) {}
+ PathComponent(Root &&o): m_data(std::move(o)) {}
+ PathComponent(Current &&o): m_data(std::move(o)) {}
+ PathComponent(Any &&o): m_data(std::move(o)) {}
+ PathComponent(Filter &&o): m_data(std::move(o)) {}
+
private:
friend class QQmlJS::Dom::Path;
friend class QQmlJS::Dom::PathEls::TestPaths;
- PathComponent(const Empty &o): data(o) {}
- PathComponent(const Field &o): data(o) {}
- PathComponent(const Index &o): data(o) {}
- PathComponent(const Key &o): data(o) {}
- PathComponent(const Root &o): data(o) {}
- PathComponent(const Current &o): data(o) {}
- PathComponent(const Any &o): data(o) {}
- PathComponent(const Filter &o): data(o) {}
-
- Base *base() {
- return reinterpret_cast<Base*>(&data);
- }
- const Base *base() const {
- return reinterpret_cast<const Base*>(&data);
- }
- union Data {
- Data(): empty() { }
- Data(const Data &d) {
- switch (d.kind()){
- case Kind::Empty:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&empty) && "non C++11 compliant compiler");
- new (&empty) Empty(d.empty);
- break;
- case Kind::Field:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&field) && "non C++11 compliant compiler");
- new (&field) Field(d.field);
- break;
- case Kind::Index:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&index) && "non C++11 compliant compiler");
- new (&index) Index(d.index);
- break;
- case Kind::Key:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&key) && "non C++11 compliant compiler");
- new (&key) Key(d.key);
- break;
- case Kind::Root:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&root) && "non C++11 compliant compiler");
- new (&root) Root(d.root);
- break;
- case Kind::Current:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&current) && "non C++11 compliant compiler");
- new (&current) Current(d.current);
- break;
- case Kind::Any:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&any) && "non C++11 compliant compiler");
- new (&any) Any(d.any);
- break;
- case Kind::Filter:
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&filter) && "non C++11 compliant compiler");
- new (&filter) Filter(d.filter);
- break;
- }
- }
- Data(const Empty &o) {
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&empty) && "non C++11 compliant compiler");
- new (&empty) Empty(o);
- }
- Data(const Field &o) {
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&field) && "non C++11 compliant compiler");
- new (&field) Field(o);
- }
- Data(const Index &o){
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&index) && "non C++11 compliant compiler");
- new (&index) Index(o);
- }
- Data(const Key &o) {
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&key) && "non C++11 compliant compiler");
- new (&key) Key(o);
- }
- Data(const Root &o) {
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&root) && "non C++11 compliant compiler");
- new (&root) Root(o);
- }
- Data(const Current &o) {
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&current) && "non C++11 compliant compiler");
- new (&current) Current(o);
- }
- Data(const Any &o) {
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&any) && "non C++11 compliant compiler");
- new (&any) Any(o);
- }
- Data(const Filter &o) {
- Q_ASSERT(static_cast<void*>(this)==static_cast<void*>(&filter) && "non C++11 compliant compiler");
- new (&filter) Filter(o);
- }
- Data &operator=(const Data &d) {
- Q_ASSERT(this != &d);
- this->~Data(); // destruct & construct new...
- new (this)Data(d);
- return *this;
- }
- Kind kind() const {
- return reinterpret_cast<const Base*>(this)->kind();
- }
- ~Data() {
- reinterpret_cast<const Base*>(this)->~Base();
- }
- Empty empty;
- Field field;
- Index index;
- Key key;
- Root root;
- Current current;
- Any any;
- Filter filter;
- } data;
+ using Variant = std::variant<Empty, Field, Index, Key, Root, Current, Any, Filter>;
+
+ template<typename T, Kind K>
+ static constexpr bool variantTypeMatches
+ = std::is_same_v<std::variant_alternative_t<size_t(K), Variant>, T>;
+
+ static_assert(size_t(Kind::Empty) == 0);
+ static_assert(variantTypeMatches<Empty, Kind::Empty>);
+ static_assert(variantTypeMatches<Field, Kind::Field>);
+ static_assert(variantTypeMatches<Key, Kind::Key>);
+ static_assert(variantTypeMatches<Root, Kind::Root>);
+ static_assert(variantTypeMatches<Current, Kind::Current>);
+ static_assert(variantTypeMatches<Any, Kind::Any>);
+ static_assert(variantTypeMatches<Filter, Kind::Filter>);
+ static_assert(std::variant_size_v<Variant> == size_t(Kind::Filter) + 1);
+
+ Variant m_data;
};
inline bool operator==(const PathComponent& lhs, const PathComponent& rhs){ return PathComponent::cmp(lhs,rhs) == 0; }
@@ -444,9 +350,13 @@ inline bool operator>=(const PathComponent& lhs, const PathComponent& rhs){ retu
class PathData {
public:
- PathData(QStringList strData, QVector<PathComponent> components): strData(strData), components(components) {}
- PathData(QStringList strData, QVector<PathComponent> components, std::shared_ptr<PathData> parent):
- strData(strData), components(components), parent(parent) {}
+ PathData(const QStringList &strData, const QVector<PathComponent> &components)
+ : strData(strData), components(components)
+ {}
+ PathData(const QStringList &strData, const QVector<PathComponent> &components,
+ const std::shared_ptr<PathData> &parent)
+ : strData(strData), components(components), parent(parent)
+ {}
QStringList strData;
QVector<PathComponent> components;
@@ -455,149 +365,251 @@ public:
} // namespace PathEls
-#define QMLDOM_USTRING(name) constexpr const auto name = u#name
+#define QMLDOM_USTRING(s) u##s
+#define QMLDOM_FIELD(name) inline constexpr const auto name = QMLDOM_USTRING(#name)
+/*!
+ \internal
+ In an ideal world, the Fields namespace would be an enum, not strings.
+ Use FieldType whenever you expect a static String from the Fields namespace instead of an
+ arbitrary QStringView.
+ */
+using FieldType = QStringView;
// namespace, so it cam be reopened to add more entries
namespace Fields{
-constexpr const auto access = u"access";
-constexpr const auto annotations = u"annotations";
-constexpr const auto attachedType = u"attachedType";
-constexpr const auto attachedTypeName = u"attachedTypeName";
-constexpr const auto autoExport = u"autoExport";
-constexpr const auto base = u"base";
-constexpr const auto bindingType = u"bindingType";
-constexpr const auto bindings = u"bindings";
-constexpr const auto body = u"body";
-constexpr const auto canonicalFilePath = u"canonicalFilePath";
-constexpr const auto canonicalPath = u"canonicalPath";
-constexpr const auto children = u"children";
-constexpr const auto classNames = u"classNames";
-constexpr const auto code = u"code";
-constexpr const auto components = u"components";
-constexpr const auto contents = u"contents";
-constexpr const auto contentsDate = u"contentsDate";
-constexpr const auto currentExposedAt = u"currentExposedAt";
-constexpr const auto currentIsValid = u"currentIsValid";
-constexpr const auto currentItem = u"currentItem";
-constexpr const auto currentRevision = u"currentRevision";
-constexpr const auto defaultPropertyName = u"defaultPropertyName";
-constexpr const auto designerSupported = u"designerSupported";
-constexpr const auto elementCanonicalPath = u"elementCanonicalPath";
-constexpr const auto enumerations = u"enumerations";
-constexpr const auto errors = u"errors";
-constexpr const auto exportSource = u"exportSource";
-constexpr const auto exports = u"exports";
-constexpr const auto extraRequired = u"extraRequired";
-constexpr const auto fileName = u"fileName";
-constexpr const auto get = u"get";
-constexpr const auto globalScopeName = u"globalScopeName";
-constexpr const auto globalScopeWithName = u"globalScopeWithName";
-constexpr const auto hasCallback = u"hasCallback";
-constexpr const auto idStr = u"idStr";
-constexpr const auto ids = u"ids";
-constexpr const auto import = u"import";
-constexpr const auto importId = u"importId";
-constexpr const auto imports = u"imports";
-constexpr const auto inheritVersion = u"inheritVersion";
-constexpr const auto inProgress = u"inProgress";
-constexpr const auto isAlias = u"isAlias";
-constexpr const auto isComposite = u"isComposite";
-constexpr const auto isCreatable = u"isCreatable";
-constexpr const auto isDefaultMember = u"isDefaultMember";
-constexpr const auto isInternal = u"isInternal";
-constexpr const auto isLatest = u"isLatest";
-constexpr const auto isList = u"isList";
-constexpr const auto isPointer = u"isPointer";
-constexpr const auto isRequired = u"isRequired";
-constexpr const auto isSingleton = u"isSingleton";
-constexpr const auto isValid = u"isValid";
-constexpr const auto isWritable = u"isWritable";
-constexpr const auto jsFileWithPath = u"jsFileWithPath";
-constexpr const auto kind = u"kind";
-constexpr const auto lastRevision = u"lastRevision";
-constexpr const auto lastValidRevision = u"lastValidRevision";
-constexpr const auto loadInfo = u"loadInfo";
-constexpr const auto loadOptions = u"loadOptions";
-constexpr const auto loadPaths = u"loadPaths";
-constexpr const auto loadsWithWork = u"loadsWithWork";
-constexpr const auto location = u"location";
-constexpr const auto logicalPath = u"logicalPath";
-constexpr const auto majorVersion = u"majorVersion";
-constexpr const auto metaRevisions = u"metaRevisions";
-constexpr const auto methodType = u"methodType";
-constexpr const auto methods = u"methods";
-constexpr const auto minorVersion = u"minorVersion";
-constexpr const auto moduleIndex = u"moduleIndex";
-constexpr const auto moduleIndexWithUri = u"moduleIndexWithUri";
-constexpr const auto moduleScope = u"moduleScope";
-constexpr const auto nAllLoadedCallbacks = u"nAllLoadedCallbacks";
-constexpr const auto nCallbacks = u"nCallbacks";
-constexpr const auto nLoaded = u"nLoaded";
-constexpr const auto nNotdone = u"nNotdone";
-constexpr const auto name = u"name";
-constexpr const auto nextScope = u"nextScope";
-constexpr const auto objects = u"objects";
-constexpr const auto onAttachedObject = u"onAttachedObject";
-constexpr const auto options = u"options";
-constexpr const auto parameters = u"parameters";
-constexpr const auto parentObject = u"parentObject";
-constexpr const auto path = u"path";
-constexpr const auto plugins = u"plugins";
-constexpr const auto pragma = u"pragma";
-constexpr const auto pragmas = u"pragmas";
-constexpr const auto propertyDef = u"propertyDef";
-constexpr const auto propertyDefRef = u"propertyDefRef";
-constexpr const auto propertyDefs = u"propertyDefs";
-constexpr const auto propertyName = u"propertyName";
-constexpr const auto prototype = u"prototype";
-constexpr const auto qmlDirectoryWithPath = u"qmlDirectoryWithPath";
-constexpr const auto qmlFileWithPath = u"qmlFileWithPath";
-constexpr const auto qmldirFileWithPath = u"qmldirFileWithPath";
-constexpr const auto qmltypesFileWithPath = u"qmltypesFileWithPath";
-constexpr const auto qmltypesFiles = u"qmltypesFiles";
-constexpr const auto queue = u"queue";
-constexpr const auto referredObject = u"referredObject";
-constexpr const auto referredObjectPath = u"referredObjectPath";
-constexpr const auto requestedAt = u"requestedAt";
-constexpr const auto requestingUniverse = u"requestingUniverse";
-constexpr const auto returnType = u"returnType";
-constexpr const auto returnTypeName = u"returnTypeName";
-constexpr const auto rootComponent = u"rootComponent";
-constexpr const auto sources = u"sources";
-constexpr const auto status = u"status";
-constexpr const auto stringValue = u"stringValue";
-constexpr const auto symbols = u"symbols";
-constexpr const auto target = u"target";
-constexpr const auto targetPropertyName = u"targetPropertyName";
-constexpr const auto type = u"type";
-constexpr const auto typeName = u"typeName";
-constexpr const auto types = u"types";
-constexpr const auto universe = u"universe";
-constexpr const auto uri = u"uri";
-constexpr const auto uris = u"uris";
-constexpr const auto validExposedAt = u"validExposedAt";
-constexpr const auto validItem = u"validItem";
-constexpr const auto value = u"value";
-constexpr const auto values = u"values";
-constexpr const auto version = u"version";
-constexpr const auto when = u"when";
-}
+QMLDOM_FIELD(access);
+QMLDOM_FIELD(accessSemantics);
+QMLDOM_FIELD(allSources);
+QMLDOM_FIELD(alternative);
+QMLDOM_FIELD(annotations);
+QMLDOM_FIELD(arguments);
+QMLDOM_FIELD(astComments);
+QMLDOM_FIELD(astRelocatableDump);
+QMLDOM_FIELD(attachedType);
+QMLDOM_FIELD(attachedTypeName);
+QMLDOM_FIELD(autoExports);
+QMLDOM_FIELD(base);
+QMLDOM_FIELD(binaryExpression);
+QMLDOM_FIELD(bindable);
+QMLDOM_FIELD(bindingElement);
+QMLDOM_FIELD(bindingIdentifiers);
+QMLDOM_FIELD(bindingType);
+QMLDOM_FIELD(bindings);
+QMLDOM_FIELD(block);
+QMLDOM_FIELD(body);
+QMLDOM_FIELD(callee);
+QMLDOM_FIELD(canonicalFilePath);
+QMLDOM_FIELD(canonicalPath);
+QMLDOM_FIELD(caseBlock);
+QMLDOM_FIELD(caseClause);
+QMLDOM_FIELD(caseClauses);
+QMLDOM_FIELD(catchBlock);
+QMLDOM_FIELD(catchParameter);
+QMLDOM_FIELD(children);
+QMLDOM_FIELD(classNames);
+QMLDOM_FIELD(code);
+QMLDOM_FIELD(commentedElements);
+QMLDOM_FIELD(comments);
+QMLDOM_FIELD(components);
+QMLDOM_FIELD(condition);
+QMLDOM_FIELD(consequence);
+QMLDOM_FIELD(contents);
+QMLDOM_FIELD(contentsDate);
+QMLDOM_FIELD(cppType);
+QMLDOM_FIELD(currentExposedAt);
+QMLDOM_FIELD(currentIsValid);
+QMLDOM_FIELD(currentItem);
+QMLDOM_FIELD(currentRevision);
+QMLDOM_FIELD(declarations);
+QMLDOM_FIELD(defaultClause);
+QMLDOM_FIELD(defaultPropertyName);
+QMLDOM_FIELD(defaultValue);
+QMLDOM_FIELD(designerSupported);
+QMLDOM_FIELD(elLocation);
+QMLDOM_FIELD(elements);
+QMLDOM_FIELD(elementCanonicalPath);
+QMLDOM_FIELD(enumerations);
+QMLDOM_FIELD(errors);
+QMLDOM_FIELD(exportSource);
+QMLDOM_FIELD(exports);
+QMLDOM_FIELD(expr);
+QMLDOM_FIELD(expression);
+QMLDOM_FIELD(expressionType);
+QMLDOM_FIELD(extensionTypeName);
+QMLDOM_FIELD(fileLocationsTree);
+QMLDOM_FIELD(fileName);
+QMLDOM_FIELD(finallyBlock);
+QMLDOM_FIELD(forStatement);
+QMLDOM_FIELD(fullRegion);
+QMLDOM_FIELD(get);
+QMLDOM_FIELD(globalScopeName);
+QMLDOM_FIELD(globalScopeWithName);
+QMLDOM_FIELD(hasCallback);
+QMLDOM_FIELD(hasCustomParser);
+QMLDOM_FIELD(idStr);
+QMLDOM_FIELD(identifier);
+QMLDOM_FIELD(ids);
+QMLDOM_FIELD(implicit);
+QMLDOM_FIELD(import);
+QMLDOM_FIELD(importId);
+QMLDOM_FIELD(importScope);
+QMLDOM_FIELD(importSources);
+QMLDOM_FIELD(imported);
+QMLDOM_FIELD(imports);
+QMLDOM_FIELD(inProgress);
+QMLDOM_FIELD(infoItem);
+QMLDOM_FIELD(inheritVersion);
+QMLDOM_FIELD(initializer);
+QMLDOM_FIELD(interfaceNames);
+QMLDOM_FIELD(isAlias);
+QMLDOM_FIELD(isComposite);
+QMLDOM_FIELD(isConstructor);
+QMLDOM_FIELD(isCreatable);
+QMLDOM_FIELD(isDefaultMember);
+QMLDOM_FIELD(isFinal);
+QMLDOM_FIELD(isInternal);
+QMLDOM_FIELD(isLatest);
+QMLDOM_FIELD(isList);
+QMLDOM_FIELD(isPointer);
+QMLDOM_FIELD(isReadonly);
+QMLDOM_FIELD(isRequired);
+QMLDOM_FIELD(isSignalHandler);
+QMLDOM_FIELD(isSingleton);
+QMLDOM_FIELD(isValid);
+QMLDOM_FIELD(jsFileWithPath);
+QMLDOM_FIELD(kind);
+QMLDOM_FIELD(lastRevision);
+QMLDOM_FIELD(label);
+QMLDOM_FIELD(lastValidRevision);
+QMLDOM_FIELD(left);
+QMLDOM_FIELD(loadInfo);
+QMLDOM_FIELD(loadOptions);
+QMLDOM_FIELD(loadPaths);
+QMLDOM_FIELD(loadsWithWork);
+QMLDOM_FIELD(localOffset);
+QMLDOM_FIELD(location);
+QMLDOM_FIELD(logicalPath);
+QMLDOM_FIELD(majorVersion);
+QMLDOM_FIELD(metaRevisions);
+QMLDOM_FIELD(methodType);
+QMLDOM_FIELD(methods);
+QMLDOM_FIELD(minorVersion);
+QMLDOM_FIELD(moduleIndex);
+QMLDOM_FIELD(moduleIndexWithUri);
+QMLDOM_FIELD(moduleScope);
+QMLDOM_FIELD(moreCaseClauses);
+QMLDOM_FIELD(nAllLoadedCallbacks);
+QMLDOM_FIELD(nCallbacks);
+QMLDOM_FIELD(nLoaded);
+QMLDOM_FIELD(nNotdone);
+QMLDOM_FIELD(name);
+QMLDOM_FIELD(nameIdentifiers);
+QMLDOM_FIELD(newlinesBefore);
+QMLDOM_FIELD(nextComponent);
+QMLDOM_FIELD(nextScope);
+QMLDOM_FIELD(notify);
+QMLDOM_FIELD(objects);
+QMLDOM_FIELD(onAttachedObject);
+QMLDOM_FIELD(operation);
+QMLDOM_FIELD(options);
+QMLDOM_FIELD(parameters);
+QMLDOM_FIELD(parent);
+QMLDOM_FIELD(parentObject);
+QMLDOM_FIELD(path);
+QMLDOM_FIELD(plugins);
+QMLDOM_FIELD(postCode);
+QMLDOM_FIELD(postCommentLocations);
+QMLDOM_FIELD(postComments);
+QMLDOM_FIELD(pragma);
+QMLDOM_FIELD(pragmas);
+QMLDOM_FIELD(preCode);
+QMLDOM_FIELD(preCommentLocations);
+QMLDOM_FIELD(preComments);
+QMLDOM_FIELD(properties);
+QMLDOM_FIELD(propertyDef);
+QMLDOM_FIELD(propertyDefRef);
+QMLDOM_FIELD(propertyDefs);
+QMLDOM_FIELD(propertyInfos);
+QMLDOM_FIELD(propertyName);
+QMLDOM_FIELD(prototypes);
+QMLDOM_FIELD(qmlDirectoryWithPath);
+QMLDOM_FIELD(qmlFileWithPath);
+QMLDOM_FIELD(qmlFiles);
+QMLDOM_FIELD(qmldirFileWithPath);
+QMLDOM_FIELD(qmldirWithPath);
+QMLDOM_FIELD(qmltypesFileWithPath);
+QMLDOM_FIELD(qmltypesFiles);
+QMLDOM_FIELD(qualifiedImports);
+QMLDOM_FIELD(rawComment);
+QMLDOM_FIELD(read);
+QMLDOM_FIELD(referredObject);
+QMLDOM_FIELD(referredObjectPath);
+QMLDOM_FIELD(regionComments);
+QMLDOM_FIELD(regions);
+QMLDOM_FIELD(requestedAt);
+QMLDOM_FIELD(requestingUniverse);
+QMLDOM_FIELD(returnType);
+QMLDOM_FIELD(returnTypeName);
+QMLDOM_FIELD(right);
+QMLDOM_FIELD(rootComponent);
+QMLDOM_FIELD(scopeType);
+QMLDOM_FIELD(scriptElement);
+QMLDOM_FIELD(sources);
+QMLDOM_FIELD(statement);
+QMLDOM_FIELD(statements);
+QMLDOM_FIELD(status);
+QMLDOM_FIELD(stringValue);
+QMLDOM_FIELD(subComponents);
+QMLDOM_FIELD(subImports);
+QMLDOM_FIELD(subItems);
+QMLDOM_FIELD(symbol);
+QMLDOM_FIELD(symbols);
+QMLDOM_FIELD(target);
+QMLDOM_FIELD(targetPropertyName);
+QMLDOM_FIELD(text);
+QMLDOM_FIELD(type);
+QMLDOM_FIELD(typeArgument);
+QMLDOM_FIELD(typeArgumentName);
+QMLDOM_FIELD(typeName);
+QMLDOM_FIELD(types);
+QMLDOM_FIELD(universe);
+QMLDOM_FIELD(updatedScriptExpressions);
+QMLDOM_FIELD(uri);
+QMLDOM_FIELD(uris);
+QMLDOM_FIELD(validExposedAt);
+QMLDOM_FIELD(validItem);
+QMLDOM_FIELD(value);
+QMLDOM_FIELD(valueTypeName);
+QMLDOM_FIELD(values);
+QMLDOM_FIELD(version);
+QMLDOM_FIELD(when);
+QMLDOM_FIELD(write);
+} // namespace Fields
class Source;
size_t qHash(const Path &, size_t);
-
+class PathIterator;
// Define a iterator for it?
// begin() can basically be itself, end() the empty path (zero length), iteration though dropFront()
class QMLDOM_EXPORT Path{
+ Q_GADGET
Q_DECLARE_TR_FUNCTIONS(ErrorGroup);
public:
using Kind = PathEls::Kind;
using Component = PathEls::PathComponent;
static ErrorGroups myErrors(); // use static consts and central registration instead?
- Path(){}
+ Path() = default;
+ explicit Path(const PathEls::PathComponent &c) : m_endOffset(0), m_length(0)
+ {
+ *this = appendComponent(c);
+ }
+
int length() const { return m_length; }
Path operator[](int i) const;
- operator bool() const;
+ explicit operator bool() const;
+
+ PathIterator begin() const;
+ PathIterator end() const;
PathRoot headRoot() const;
PathCurrent headCurrent() const;
@@ -605,47 +617,49 @@ public:
QString headName() const;
bool checkHeadName(QStringView name) const;
index_type headIndex(index_type defaultValue=-1) const;
- std::function<bool(DomItem)> headFilter() const;
+ std::function<bool(const DomItem &)> headFilter() const;
Path head() const;
Path last() const;
Source split() const;
- void dump(Sink sink) const;
+ void dump(const Sink &sink) const;
QString toString() const;
- Path dropFront() const;
- Path dropTail() const;
+ Path dropFront(int n = 1) const;
+ Path dropTail(int n = 1) const;
Path mid(int offset, int length) const;
Path mid(int offset) const;
+ Path appendComponent(const PathEls::PathComponent &c);
// # Path construction
- static Path fromString(QString s, ErrorHandler errorHandler=nullptr);
- static Path fromString(QStringView s, ErrorHandler errorHandler=nullptr);
- static Path root(PathRoot r);
- static Path root(QStringView s=u"");
- static Path root(QString s);
- static Path index(index_type i);
- static Path field(QStringView s=u"");
- static Path field(QString s);
- static Path key(QStringView s=u"");
- static Path key(QString s);
- static Path current(PathCurrent c);
- static Path current(QStringView s=u"");
- static Path current(QString s);
- static Path empty();
+ static Path fromString(const QString &s, const ErrorHandler &errorHandler = nullptr);
+ static Path fromString(QStringView s, const ErrorHandler &errorHandler = nullptr);
+ static Path Root(PathRoot r);
+ static Path Root(QStringView s=u"");
+ static Path Root(const QString &s);
+ static Path Index(index_type i);
+ static Path Field(QStringView s=u"");
+ static Path Field(const QString &s);
+ static Path Key(QStringView s=u"");
+ static Path Key(const QString &s);
+ static Path Current(PathCurrent c);
+ static Path Current(QStringView s=u"");
+ static Path Current(const QString &s);
+ static Path Empty();
// add
- Path subEmpty() const;
- Path subField(QString name) const;
- Path subField(QStringView name) const;
- Path subKey(QString name) const;
- Path subKey(QStringView name) const;
- Path subIndex(index_type i) const;
- Path subAny() const;
- Path subFilter(std::function<bool(DomItem)>, QString) const;
- Path subFilter(std::function<bool(DomItem)>, QStringView desc=u"<native code filter>") const;
- Path subCurrent(PathCurrent s) const;
- Path subCurrent(QString s) const;
- Path subCurrent(QStringView s=u"") const;
- Path subPath(Path toAdd, bool avoidToAddAsBase = false) const;
+ Path empty() const;
+ Path field(const QString &name) const;
+ Path field(QStringView name) const;
+ Path key(const QString &name) const;
+ Path key(QStringView name) const;
+ Path index(index_type i) const;
+ Path any() const;
+ Path filter(const std::function<bool(const DomItem &)> &, const QString &) const;
+ Path filter(const std::function<bool(const DomItem &)> &,
+ QStringView desc=u"<native code filter>") const;
+ Path current(PathCurrent s) const;
+ Path current(const QString &s) const;
+ Path current(QStringView s=u"") const;
+ Path path(const Path &toAdd, bool avoidToAddAsBase = false) const;
Path expandFront() const;
Path expandBack() const;
@@ -661,25 +675,56 @@ public:
using iterator_category = std::forward_iterator_tag;
static int cmp(const Path &p1, const Path &p2);
+
private:
- explicit Path(quint16 endOffset, quint16 length, std::shared_ptr<PathEls::PathData> data);
+ const Component &component(int i) const;
+ explicit Path(quint16 endOffset, quint16 length,
+ const std::shared_ptr<PathEls::PathData> &data);
friend class QQmlJS::Dom::PathEls::TestPaths;
+ friend class FieldFilter;
friend size_t qHash(const Path &, size_t);
- Component component(int i) const;
Path noEndOffset() const;
quint16 m_endOffset = 0;
quint16 m_length = 0;
- std::shared_ptr<PathEls::PathData> m_data;
+ std::shared_ptr<PathEls::PathData> m_data = {};
};
-inline bool operator==(const Path& lhs, const Path& rhs){ return lhs.length() == rhs.length() && Path::cmp(lhs,rhs) == 0; }
-inline bool operator!=(const Path& lhs, const Path& rhs){ return lhs.length() != rhs.length() || Path::cmp(lhs,rhs) != 0; }
-inline bool operator< (const Path& lhs, const Path& rhs){ return Path::cmp(lhs,rhs) < 0; }
-inline bool operator> (const Path& lhs, const Path& rhs){ return Path::cmp(lhs,rhs) > 0; }
-inline bool operator<=(const Path& lhs, const Path& rhs){ return Path::cmp(lhs,rhs) <= 0; }
-inline bool operator>=(const Path& lhs, const Path& rhs){ return Path::cmp(lhs,rhs) >= 0; }
+inline bool operator==(const Path &lhs, const Path &rhs)
+{
+ return lhs.length() == rhs.length() && Path::cmp(lhs, rhs) == 0;
+}
+inline bool operator!=(const Path &lhs, const Path &rhs)
+{
+ return lhs.length() != rhs.length() || Path::cmp(lhs, rhs) != 0;
+}
+inline bool operator<(const Path &lhs, const Path &rhs)
+{
+ return Path::cmp(lhs, rhs) < 0;
+}
+inline bool operator>(const Path &lhs, const Path &rhs)
+{
+ return Path::cmp(lhs, rhs) > 0;
+}
+inline bool operator<=(const Path &lhs, const Path &rhs)
+{
+ return Path::cmp(lhs, rhs) <= 0;
+}
+inline bool operator>=(const Path &lhs, const Path &rhs)
+{
+ return Path::cmp(lhs, rhs) >= 0;
+}
+
+class PathIterator {
+public:
+ Path currentEl;
+ Path operator *() const { return currentEl.head(); }
+ PathIterator operator ++() { currentEl = currentEl.dropFront(); return *this; }
+ PathIterator operator ++(int) { PathIterator res{currentEl}; currentEl = currentEl.dropFront(); return res; }
+ bool operator ==(const PathIterator &o) const { return currentEl == o.currentEl; }
+ bool operator !=(const PathIterator &o) const { return currentEl != o.currentEl; }
+};
class Source {
public:
@@ -704,6 +749,9 @@ inline size_t qHash(const Path &path, size_t seed)
*it++ = qHash(p.component(0).stringView(), seed)^size_t(p.headRoot())^size_t(p.headCurrent());
}
}
+
+ // TODO: Get rid of the reinterpret_cast.
+ // Rather hash the path components in a more structured way.
return qHash(QByteArray::fromRawData(reinterpret_cast<char *>(&buf[0]), (it - &buf[0])*sizeof(size_t)), seed);
}