| 1 | // Copyright (C) 2021 The Qt Company Ltd. | 
|---|
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only | 
|---|
| 3 |  | 
|---|
| 4 | #ifndef QQMLDOMELEMENTS_P_H | 
|---|
| 5 | #define QQMLDOMELEMENTS_P_H | 
|---|
| 6 |  | 
|---|
| 7 | // | 
|---|
| 8 | //  W A R N I N G | 
|---|
| 9 | //  ------------- | 
|---|
| 10 | // | 
|---|
| 11 | // This file is not part of the Qt API.  It exists purely as an | 
|---|
| 12 | // implementation detail.  This header file may change from version to | 
|---|
| 13 | // version without notice, or even be removed. | 
|---|
| 14 | // | 
|---|
| 15 | // We mean it. | 
|---|
| 16 | // | 
|---|
| 17 |  | 
|---|
| 18 | #include "qqmldomitem_p.h" | 
|---|
| 19 | #include "qqmldomconstants_p.h" | 
|---|
| 20 | #include "qqmldomcomments_p.h" | 
|---|
| 21 | #include "qqmldomlinewriter_p.h" | 
|---|
| 22 |  | 
|---|
| 23 | #include <QtQml/private/qqmljsast_p.h> | 
|---|
| 24 | #include <QtQml/private/qqmljsengine_p.h> | 
|---|
| 25 | #include <QtQml/private/qqmlsignalnames_p.h> | 
|---|
| 26 |  | 
|---|
| 27 | #include <QtCore/QCborValue> | 
|---|
| 28 | #include <QtCore/QCborMap> | 
|---|
| 29 | #include <QtCore/QMutexLocker> | 
|---|
| 30 | #include <QtCore/QPair> | 
|---|
| 31 |  | 
|---|
| 32 | #include <memory> | 
|---|
| 33 | #include <private/qqmljsscope_p.h> | 
|---|
| 34 |  | 
|---|
| 35 | #include <functional> | 
|---|
| 36 | #include <limits> | 
|---|
| 37 |  | 
|---|
| 38 | QT_BEGIN_NAMESPACE | 
|---|
| 39 |  | 
|---|
| 40 | namespace QQmlJS { | 
|---|
| 41 | namespace Dom { | 
|---|
| 42 |  | 
|---|
| 43 | // namespace for utility methods building specific paths | 
|---|
| 44 | // using a namespace one can reopen it and add more methods in other places | 
|---|
| 45 | namespace Paths { | 
|---|
| 46 | Path moduleIndexPath( | 
|---|
| 47 | const QString &uri, int majorVersion, const ErrorHandler &errorHandler = nullptr); | 
|---|
| 48 | Path moduleScopePath( | 
|---|
| 49 | const QString &uri, Version version, const ErrorHandler &errorHandler = nullptr); | 
|---|
| 50 | Path moduleScopePath( | 
|---|
| 51 | const QString &uri, const QString &version, const ErrorHandler &errorHandler = nullptr); | 
|---|
| 52 | inline Path moduleScopePath( | 
|---|
| 53 | const QString &uri, const ErrorHandler &errorHandler = nullptr) | 
|---|
| 54 | { | 
|---|
| 55 | return moduleScopePath(uri, version: QString(), errorHandler); | 
|---|
| 56 | } | 
|---|
| 57 | inline Path qmlDirInfoPath(const QString &path) | 
|---|
| 58 | { | 
|---|
| 59 | return Path::Root(r: PathRoot::Top).field(name: Fields::qmldirWithPath).key(name: path); | 
|---|
| 60 | } | 
|---|
| 61 | inline Path qmlDirPath(const QString &path) | 
|---|
| 62 | { | 
|---|
| 63 | return qmlDirInfoPath(path).field(name: Fields::currentItem); | 
|---|
| 64 | } | 
|---|
| 65 | inline Path qmldirFileInfoPath(const QString &path) | 
|---|
| 66 | { | 
|---|
| 67 | return Path::Root(r: PathRoot::Top).field(name: Fields::qmldirFileWithPath).key(name: path); | 
|---|
| 68 | } | 
|---|
| 69 | inline Path qmldirFilePath(const QString &path) | 
|---|
| 70 | { | 
|---|
| 71 | return qmldirFileInfoPath(path).field(name: Fields::currentItem); | 
|---|
| 72 | } | 
|---|
| 73 | inline Path qmlFileInfoPath(const QString &canonicalFilePath) | 
|---|
| 74 | { | 
|---|
| 75 | return Path::Root(r: PathRoot::Top).field(name: Fields::qmlFileWithPath).key(name: canonicalFilePath); | 
|---|
| 76 | } | 
|---|
| 77 | inline Path qmlFilePath(const QString &canonicalFilePath) | 
|---|
| 78 | { | 
|---|
| 79 | return qmlFileInfoPath(canonicalFilePath).field(name: Fields::currentItem); | 
|---|
| 80 | } | 
|---|
| 81 | inline Path qmlFileObjectPath(const QString &canonicalFilePath) | 
|---|
| 82 | { | 
|---|
| 83 | return qmlFilePath(canonicalFilePath) | 
|---|
| 84 | .field(name: Fields::components) | 
|---|
| 85 | .key(name: QString()) | 
|---|
| 86 | .index(i: 0) | 
|---|
| 87 | .field(name: Fields::objects) | 
|---|
| 88 | .index(i: 0); | 
|---|
| 89 | } | 
|---|
| 90 | inline Path qmltypesFileInfoPath(const QString &path) | 
|---|
| 91 | { | 
|---|
| 92 | return Path::Root(r: PathRoot::Top).field(name: Fields::qmltypesFileWithPath).key(name: path); | 
|---|
| 93 | } | 
|---|
| 94 | inline Path qmltypesFilePath(const QString &path) | 
|---|
| 95 | { | 
|---|
| 96 | return qmltypesFileInfoPath(path).field(name: Fields::currentItem); | 
|---|
| 97 | } | 
|---|
| 98 | inline Path jsFileInfoPath(const QString &path) | 
|---|
| 99 | { | 
|---|
| 100 | return Path::Root(r: PathRoot::Top).field(name: Fields::jsFileWithPath).key(name: path); | 
|---|
| 101 | } | 
|---|
| 102 | inline Path jsFilePath(const QString &path) | 
|---|
| 103 | { | 
|---|
| 104 | return jsFileInfoPath(path).field(name: Fields::currentItem); | 
|---|
| 105 | } | 
|---|
| 106 | inline Path qmlDirectoryInfoPath(const QString &path) | 
|---|
| 107 | { | 
|---|
| 108 | return Path::Root(r: PathRoot::Top).field(name: Fields::qmlDirectoryWithPath).key(name: path); | 
|---|
| 109 | } | 
|---|
| 110 | inline Path qmlDirectoryPath(const QString &path) | 
|---|
| 111 | { | 
|---|
| 112 | return qmlDirectoryInfoPath(path).field(name: Fields::currentItem); | 
|---|
| 113 | } | 
|---|
| 114 | inline Path globalScopeInfoPath(const QString &name) | 
|---|
| 115 | { | 
|---|
| 116 | return Path::Root(r: PathRoot::Top).field(name: Fields::globalScopeWithName).key(name); | 
|---|
| 117 | } | 
|---|
| 118 | inline Path globalScopePath(const QString &name) | 
|---|
| 119 | { | 
|---|
| 120 | return globalScopeInfoPath(name).field(name: Fields::currentItem); | 
|---|
| 121 | } | 
|---|
| 122 | inline Path lookupCppTypePath(const QString &name) | 
|---|
| 123 | { | 
|---|
| 124 | return Path::Current(c: PathCurrent::Lookup).field(name: Fields::cppType).key(name); | 
|---|
| 125 | } | 
|---|
| 126 | inline Path lookupPropertyPath(const QString &name) | 
|---|
| 127 | { | 
|---|
| 128 | return Path::Current(c: PathCurrent::Lookup).field(name: Fields::propertyDef).key(name); | 
|---|
| 129 | } | 
|---|
| 130 | inline Path lookupSymbolPath(const QString &name) | 
|---|
| 131 | { | 
|---|
| 132 | return Path::Current(c: PathCurrent::Lookup).field(name: Fields::symbol).key(name); | 
|---|
| 133 | } | 
|---|
| 134 | inline Path lookupTypePath(const QString &name) | 
|---|
| 135 | { | 
|---|
| 136 | return Path::Current(c: PathCurrent::Lookup).field(name: Fields::type).key(name); | 
|---|
| 137 | } | 
|---|
| 138 | inline Path loadInfoPath(const Path &el) | 
|---|
| 139 | { | 
|---|
| 140 | return Path::Root(r: PathRoot::Env).field(name: Fields::loadInfo).key(name: el.toString()); | 
|---|
| 141 | } | 
|---|
| 142 | } // end namespace Paths | 
|---|
| 143 |  | 
|---|
| 144 | class QMLDOM_EXPORT  : public DomElement | 
|---|
| 145 | { | 
|---|
| 146 | public: | 
|---|
| 147 | (const Path &pathFromOwner = Path()) : DomElement(pathFromOwner) { } | 
|---|
| 148 | (const CommentableDomElement &o) : DomElement(o), m_comments(o.m_comments) | 
|---|
| 149 | { | 
|---|
| 150 | } | 
|---|
| 151 | CommentableDomElement &(const CommentableDomElement &o) = default; | 
|---|
| 152 | bool (const DomItem &self, DirectVisitor) const override; | 
|---|
| 153 | RegionComments &() { return m_comments; } | 
|---|
| 154 | const RegionComments &() const { return m_comments; } | 
|---|
| 155 |  | 
|---|
| 156 | private: | 
|---|
| 157 | RegionComments ; | 
|---|
| 158 | }; | 
|---|
| 159 |  | 
|---|
| 160 | class QMLDOM_EXPORT Version | 
|---|
| 161 | { | 
|---|
| 162 | public: | 
|---|
| 163 | constexpr static DomType kindValue = DomType::Version; | 
|---|
| 164 | constexpr static qint32 Undefined = -1; | 
|---|
| 165 | constexpr static qint32 Latest = -2; | 
|---|
| 166 |  | 
|---|
| 167 | Version(qint32 majorVersion = Undefined, qint32 minorVersion = Undefined); | 
|---|
| 168 | static Version fromString(QStringView v); | 
|---|
| 169 |  | 
|---|
| 170 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const; | 
|---|
| 171 |  | 
|---|
| 172 | bool isLatest() const; | 
|---|
| 173 | bool isValid() const; | 
|---|
| 174 | QString stringValue() const; | 
|---|
| 175 | QString majorString() const | 
|---|
| 176 | { | 
|---|
| 177 | if (majorVersion >= 0 || majorVersion == Undefined) | 
|---|
| 178 | return QString::number(majorVersion); | 
|---|
| 179 | return QString(); | 
|---|
| 180 | } | 
|---|
| 181 | QString majorSymbolicString() const | 
|---|
| 182 | { | 
|---|
| 183 | if (majorVersion == Version::Latest) | 
|---|
| 184 | return QLatin1String( "Latest"); | 
|---|
| 185 | if (majorVersion >= 0 || majorVersion == Undefined) | 
|---|
| 186 | return QString::number(majorVersion); | 
|---|
| 187 | return QString(); | 
|---|
| 188 | } | 
|---|
| 189 | QString minorString() const | 
|---|
| 190 | { | 
|---|
| 191 | if (minorVersion >= 0 || minorVersion == Undefined) | 
|---|
| 192 | return QString::number(minorVersion); | 
|---|
| 193 | return QString(); | 
|---|
| 194 | } | 
|---|
| 195 | int compare(const Version &o) const | 
|---|
| 196 | { | 
|---|
| 197 | int c = majorVersion - o.majorVersion; | 
|---|
| 198 | if (c != 0) | 
|---|
| 199 | return c; | 
|---|
| 200 | return minorVersion - o.minorVersion; | 
|---|
| 201 | } | 
|---|
| 202 |  | 
|---|
| 203 | qint32 majorVersion; | 
|---|
| 204 | qint32 minorVersion; | 
|---|
| 205 | }; | 
|---|
| 206 | inline bool operator==(const Version &v1, const Version &v2) | 
|---|
| 207 | { | 
|---|
| 208 | return v1.compare(o: v2) == 0; | 
|---|
| 209 | } | 
|---|
| 210 | inline bool operator!=(const Version &v1, const Version &v2) | 
|---|
| 211 | { | 
|---|
| 212 | return v1.compare(o: v2) != 0; | 
|---|
| 213 | } | 
|---|
| 214 | inline bool operator<(const Version &v1, const Version &v2) | 
|---|
| 215 | { | 
|---|
| 216 | return v1.compare(o: v2) < 0; | 
|---|
| 217 | } | 
|---|
| 218 | inline bool operator<=(const Version &v1, const Version &v2) | 
|---|
| 219 | { | 
|---|
| 220 | return v1.compare(o: v2) <= 0; | 
|---|
| 221 | } | 
|---|
| 222 | inline bool operator>(const Version &v1, const Version &v2) | 
|---|
| 223 | { | 
|---|
| 224 | return v1.compare(o: v2) > 0; | 
|---|
| 225 | } | 
|---|
| 226 | inline bool operator>=(const Version &v1, const Version &v2) | 
|---|
| 227 | { | 
|---|
| 228 | return v1.compare(o: v2) >= 0; | 
|---|
| 229 | } | 
|---|
| 230 |  | 
|---|
| 231 | class QMLDOM_EXPORT QmlUri | 
|---|
| 232 | { | 
|---|
| 233 | public: | 
|---|
| 234 | enum class Kind { Invalid, ModuleUri, DirectoryUrl, RelativePath, AbsolutePath }; | 
|---|
| 235 | QmlUri() = default; | 
|---|
| 236 | static QmlUri fromString(const QString &importStr); | 
|---|
| 237 | static QmlUri fromUriString(const QString &importStr); | 
|---|
| 238 | static QmlUri fromDirectoryString(const QString &importStr); | 
|---|
| 239 | bool isValid() const; | 
|---|
| 240 | bool isDirectory() const; | 
|---|
| 241 | bool isModule() const; | 
|---|
| 242 | QString moduleUri() const; | 
|---|
| 243 | QString localPath() const; | 
|---|
| 244 | QString absoluteLocalPath(const QString &basePath = QString()) const; | 
|---|
| 245 | QUrl directoryUrl() const; | 
|---|
| 246 | QString directoryString() const; | 
|---|
| 247 | QString toString() const; | 
|---|
| 248 | Kind kind() const; | 
|---|
| 249 |  | 
|---|
| 250 | friend bool operator==(const QmlUri &i1, const QmlUri &i2) | 
|---|
| 251 | { | 
|---|
| 252 | return i1.m_kind == i2.m_kind && i1.m_value == i2.m_value; | 
|---|
| 253 | } | 
|---|
| 254 | friend bool operator!=(const QmlUri &i1, const QmlUri &i2) { return !(i1 == i2); } | 
|---|
| 255 |  | 
|---|
| 256 | private: | 
|---|
| 257 | QmlUri(const QUrl &url) : m_kind(Kind::DirectoryUrl), m_value(url) { } | 
|---|
| 258 | QmlUri(Kind kind, const QString &value) : m_kind(kind), m_value(value) { } | 
|---|
| 259 | Kind m_kind = Kind::Invalid; | 
|---|
| 260 | std::variant<QString, QUrl> m_value; | 
|---|
| 261 | }; | 
|---|
| 262 |  | 
|---|
| 263 | class QMLDOM_EXPORT Import | 
|---|
| 264 | { | 
|---|
| 265 | Q_DECLARE_TR_FUNCTIONS(Import) | 
|---|
| 266 | public: | 
|---|
| 267 | constexpr static DomType kindValue = DomType::Import; | 
|---|
| 268 |  | 
|---|
| 269 | static Import fromUriString( | 
|---|
| 270 | const QString &importStr, Version v = Version(), const QString &importId = QString(), | 
|---|
| 271 | const ErrorHandler &handler = nullptr); | 
|---|
| 272 | static Import fromFileString( | 
|---|
| 273 | const QString &importStr, const QString &importId = QString(), | 
|---|
| 274 | const ErrorHandler &handler = nullptr); | 
|---|
| 275 |  | 
|---|
| 276 | Import(const QmlUri &uri = QmlUri(), Version version = Version(), | 
|---|
| 277 | const QString &importId = QString()) | 
|---|
| 278 | : uri(uri), version(version), importId(importId) | 
|---|
| 279 | { | 
|---|
| 280 | } | 
|---|
| 281 |  | 
|---|
| 282 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const; | 
|---|
| 283 | Path importedPath() const | 
|---|
| 284 | { | 
|---|
| 285 | if (uri.isDirectory()) { | 
|---|
| 286 | QString path = uri.absoluteLocalPath(); | 
|---|
| 287 | if (!path.isEmpty()) { | 
|---|
| 288 | return Paths::qmlDirPath(path); | 
|---|
| 289 | } else { | 
|---|
| 290 | Q_ASSERT_X(false, "Import", "url imports not supported"); | 
|---|
| 291 | return Paths::qmldirFilePath(path: uri.directoryString()); | 
|---|
| 292 | } | 
|---|
| 293 | } else { | 
|---|
| 294 | return Paths::moduleScopePath(uri: uri.moduleUri(), version); | 
|---|
| 295 | } | 
|---|
| 296 | } | 
|---|
| 297 | Import baseImport() const { return Import { uri, version }; } | 
|---|
| 298 |  | 
|---|
| 299 | friend bool operator==(const Import &i1, const Import &i2) | 
|---|
| 300 | { | 
|---|
| 301 | return i1.uri == i2.uri && i1.version == i2.version && i1.importId == i2.importId | 
|---|
| 302 | && i1.comments == i2.comments && i1.implicit == i2.implicit; | 
|---|
| 303 | } | 
|---|
| 304 | friend bool operator!=(const Import &i1, const Import &i2) { return !(i1 == i2); } | 
|---|
| 305 |  | 
|---|
| 306 | void writeOut(const DomItem &self, OutWriter &ow) const; | 
|---|
| 307 |  | 
|---|
| 308 | static QRegularExpression importRe(); | 
|---|
| 309 |  | 
|---|
| 310 | QmlUri uri; | 
|---|
| 311 | Version version; | 
|---|
| 312 | QString importId; | 
|---|
| 313 | RegionComments ; | 
|---|
| 314 | bool implicit = false; | 
|---|
| 315 | }; | 
|---|
| 316 |  | 
|---|
| 317 | class QMLDOM_EXPORT ModuleAutoExport | 
|---|
| 318 | { | 
|---|
| 319 | public: | 
|---|
| 320 | constexpr static DomType kindValue = DomType::ModuleAutoExport; | 
|---|
| 321 |  | 
|---|
| 322 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const | 
|---|
| 323 | { | 
|---|
| 324 | bool cont = true; | 
|---|
| 325 | cont = cont && self.dvWrapField(visitor, f: Fields::import, obj: import); | 
|---|
| 326 | cont = cont && self.dvValueField(visitor, f: Fields::inheritVersion, value: inheritVersion); | 
|---|
| 327 | return cont; | 
|---|
| 328 | } | 
|---|
| 329 |  | 
|---|
| 330 | friend bool operator==(const ModuleAutoExport &i1, const ModuleAutoExport &i2) | 
|---|
| 331 | { | 
|---|
| 332 | return i1.import == i2.import && i1.inheritVersion == i2.inheritVersion; | 
|---|
| 333 | } | 
|---|
| 334 | friend bool operator!=(const ModuleAutoExport &i1, const ModuleAutoExport &i2) | 
|---|
| 335 | { | 
|---|
| 336 | return !(i1 == i2); | 
|---|
| 337 | } | 
|---|
| 338 |  | 
|---|
| 339 | Import import; | 
|---|
| 340 | bool inheritVersion = false; | 
|---|
| 341 | }; | 
|---|
| 342 |  | 
|---|
| 343 | class QMLDOM_EXPORT Pragma | 
|---|
| 344 | { | 
|---|
| 345 | public: | 
|---|
| 346 | constexpr static DomType kindValue = DomType::Pragma; | 
|---|
| 347 |  | 
|---|
| 348 | Pragma(const QString &pragmaName = QString(), const QStringList &pragmaValues = {}) | 
|---|
| 349 | : name(pragmaName), values{ pragmaValues } | 
|---|
| 350 | { | 
|---|
| 351 | } | 
|---|
| 352 |  | 
|---|
| 353 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const | 
|---|
| 354 | { | 
|---|
| 355 | bool cont = self.dvValueField(visitor, f: Fields::name, value: name); | 
|---|
| 356 | cont = cont && self.dvValueField(visitor, f: Fields::values, value: values); | 
|---|
| 357 | cont = cont && self.dvWrapField(visitor, f: Fields::comments, obj: comments); | 
|---|
| 358 | return cont; | 
|---|
| 359 | } | 
|---|
| 360 |  | 
|---|
| 361 | void writeOut(const DomItem &self, OutWriter &ow) const; | 
|---|
| 362 |  | 
|---|
| 363 | QString name; | 
|---|
| 364 | QStringList values; | 
|---|
| 365 | RegionComments ; | 
|---|
| 366 | }; | 
|---|
| 367 |  | 
|---|
| 368 | class QMLDOM_EXPORT Id | 
|---|
| 369 | { | 
|---|
| 370 | public: | 
|---|
| 371 | constexpr static DomType kindValue = DomType::Id; | 
|---|
| 372 |  | 
|---|
| 373 | Id(const QString &idName = QString(), const Path &referredObject = Path()); | 
|---|
| 374 |  | 
|---|
| 375 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const; | 
|---|
| 376 | void updatePathFromOwner(const Path &pathFromOwner); | 
|---|
| 377 | Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &ann, QmlObject **aPtr = nullptr); | 
|---|
| 378 |  | 
|---|
| 379 | QString name; | 
|---|
| 380 | Path referredObjectPath; | 
|---|
| 381 | RegionComments ; | 
|---|
| 382 | QList<QmlObject> annotations; | 
|---|
| 383 | std::shared_ptr<ScriptExpression> value; | 
|---|
| 384 | }; | 
|---|
| 385 |  | 
|---|
| 386 | // TODO: rename? it may contain statements and stuff, not only expressions | 
|---|
| 387 | // TODO QTBUG-121933 | 
|---|
| 388 | class QMLDOM_EXPORT ScriptExpression final : public OwningItem | 
|---|
| 389 | { | 
|---|
| 390 | Q_GADGET | 
|---|
| 391 | Q_DECLARE_TR_FUNCTIONS(ScriptExpression) | 
|---|
| 392 | public: | 
|---|
| 393 | enum class ExpressionType { | 
|---|
| 394 | BindingExpression, | 
|---|
| 395 | FunctionBody, | 
|---|
| 396 | ArgInitializer, | 
|---|
| 397 | ArgumentStructure, | 
|---|
| 398 | ReturnType, | 
|---|
| 399 | JSCode, // Used for storing the content of the whole .js file as "one" Expression | 
|---|
| 400 | ESMCode, // Used for storing the content of the whole ECMAScript module (.mjs) as "one" | 
|---|
| 401 | // Expression | 
|---|
| 402 | }; | 
|---|
| 403 | Q_ENUM(ExpressionType); | 
|---|
| 404 | constexpr static DomType kindValue = DomType::ScriptExpression; | 
|---|
| 405 | DomType kind() const override { return kindValue; } | 
|---|
| 406 |  | 
|---|
| 407 | explicit ( | 
|---|
| 408 | QStringView code, const std::shared_ptr<QQmlJS::Engine> &engine, AST::Node *ast, | 
|---|
| 409 | const std::shared_ptr<AstComments> &, ExpressionType expressionType, | 
|---|
| 410 | SourceLocation localOffset = SourceLocation(), int derivedFrom = 0, | 
|---|
| 411 | QStringView preCode = QStringView(), QStringView postCode = QStringView()); | 
|---|
| 412 |  | 
|---|
| 413 | ScriptExpression() | 
|---|
| 414 | : ScriptExpression(QStringView(), std::shared_ptr<QQmlJS::Engine>(), nullptr, | 
|---|
| 415 | std::shared_ptr<AstComments>(), ExpressionType::BindingExpression, | 
|---|
| 416 | SourceLocation(), 0) | 
|---|
| 417 | { | 
|---|
| 418 | } | 
|---|
| 419 |  | 
|---|
| 420 | explicit ScriptExpression( | 
|---|
| 421 | const QString &code, ExpressionType expressionType, int derivedFrom = 0, | 
|---|
| 422 | const QString &preCode = QString(), const QString &postCode = QString()) | 
|---|
| 423 | : OwningItem(derivedFrom), m_expressionType(expressionType) | 
|---|
| 424 | { | 
|---|
| 425 | setCode(code, preCode, postCode); | 
|---|
| 426 | } | 
|---|
| 427 |  | 
|---|
| 428 | ScriptExpression(const ScriptExpression &e); | 
|---|
| 429 |  | 
|---|
| 430 | std::shared_ptr<ScriptExpression> makeCopy(const DomItem &self) const | 
|---|
| 431 | { | 
|---|
| 432 | return std::static_pointer_cast<ScriptExpression>(r: doCopy(self)); | 
|---|
| 433 | } | 
|---|
| 434 |  | 
|---|
| 435 | std::shared_ptr<ScriptExpression> copyWithUpdatedCode(const DomItem &self, const QString &code) const; | 
|---|
| 436 |  | 
|---|
| 437 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override; | 
|---|
| 438 |  | 
|---|
| 439 | Path canonicalPath(const DomItem &self) const override { return self.m_ownerPath; } | 
|---|
| 440 | // parsed and created if not available | 
|---|
| 441 | AST::Node *ast() const { return m_ast; } | 
|---|
| 442 | // dump of the ast (without locations) | 
|---|
| 443 | void astDumper(const Sink &s, AstDumperOptions options) const; | 
|---|
| 444 | QString astRelocatableDump() const; | 
|---|
| 445 |  | 
|---|
| 446 | // definedSymbols name, value, from | 
|---|
| 447 | // usedSymbols name, locations | 
|---|
| 448 | QStringView code() const | 
|---|
| 449 | { | 
|---|
| 450 | QMutexLocker l(mutex()); | 
|---|
| 451 | return m_code; | 
|---|
| 452 | } | 
|---|
| 453 |  | 
|---|
| 454 | ExpressionType expressionType() const | 
|---|
| 455 | { | 
|---|
| 456 | QMutexLocker l(mutex()); | 
|---|
| 457 | return m_expressionType; | 
|---|
| 458 | } | 
|---|
| 459 |  | 
|---|
| 460 | bool isNull() const | 
|---|
| 461 | { | 
|---|
| 462 | QMutexLocker l(mutex()); | 
|---|
| 463 | return m_code.isNull(); | 
|---|
| 464 | } | 
|---|
| 465 | std::shared_ptr<QQmlJS::Engine> engine() const | 
|---|
| 466 | { | 
|---|
| 467 | QMutexLocker l(mutex()); | 
|---|
| 468 | return m_engine; | 
|---|
| 469 | } | 
|---|
| 470 | std::shared_ptr<AstComments> () const { return m_astComments; } | 
|---|
| 471 | void writeOut(const DomItem &self, OutWriter &lw) const override; | 
|---|
| 472 | SourceLocation globalLocation(const DomItem &self) const; | 
|---|
| 473 | SourceLocation localOffset() const { return m_localOffset; } | 
|---|
| 474 | QStringView preCode() const { return m_preCode; } | 
|---|
| 475 | QStringView postCode() const { return m_postCode; } | 
|---|
| 476 | void setScriptElement(const ScriptElementVariant &p); | 
|---|
| 477 | ScriptElementVariant scriptElement() { return m_element; } | 
|---|
| 478 |  | 
|---|
| 479 | protected: | 
|---|
| 480 | std::shared_ptr<OwningItem> doCopy(const DomItem &) const override | 
|---|
| 481 | { | 
|---|
| 482 | return std::make_shared<ScriptExpression>(args: *this); | 
|---|
| 483 | } | 
|---|
| 484 |  | 
|---|
| 485 | std::function<SourceLocation(SourceLocation)> locationToGlobalF(const DomItem &self) const | 
|---|
| 486 | { | 
|---|
| 487 | SourceLocation loc = globalLocation(self); | 
|---|
| 488 | return [loc, this](SourceLocation x) { | 
|---|
| 489 | return SourceLocation(x.offset - m_localOffset.offset + loc.offset, x.length, | 
|---|
| 490 | x.startLine - m_localOffset.startLine + loc.startLine, | 
|---|
| 491 | ((x.startLine == m_localOffset.startLine) ? x.startColumn | 
|---|
| 492 | - m_localOffset.startColumn + loc.startColumn | 
|---|
| 493 | : x.startColumn)); | 
|---|
| 494 | }; | 
|---|
| 495 | } | 
|---|
| 496 |  | 
|---|
| 497 | SourceLocation locationToLocal(SourceLocation x) const | 
|---|
| 498 | { | 
|---|
| 499 | return SourceLocation( | 
|---|
| 500 | x.offset - m_localOffset.offset, x.length, x.startLine - m_localOffset.startLine, | 
|---|
| 501 | ((x.startLine == m_localOffset.startLine) | 
|---|
| 502 | ? x.startColumn - m_localOffset.startColumn | 
|---|
| 503 | : x.startColumn)); // are line and column 1 based? then we should + 1 | 
|---|
| 504 | } | 
|---|
| 505 |  | 
|---|
| 506 | std::function<SourceLocation(SourceLocation)> locationToLocalF(const DomItem &) const | 
|---|
| 507 | { | 
|---|
| 508 | return [this](SourceLocation x) { return locationToLocal(x); }; | 
|---|
| 509 | } | 
|---|
| 510 |  | 
|---|
| 511 | private: | 
|---|
| 512 | enum class ParseMode { | 
|---|
| 513 | QML, | 
|---|
| 514 | JS, | 
|---|
| 515 | ESM, // ECMAScript module | 
|---|
| 516 | }; | 
|---|
| 517 |  | 
|---|
| 518 | inline ParseMode resolveParseMode() | 
|---|
| 519 | { | 
|---|
| 520 | switch (m_expressionType) { | 
|---|
| 521 | case ExpressionType::BindingExpression: | 
|---|
| 522 | // unfortunately there are no documentation explaining this resolution | 
|---|
| 523 | // this was just moved from the original implementation | 
|---|
| 524 | return ParseMode::QML; | 
|---|
| 525 | case ExpressionType::ESMCode: | 
|---|
| 526 | return ParseMode::ESM; | 
|---|
| 527 | default: | 
|---|
| 528 | return ParseMode::JS; | 
|---|
| 529 | } | 
|---|
| 530 | } | 
|---|
| 531 | void setCode(const QString &code, const QString &preCode, const QString &postCode); | 
|---|
| 532 | [[nodiscard]] AST::Node *parse(ParseMode mode); | 
|---|
| 533 |  | 
|---|
| 534 | ExpressionType m_expressionType; | 
|---|
| 535 | QString m_codeStr; | 
|---|
| 536 | QStringView m_code; | 
|---|
| 537 | QStringView m_preCode; | 
|---|
| 538 | QStringView m_postCode; | 
|---|
| 539 | mutable std::shared_ptr<QQmlJS::Engine> m_engine; | 
|---|
| 540 | mutable AST::Node *m_ast; | 
|---|
| 541 | std::shared_ptr<AstComments> ; | 
|---|
| 542 | SourceLocation m_localOffset; | 
|---|
| 543 | ScriptElementVariant m_element; | 
|---|
| 544 | }; | 
|---|
| 545 |  | 
|---|
| 546 | class BindingValue; | 
|---|
| 547 |  | 
|---|
| 548 | class QMLDOM_EXPORT Binding | 
|---|
| 549 | { | 
|---|
| 550 | public: | 
|---|
| 551 | constexpr static DomType kindValue = DomType::Binding; | 
|---|
| 552 |  | 
|---|
| 553 | Binding(const QString &m_name = QString()); | 
|---|
| 554 | Binding(const QString &m_name, std::unique_ptr<BindingValue> value, | 
|---|
| 555 | BindingType bindingType = BindingType::Normal); | 
|---|
| 556 | Binding(const QString &m_name, const std::shared_ptr<ScriptExpression> &value, | 
|---|
| 557 | BindingType bindingType = BindingType::Normal); | 
|---|
| 558 | Binding(const QString &m_name, const QString &scriptCode, | 
|---|
| 559 | BindingType bindingType = BindingType::Normal); | 
|---|
| 560 | Binding(const QString &m_name, const QmlObject &value, | 
|---|
| 561 | BindingType bindingType = BindingType::Normal); | 
|---|
| 562 | Binding(const QString &m_name, const QList<QmlObject> &value, | 
|---|
| 563 | BindingType bindingType = BindingType::Normal); | 
|---|
| 564 | Binding(const Binding &o); | 
|---|
| 565 | Binding(Binding &&o) = default; | 
|---|
| 566 | ~Binding(); | 
|---|
| 567 | Binding &operator=(const Binding &); | 
|---|
| 568 | Binding &operator=(Binding &&) = default; | 
|---|
| 569 |  | 
|---|
| 570 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const; | 
|---|
| 571 | DomItem valueItem(const DomItem &self) const; //  ### REVISIT: consider replacing return value with variant | 
|---|
| 572 | BindingValueKind valueKind() const; | 
|---|
| 573 | QString name() const { return m_name; } | 
|---|
| 574 | BindingType bindingType() const { return m_bindingType; } | 
|---|
| 575 | QmlObject const *objectValue() const; | 
|---|
| 576 | QList<QmlObject> const *arrayValue() const; | 
|---|
| 577 | std::shared_ptr<ScriptExpression> scriptExpressionValue() const; | 
|---|
| 578 | QmlObject *objectValue(); | 
|---|
| 579 | QList<QmlObject> *arrayValue(); | 
|---|
| 580 | std::shared_ptr<ScriptExpression> scriptExpressionValue(); | 
|---|
| 581 | QList<QmlObject> annotations() const { return m_annotations; } | 
|---|
| 582 | void setAnnotations(const QList<QmlObject> &annotations) { m_annotations = annotations; } | 
|---|
| 583 | void setValue(std::unique_ptr<BindingValue> &&value); | 
|---|
| 584 | Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &a, QmlObject **aPtr = nullptr); | 
|---|
| 585 | const RegionComments &() const { return m_comments; } | 
|---|
| 586 | RegionComments &() { return m_comments; } | 
|---|
| 587 | void updatePathFromOwner(const Path &newPath); | 
|---|
| 588 | void writeOut(const DomItem &self, OutWriter &lw) const; | 
|---|
| 589 | void writeOutValue(const DomItem &self, OutWriter &lw) const; | 
|---|
| 590 | bool isSignalHandler() const | 
|---|
| 591 | { | 
|---|
| 592 | QString baseName = m_name.split(sep: QLatin1Char('.')).last(); | 
|---|
| 593 | return QQmlSignalNames::isHandlerName(signalName: baseName); | 
|---|
| 594 | } | 
|---|
| 595 | static QString preCodeForName(QStringView n) | 
|---|
| 596 | { | 
|---|
| 597 | return QStringLiteral(u "QtObject{\n  %1: ").arg(a: n.split(sep: u'.').last()); | 
|---|
| 598 | } | 
|---|
| 599 | static QString postCodeForName(QStringView) { return QStringLiteral(u "\n}\n"); } | 
|---|
| 600 | QString preCode() const { return preCodeForName(n: m_name); } | 
|---|
| 601 | QString postCode() const { return postCodeForName(m_name); } | 
|---|
| 602 |  | 
|---|
| 603 | ScriptElementVariant bindingIdentifiers() const { return m_bindingIdentifiers; } | 
|---|
| 604 | void setBindingIdentifiers(const ScriptElementVariant &bindingIdentifiers) { m_bindingIdentifiers = bindingIdentifiers; } | 
|---|
| 605 |  | 
|---|
| 606 | private: | 
|---|
| 607 | friend class QQmlDomAstCreator; | 
|---|
| 608 | BindingType m_bindingType; | 
|---|
| 609 | QString m_name; | 
|---|
| 610 | std::unique_ptr<BindingValue> m_value; | 
|---|
| 611 | QList<QmlObject> m_annotations; | 
|---|
| 612 | RegionComments ; | 
|---|
| 613 | ScriptElementVariant m_bindingIdentifiers; | 
|---|
| 614 | }; | 
|---|
| 615 |  | 
|---|
| 616 | class QMLDOM_EXPORT AttributeInfo | 
|---|
| 617 | { | 
|---|
| 618 | public: | 
|---|
| 619 | enum Access { Private, Protected, Public }; | 
|---|
| 620 |  | 
|---|
| 621 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const; | 
|---|
| 622 |  | 
|---|
| 623 | Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &annotation, | 
|---|
| 624 | QmlObject **aPtr = nullptr); | 
|---|
| 625 | void updatePathFromOwner(const Path &newPath); | 
|---|
| 626 |  | 
|---|
| 627 | QQmlJSScope::ConstPtr semanticScope() const { return m_semanticScope; } | 
|---|
| 628 | void setSemanticScope(const QQmlJSScope::ConstPtr &scope) { m_semanticScope = scope; } | 
|---|
| 629 |  | 
|---|
| 630 | QString name; | 
|---|
| 631 | Access access = Access::Public; | 
|---|
| 632 | QString typeName; | 
|---|
| 633 | bool isReadonly = false; | 
|---|
| 634 | bool isList = false; | 
|---|
| 635 | QList<QmlObject> annotations; | 
|---|
| 636 | RegionComments ; | 
|---|
| 637 | QQmlJSScope::ConstPtr m_semanticScope; | 
|---|
| 638 | }; | 
|---|
| 639 |  | 
|---|
| 640 | struct QMLDOM_EXPORT LocallyResolvedAlias | 
|---|
| 641 | { | 
|---|
| 642 | enum class Status { Invalid, ResolvedProperty, ResolvedObject, Loop, TooDeep }; | 
|---|
| 643 | bool valid() | 
|---|
| 644 | { | 
|---|
| 645 | switch (status) { | 
|---|
| 646 | case Status::ResolvedProperty: | 
|---|
| 647 | case Status::ResolvedObject: | 
|---|
| 648 | return true; | 
|---|
| 649 | default: | 
|---|
| 650 | return false; | 
|---|
| 651 | } | 
|---|
| 652 | } | 
|---|
| 653 | DomItem baseObject; | 
|---|
| 654 | DomItem localPropertyDef; | 
|---|
| 655 | QString typeName; | 
|---|
| 656 | QStringList accessedPath; | 
|---|
| 657 | Status status = Status::Invalid; | 
|---|
| 658 | int nAliases = 0; | 
|---|
| 659 | }; | 
|---|
| 660 |  | 
|---|
| 661 | class QMLDOM_EXPORT PropertyDefinition : public AttributeInfo | 
|---|
| 662 | { | 
|---|
| 663 | public: | 
|---|
| 664 | constexpr static DomType kindValue = DomType::PropertyDefinition; | 
|---|
| 665 |  | 
|---|
| 666 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const | 
|---|
| 667 | { | 
|---|
| 668 | bool cont = AttributeInfo::iterateDirectSubpaths(self, visitor); | 
|---|
| 669 | cont = cont && self.dvValueField(visitor, f: Fields::isPointer, value: isPointer); | 
|---|
| 670 | cont = cont && self.dvValueField(visitor, f: Fields::isFinal, value: isFinal); | 
|---|
| 671 | cont = cont && self.dvValueField(visitor, f: Fields::isAlias, value: isAlias()); | 
|---|
| 672 | cont = cont && self.dvValueField(visitor, f: Fields::isDefaultMember, value: isDefaultMember); | 
|---|
| 673 | cont = cont && self.dvValueField(visitor, f: Fields::isRequired, value: isRequired); | 
|---|
| 674 | cont = cont && self.dvValueField(visitor, f: Fields::read, value: read); | 
|---|
| 675 | cont = cont && self.dvValueField(visitor, f: Fields::write, value: write); | 
|---|
| 676 | cont = cont && self.dvValueField(visitor, f: Fields::bindable, value: bindable); | 
|---|
| 677 | cont = cont && self.dvValueField(visitor, f: Fields::notify, value: notify); | 
|---|
| 678 | cont = cont && self.dvReferenceField(visitor, f: Fields::type, referencedObject: typePath()); | 
|---|
| 679 | if (m_nameIdentifiers) { | 
|---|
| 680 | cont = cont && self.dvItemField(visitor, f: Fields::nameIdentifiers, it: [this, &self]() { | 
|---|
| 681 | return self.subScriptElementWrapperItem(obj: m_nameIdentifiers); | 
|---|
| 682 | }); | 
|---|
| 683 | } | 
|---|
| 684 | return cont; | 
|---|
| 685 | } | 
|---|
| 686 |  | 
|---|
| 687 | Path typePath() const { return Paths::lookupTypePath(name: typeName); } | 
|---|
| 688 |  | 
|---|
| 689 | bool isAlias() const { return typeName == u "alias"; } | 
|---|
| 690 | bool isParametricType() const; | 
|---|
| 691 | void writeOut(const DomItem &self, OutWriter &lw) const; | 
|---|
| 692 | ScriptElementVariant nameIdentifiers() const { return m_nameIdentifiers; } | 
|---|
| 693 | void setNameIdentifiers(const ScriptElementVariant &name) { m_nameIdentifiers = name; } | 
|---|
| 694 |  | 
|---|
| 695 | QString read; | 
|---|
| 696 | QString write; | 
|---|
| 697 | QString bindable; | 
|---|
| 698 | QString notify; | 
|---|
| 699 | bool isFinal = false; | 
|---|
| 700 | bool isPointer = false; | 
|---|
| 701 | bool isDefaultMember = false; | 
|---|
| 702 | bool isRequired = false; | 
|---|
| 703 | ScriptElementVariant m_nameIdentifiers; | 
|---|
| 704 | }; | 
|---|
| 705 |  | 
|---|
| 706 | class QMLDOM_EXPORT PropertyInfo | 
|---|
| 707 | { | 
|---|
| 708 | public: | 
|---|
| 709 | constexpr static DomType kindValue = DomType::PropertyInfo; // used to get the correct kind in ObjectWrapper | 
|---|
| 710 |  | 
|---|
| 711 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const; | 
|---|
| 712 |  | 
|---|
| 713 | QList<DomItem> propertyDefs; | 
|---|
| 714 | QList<DomItem> bindings; | 
|---|
| 715 | }; | 
|---|
| 716 |  | 
|---|
| 717 | class QMLDOM_EXPORT MethodParameter | 
|---|
| 718 | { | 
|---|
| 719 | public: | 
|---|
| 720 | constexpr static DomType kindValue = DomType::MethodParameter; | 
|---|
| 721 | enum class TypeAnnotationStyle { | 
|---|
| 722 | Prefix, // a(int x) | 
|---|
| 723 | Suffix, // a(x : int) | 
|---|
| 724 | }; | 
|---|
| 725 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const; | 
|---|
| 726 |  | 
|---|
| 727 | void writeOut(const DomItem &self, OutWriter &ow) const; | 
|---|
| 728 | void writeOutSignal(const DomItem &self, OutWriter &ow) const; | 
|---|
| 729 |  | 
|---|
| 730 | QString name; | 
|---|
| 731 | QString typeName; | 
|---|
| 732 | bool isPointer = false; | 
|---|
| 733 | bool isReadonly = false; | 
|---|
| 734 | bool isList = false; | 
|---|
| 735 | bool isRestElement = false; | 
|---|
| 736 | std::shared_ptr<ScriptExpression> defaultValue; | 
|---|
| 737 | /*! | 
|---|
| 738 | \internal | 
|---|
| 739 | Contains the scriptElement representing this argument, inclusive default value, | 
|---|
| 740 | deconstruction, etc. | 
|---|
| 741 | */ | 
|---|
| 742 | std::shared_ptr<ScriptExpression> value; | 
|---|
| 743 | QList<QmlObject> annotations; | 
|---|
| 744 | RegionComments ; | 
|---|
| 745 | TypeAnnotationStyle typeAnnotationStyle = TypeAnnotationStyle::Suffix; | 
|---|
| 746 | }; | 
|---|
| 747 |  | 
|---|
| 748 | class QMLDOM_EXPORT MethodInfo : public AttributeInfo | 
|---|
| 749 | { | 
|---|
| 750 | Q_GADGET | 
|---|
| 751 | public: | 
|---|
| 752 | enum MethodType { Signal, Method }; | 
|---|
| 753 | Q_ENUM(MethodType) | 
|---|
| 754 |  | 
|---|
| 755 | constexpr static DomType kindValue = DomType::MethodInfo; | 
|---|
| 756 |  | 
|---|
| 757 | Path typePath(const DomItem &) const | 
|---|
| 758 | { | 
|---|
| 759 | return (typeName.isEmpty() ? Path() : Paths::lookupTypePath(name: typeName)); | 
|---|
| 760 | } | 
|---|
| 761 |  | 
|---|
| 762 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const; | 
|---|
| 763 | QString preCode(const DomItem &) const; // ### REVISIT, might be simplified by using different toplevel production rules at usage site | 
|---|
| 764 | QString postCode(const DomItem &) const; | 
|---|
| 765 | void writePre(const DomItem &self, OutWriter &ow) const; | 
|---|
| 766 | void writeOut(const DomItem &self, OutWriter &ow) const; | 
|---|
| 767 | void setCode(const QString &code) | 
|---|
| 768 | { | 
|---|
| 769 | body = std::make_shared<ScriptExpression>( | 
|---|
| 770 | args: code, args: ScriptExpression::ExpressionType::FunctionBody, args: 0, | 
|---|
| 771 | args: QLatin1String( "function foo(){\n"), args: QLatin1String( "\n}\n")); | 
|---|
| 772 | } | 
|---|
| 773 | MethodInfo() = default; | 
|---|
| 774 |  | 
|---|
| 775 | // TODO: make private + add getters/setters | 
|---|
| 776 | QList<MethodParameter> parameters; | 
|---|
| 777 | MethodType methodType = Method; | 
|---|
| 778 | std::shared_ptr<ScriptExpression> body; | 
|---|
| 779 | std::shared_ptr<ScriptExpression> returnType; | 
|---|
| 780 | bool isConstructor = false; | 
|---|
| 781 | }; | 
|---|
| 782 |  | 
|---|
| 783 | class QMLDOM_EXPORT EnumItem | 
|---|
| 784 | { | 
|---|
| 785 | public: | 
|---|
| 786 | constexpr static DomType kindValue = DomType::EnumItem; | 
|---|
| 787 | enum class ValueKind : quint8 { | 
|---|
| 788 | ImplicitValue, | 
|---|
| 789 | ExplicitValue | 
|---|
| 790 | }; | 
|---|
| 791 | EnumItem(const QString &name = QString(), int value = 0, ValueKind valueKind = ValueKind::ImplicitValue) | 
|---|
| 792 | : m_name(name), m_value(value), m_valueKind(valueKind) | 
|---|
| 793 | { | 
|---|
| 794 | } | 
|---|
| 795 |  | 
|---|
| 796 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const; | 
|---|
| 797 |  | 
|---|
| 798 | QString name() const { return m_name; } | 
|---|
| 799 | double value() const { return m_value; } | 
|---|
| 800 | RegionComments &() { return m_comments; } | 
|---|
| 801 | const RegionComments &() const { return m_comments; } | 
|---|
| 802 | void writeOut(const DomItem &self, OutWriter &lw) const; | 
|---|
| 803 |  | 
|---|
| 804 | private: | 
|---|
| 805 | QString m_name; | 
|---|
| 806 | double m_value; | 
|---|
| 807 | ValueKind m_valueKind; | 
|---|
| 808 | RegionComments ; | 
|---|
| 809 | }; | 
|---|
| 810 |  | 
|---|
| 811 | class QMLDOM_EXPORT EnumDecl final : public CommentableDomElement | 
|---|
| 812 | { | 
|---|
| 813 | public: | 
|---|
| 814 | constexpr static DomType kindValue = DomType::EnumDecl; | 
|---|
| 815 | DomType kind() const override { return kindValue; } | 
|---|
| 816 |  | 
|---|
| 817 | EnumDecl(const QString &name = QString(), QList<EnumItem> values = QList<EnumItem>(), | 
|---|
| 818 | Path pathFromOwner = Path()) | 
|---|
| 819 | : CommentableDomElement(pathFromOwner), m_name(name), m_values(values) | 
|---|
| 820 | { | 
|---|
| 821 | } | 
|---|
| 822 |  | 
|---|
| 823 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override; | 
|---|
| 824 |  | 
|---|
| 825 | QString name() const { return m_name; } | 
|---|
| 826 | void setName(const QString &name) { m_name = name; } | 
|---|
| 827 | const QList<EnumItem> &values() const & { return m_values; } | 
|---|
| 828 | bool isFlag() const { return m_isFlag; } | 
|---|
| 829 | void setIsFlag(bool flag) { m_isFlag = flag; } | 
|---|
| 830 | QString alias() const { return m_alias; } | 
|---|
| 831 | void setAlias(const QString &aliasName) { m_alias = aliasName; } | 
|---|
| 832 | void setValues(QList<EnumItem> values) { m_values = values; } | 
|---|
| 833 | Path addValue(EnumItem value) | 
|---|
| 834 | { | 
|---|
| 835 | m_values.append(t: value); | 
|---|
| 836 | return Path::Field(s: Fields::values).index(i: index_type(m_values.size() - 1)); | 
|---|
| 837 | } | 
|---|
| 838 | void updatePathFromOwner(const Path &newP) override; | 
|---|
| 839 |  | 
|---|
| 840 | const QList<QmlObject> &annotations() const & { return m_annotations; } | 
|---|
| 841 | void setAnnotations(const QList<QmlObject> &annotations); | 
|---|
| 842 | Path addAnnotation(const QmlObject &child, QmlObject **cPtr = nullptr); | 
|---|
| 843 | void writeOut(const DomItem &self, OutWriter &lw) const override; | 
|---|
| 844 |  | 
|---|
| 845 | private: | 
|---|
| 846 | QString m_name; | 
|---|
| 847 | bool m_isFlag = false; | 
|---|
| 848 | QString m_alias; | 
|---|
| 849 | QList<EnumItem> m_values; | 
|---|
| 850 | QList<QmlObject> m_annotations; | 
|---|
| 851 | }; | 
|---|
| 852 |  | 
|---|
| 853 | class QMLDOM_EXPORT QmlObject final : public CommentableDomElement | 
|---|
| 854 | { | 
|---|
| 855 | Q_DECLARE_TR_FUNCTIONS(QmlObject) | 
|---|
| 856 | public: | 
|---|
| 857 | constexpr static DomType kindValue = DomType::QmlObject; | 
|---|
| 858 | DomType kind() const override { return kindValue; } | 
|---|
| 859 |  | 
|---|
| 860 | QmlObject(const Path &pathFromOwner = Path()); | 
|---|
| 861 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override; | 
|---|
| 862 | bool iterateBaseDirectSubpaths(const DomItem &self, DirectVisitor) const; | 
|---|
| 863 | QList<QString> fields() const; | 
|---|
| 864 | QList<QString> fields(const DomItem &) const override { return fields(); } | 
|---|
| 865 | DomItem field(const DomItem &self, QStringView name) const override; | 
|---|
| 866 | void updatePathFromOwner(const Path &newPath) override; | 
|---|
| 867 | QString localDefaultPropertyName() const; | 
|---|
| 868 | QString defaultPropertyName(const DomItem &self) const; | 
|---|
| 869 | virtual bool iterateSubOwners(const DomItem &self, function_ref<bool(const DomItem &owner)> visitor) const; | 
|---|
| 870 |  | 
|---|
| 871 | QString idStr() const { return m_idStr; } | 
|---|
| 872 | QString name() const { return m_name; } | 
|---|
| 873 | const QList<Path> &prototypePaths() const & { return m_prototypePaths; } | 
|---|
| 874 | Path nextScopePath() const { return m_nextScopePath; } | 
|---|
| 875 | const QMultiMap<QString, PropertyDefinition> &propertyDefs() const & { return m_propertyDefs; } | 
|---|
| 876 | const QMultiMap<QString, Binding> &bindings() const & { return m_bindings; } | 
|---|
| 877 | const QMultiMap<QString, MethodInfo> &methods() const & { return m_methods; } | 
|---|
| 878 | QList<QmlObject> children() const { return m_children; } | 
|---|
| 879 | QList<QmlObject> annotations() const { return m_annotations; } | 
|---|
| 880 |  | 
|---|
| 881 | void setIdStr(const QString &id) { m_idStr = id; } | 
|---|
| 882 | void setName(const QString &name) { m_name = name; } | 
|---|
| 883 | void setDefaultPropertyName(const QString &name) { m_defaultPropertyName = name; } | 
|---|
| 884 | void setPrototypePaths(QList<Path> prototypePaths) { m_prototypePaths = prototypePaths; } | 
|---|
| 885 | Path addPrototypePath(const Path &prototypePath) | 
|---|
| 886 | { | 
|---|
| 887 | index_type idx = index_type(m_prototypePaths.indexOf(t: prototypePath)); | 
|---|
| 888 | if (idx == -1) { | 
|---|
| 889 | idx = index_type(m_prototypePaths.size()); | 
|---|
| 890 | m_prototypePaths.append(t: prototypePath); | 
|---|
| 891 | } | 
|---|
| 892 | return Path::Field(s: Fields::prototypes).index(i: idx); | 
|---|
| 893 | } | 
|---|
| 894 | void setNextScopePath(const Path &nextScopePath) { m_nextScopePath = nextScopePath; } | 
|---|
| 895 | void setPropertyDefs(QMultiMap<QString, PropertyDefinition> propertyDefs) | 
|---|
| 896 | { | 
|---|
| 897 | m_propertyDefs = propertyDefs; | 
|---|
| 898 | } | 
|---|
| 899 | void setBindings(QMultiMap<QString, Binding> bindings) { m_bindings = bindings; } | 
|---|
| 900 | void setMethods(QMultiMap<QString, MethodInfo> functionDefs) { m_methods = functionDefs; } | 
|---|
| 901 | void setChildren(const QList<QmlObject> &children) | 
|---|
| 902 | { | 
|---|
| 903 | m_children = children; | 
|---|
| 904 | if (pathFromOwner()) | 
|---|
| 905 | updatePathFromOwner(newPath: pathFromOwner()); | 
|---|
| 906 | } | 
|---|
| 907 | void setAnnotations(const QList<QmlObject> &annotations) | 
|---|
| 908 | { | 
|---|
| 909 | m_annotations = annotations; | 
|---|
| 910 | if (pathFromOwner()) | 
|---|
| 911 | updatePathFromOwner(newPath: pathFromOwner()); | 
|---|
| 912 | } | 
|---|
| 913 | Path addPropertyDef(const PropertyDefinition &propertyDef, AddOption option, | 
|---|
| 914 | PropertyDefinition **pDef = nullptr) | 
|---|
| 915 | { | 
|---|
| 916 | return insertUpdatableElementInMultiMap(mapPathFromOwner: pathFromOwner().field(name: Fields::propertyDefs), | 
|---|
| 917 | mmap&: m_propertyDefs, key: propertyDef.name, value: propertyDef, | 
|---|
| 918 | option, valuePtr: pDef); | 
|---|
| 919 | } | 
|---|
| 920 | MutableDomItem addPropertyDef(MutableDomItem &self, const PropertyDefinition &propertyDef, | 
|---|
| 921 | AddOption option); | 
|---|
| 922 |  | 
|---|
| 923 | Path addBinding(Binding binding, AddOption option, Binding **bPtr = nullptr) | 
|---|
| 924 | { | 
|---|
| 925 | return insertUpdatableElementInMultiMap(mapPathFromOwner: pathFromOwner().field(name: Fields::bindings), mmap&: m_bindings, | 
|---|
| 926 | key: binding.name(), value: binding, option, valuePtr: bPtr); | 
|---|
| 927 | } | 
|---|
| 928 | MutableDomItem addBinding(MutableDomItem &self, Binding binding, AddOption option); | 
|---|
| 929 | Path addMethod(const MethodInfo &functionDef, AddOption option, MethodInfo **mPtr = nullptr) | 
|---|
| 930 | { | 
|---|
| 931 | return insertUpdatableElementInMultiMap(mapPathFromOwner: pathFromOwner().field(name: Fields::methods), mmap&: m_methods, | 
|---|
| 932 | key: functionDef.name, value: functionDef, option, valuePtr: mPtr); | 
|---|
| 933 | } | 
|---|
| 934 | MutableDomItem addMethod(MutableDomItem &self, const MethodInfo &functionDef, AddOption option); | 
|---|
| 935 | Path addChild(QmlObject child, QmlObject **cPtr = nullptr) | 
|---|
| 936 | { | 
|---|
| 937 | return appendUpdatableElementInQList(listPathFromOwner: pathFromOwner().field(name: Fields::children), list&: m_children, | 
|---|
| 938 | value: child, vPtr: cPtr); | 
|---|
| 939 | } | 
|---|
| 940 | MutableDomItem addChild(MutableDomItem &self, QmlObject child) | 
|---|
| 941 | { | 
|---|
| 942 | Path p = addChild(child); | 
|---|
| 943 | return MutableDomItem(self.owner().item(), p); | 
|---|
| 944 | } | 
|---|
| 945 | Path addAnnotation(const QmlObject &annotation, QmlObject **aPtr = nullptr) | 
|---|
| 946 | { | 
|---|
| 947 | return appendUpdatableElementInQList(listPathFromOwner: pathFromOwner().field(name: Fields::annotations), | 
|---|
| 948 | list&: m_annotations, value: annotation, vPtr: aPtr); | 
|---|
| 949 | } | 
|---|
| 950 | void writeOut(const DomItem &self, OutWriter &ow, const QString &onTarget) const; | 
|---|
| 951 | void writeOut(const DomItem &self, OutWriter &lw) const override { writeOut(self, ow&: lw, onTarget: QString()); } | 
|---|
| 952 |  | 
|---|
| 953 | LocallyResolvedAlias resolveAlias(const DomItem &self, | 
|---|
| 954 | std::shared_ptr<ScriptExpression> accessSequence) const; | 
|---|
| 955 | LocallyResolvedAlias resolveAlias(const DomItem &self, const QStringList &accessSequence) const; | 
|---|
| 956 |  | 
|---|
| 957 | QQmlJSScope::ConstPtr semanticScope() const { return m_scope; } | 
|---|
| 958 | void setSemanticScope(const QQmlJSScope::ConstPtr &scope) { m_scope = scope; } | 
|---|
| 959 |  | 
|---|
| 960 | ScriptElementVariant nameIdentifiers() const { return m_nameIdentifiers; } | 
|---|
| 961 | void setNameIdentifiers(const ScriptElementVariant &name) { m_nameIdentifiers = name; } | 
|---|
| 962 |  | 
|---|
| 963 | private: | 
|---|
| 964 | friend class QQmlDomAstCreator; | 
|---|
| 965 | QString m_idStr; | 
|---|
| 966 | QString m_name; | 
|---|
| 967 | QList<Path> m_prototypePaths; | 
|---|
| 968 | Path m_nextScopePath; | 
|---|
| 969 | QString m_defaultPropertyName; | 
|---|
| 970 | QMultiMap<QString, PropertyDefinition> m_propertyDefs; | 
|---|
| 971 | QMultiMap<QString, Binding> m_bindings; | 
|---|
| 972 | QMultiMap<QString, MethodInfo> m_methods; | 
|---|
| 973 | QList<QmlObject> m_children; | 
|---|
| 974 | QList<QmlObject> m_annotations; | 
|---|
| 975 | QQmlJSScope::ConstPtr m_scope; | 
|---|
| 976 | ScriptElementVariant m_nameIdentifiers; | 
|---|
| 977 | }; | 
|---|
| 978 |  | 
|---|
| 979 | class Export | 
|---|
| 980 | { | 
|---|
| 981 | Q_DECLARE_TR_FUNCTIONS(Export) | 
|---|
| 982 | public: | 
|---|
| 983 | constexpr static DomType kindValue = DomType::Export; | 
|---|
| 984 | static Export fromString( | 
|---|
| 985 | const Path &source, QStringView exp, const Path &typePath, const ErrorHandler &h); | 
|---|
| 986 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const | 
|---|
| 987 | { | 
|---|
| 988 | bool cont = true; | 
|---|
| 989 | cont = cont && self.dvValueField(visitor, f: Fields::uri, value: uri); | 
|---|
| 990 | cont = cont && self.dvValueField(visitor, f: Fields::typeName, value: typeName); | 
|---|
| 991 | cont = cont && self.dvWrapField(visitor, f: Fields::version, obj: version); | 
|---|
| 992 | if (typePath) | 
|---|
| 993 | cont = cont && self.dvReferenceField(visitor, f: Fields::type, referencedObject: typePath); | 
|---|
| 994 | cont = cont && self.dvValueField(visitor, f: Fields::isInternal, value: isInternal); | 
|---|
| 995 | cont = cont && self.dvValueField(visitor, f: Fields::isSingleton, value: isSingleton); | 
|---|
| 996 | if (exportSourcePath) | 
|---|
| 997 | cont = cont && self.dvReferenceField(visitor, f: Fields::exportSource, referencedObject: exportSourcePath); | 
|---|
| 998 | return cont; | 
|---|
| 999 | } | 
|---|
| 1000 |  | 
|---|
| 1001 | Path exportSourcePath; | 
|---|
| 1002 | QString uri; | 
|---|
| 1003 | QString typeName; | 
|---|
| 1004 | Version version; | 
|---|
| 1005 | Path typePath; | 
|---|
| 1006 | bool isInternal = false; | 
|---|
| 1007 | bool isSingleton = false; | 
|---|
| 1008 | }; | 
|---|
| 1009 |  | 
|---|
| 1010 | class QMLDOM_EXPORT Component : public CommentableDomElement | 
|---|
| 1011 | { | 
|---|
| 1012 | public: | 
|---|
| 1013 | Component(const QString &name); | 
|---|
| 1014 | Component(const Path &pathFromOwner = Path()); | 
|---|
| 1015 | Component(const Component &o) = default; | 
|---|
| 1016 | Component &operator=(const Component &) = default; | 
|---|
| 1017 |  | 
|---|
| 1018 | bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override; | 
|---|
| 1019 | void updatePathFromOwner(const Path &newPath) override; | 
|---|
| 1020 | DomItem field(const DomItem &self, QStringView name) const override; | 
|---|
| 1021 |  | 
|---|
| 1022 | QString name() const { return m_name; } | 
|---|
| 1023 | const QMultiMap<QString, EnumDecl> &enumerations() const & { return m_enumerations; } | 
|---|
| 1024 | const QList<QmlObject> &objects() const & { return m_objects; } | 
|---|
| 1025 | bool isSingleton() const { return m_isSingleton; } | 
|---|
| 1026 | bool isCreatable() const { return m_isCreatable; } | 
|---|
| 1027 | bool isComposite() const { return m_isComposite; } | 
|---|
| 1028 | QString attachedTypeName() const { return m_attachedTypeName; } | 
|---|
| 1029 | Path attachedTypePath(const DomItem &) const { return m_attachedTypePath; } | 
|---|
| 1030 |  | 
|---|
| 1031 | void setName(const QString &name) { m_name = name; } | 
|---|
| 1032 | void setEnumerations(QMultiMap<QString, EnumDecl> enumerations) | 
|---|
| 1033 | { | 
|---|
| 1034 | m_enumerations = enumerations; | 
|---|
| 1035 | } | 
|---|
| 1036 | Path addEnumeration(const EnumDecl &enumeration, AddOption option = AddOption::Overwrite, | 
|---|
| 1037 | EnumDecl **ePtr = nullptr) | 
|---|
| 1038 | { | 
|---|
| 1039 | return insertUpdatableElementInMultiMap(mapPathFromOwner: pathFromOwner().field(name: Fields::enumerations), | 
|---|
| 1040 | mmap&: m_enumerations, key: enumeration.name(), value: enumeration, | 
|---|
| 1041 | option, valuePtr: ePtr); | 
|---|
| 1042 | } | 
|---|
| 1043 | void setObjects(const QList<QmlObject> &objects) { m_objects = objects; } | 
|---|
| 1044 | Path addObject(const QmlObject &object, QmlObject **oPtr = nullptr); | 
|---|
| 1045 | void setIsSingleton(bool isSingleton) { m_isSingleton = isSingleton; } | 
|---|
| 1046 | void setIsCreatable(bool isCreatable) { m_isCreatable = isCreatable; } | 
|---|
| 1047 | void setIsComposite(bool isComposite) { m_isComposite = isComposite; } | 
|---|
| 1048 | void setAttachedTypeName(const QString &name) { m_attachedTypeName = name; } | 
|---|
| 1049 | void setAttachedTypePath(const Path &p) { m_attachedTypePath = p; } | 
|---|
| 1050 |  | 
|---|
| 1051 | private: | 
|---|
| 1052 | friend class QQmlDomAstCreator; | 
|---|
| 1053 | QString m_name; | 
|---|
| 1054 | QMultiMap<QString, EnumDecl> m_enumerations; | 
|---|
| 1055 | QList<QmlObject> m_objects; | 
|---|
| 1056 | bool m_isSingleton = false; | 
|---|
| 1057 | bool m_isCreatable = true; | 
|---|
| 1058 | bool m_isComposite = true; | 
|---|
| 1059 | QString m_attachedTypeName; | 
|---|
| 1060 | Path m_attachedTypePath; | 
|---|
| 1061 | }; | 
|---|
| 1062 |  | 
|---|
| 1063 | class QMLDOM_EXPORT JsResource final : public Component | 
|---|
| 1064 | { | 
|---|
| 1065 | public: | 
|---|
| 1066 | constexpr static DomType kindValue = DomType::JsResource; | 
|---|
| 1067 | DomType kind() const override { return kindValue; } | 
|---|
| 1068 |  | 
|---|
| 1069 | JsResource(const Path &pathFromOwner = Path()) : Component(pathFromOwner) { } | 
|---|
| 1070 | bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override | 
|---|
| 1071 | { // to do: complete | 
|---|
| 1072 | return true; | 
|---|
| 1073 | } | 
|---|
| 1074 | // globalSymbols defined/exported, required/used | 
|---|
| 1075 | }; | 
|---|
| 1076 |  | 
|---|
| 1077 | class QMLDOM_EXPORT QmltypesComponent final : public Component | 
|---|
| 1078 | { | 
|---|
| 1079 | public: | 
|---|
| 1080 | constexpr static DomType kindValue = DomType::QmltypesComponent; | 
|---|
| 1081 | DomType kind() const override { return kindValue; } | 
|---|
| 1082 |  | 
|---|
| 1083 | QmltypesComponent(const Path &pathFromOwner = Path()) : Component(pathFromOwner) { } | 
|---|
| 1084 | bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override; | 
|---|
| 1085 | const QList<Export> &exports() const & { return m_exports; } | 
|---|
| 1086 | QString fileName() const { return m_fileName; } | 
|---|
| 1087 | void setExports(QList<Export> exports) { m_exports = exports; } | 
|---|
| 1088 | void addExport(const Export &exportedEntry) { m_exports.append(t: exportedEntry); } | 
|---|
| 1089 | void setFileName(const QString &fileName) { m_fileName = fileName; } | 
|---|
| 1090 | const QList<int> &metaRevisions() const & { return m_metaRevisions; } | 
|---|
| 1091 | void setMetaRevisions(QList<int> metaRevisions) { m_metaRevisions = metaRevisions; } | 
|---|
| 1092 | void setInterfaceNames(const QStringList& interfaces) { m_interfaceNames = interfaces; } | 
|---|
| 1093 | const QStringList &interfaceNames() const & { return m_interfaceNames; } | 
|---|
| 1094 | QString extensionTypeName() const { return m_extensionTypeName; } | 
|---|
| 1095 | void setExtensionTypeName(const QString &name) { m_extensionTypeName =  name; } | 
|---|
| 1096 | QString valueTypeName() const { return m_valueTypeName; } | 
|---|
| 1097 | void setValueTypeName(const QString &name) { m_valueTypeName = name; } | 
|---|
| 1098 | bool hasCustomParser() const { return m_hasCustomParser; } | 
|---|
| 1099 | void setHasCustomParser(bool v) { m_hasCustomParser = v; } | 
|---|
| 1100 | bool extensionIsJavaScript() const { return m_extensionIsJavaScript; } | 
|---|
| 1101 | void setExtensionIsJavaScript(bool v) { m_extensionIsJavaScript = v; } | 
|---|
| 1102 | bool extensionIsNamespace() const { return m_extensionIsNamespace; } | 
|---|
| 1103 | void setExtensionIsNamespace(bool v) { m_extensionIsNamespace = v; } | 
|---|
| 1104 | QQmlJSScope::AccessSemantics accessSemantics() const { return m_accessSemantics; } | 
|---|
| 1105 | void setAccessSemantics(QQmlJSScope::AccessSemantics v) { m_accessSemantics = v; } | 
|---|
| 1106 |  | 
|---|
| 1107 | void setSemanticScope(const QQmlJSScope::ConstPtr &scope) { m_semanticScope = scope; } | 
|---|
| 1108 | QQmlJSScope::ConstPtr semanticScope() const { return m_semanticScope; } | 
|---|
| 1109 |  | 
|---|
| 1110 | private: | 
|---|
| 1111 | QList<Export> m_exports; | 
|---|
| 1112 | QList<int> m_metaRevisions; | 
|---|
| 1113 | QString m_fileName; // remove? | 
|---|
| 1114 | QStringList m_interfaceNames; | 
|---|
| 1115 | bool m_hasCustomParser = false; | 
|---|
| 1116 | bool m_extensionIsJavaScript = false; | 
|---|
| 1117 | bool m_extensionIsNamespace = false; | 
|---|
| 1118 | QString m_valueTypeName; | 
|---|
| 1119 | QString m_extensionTypeName; | 
|---|
| 1120 | QQmlJSScope::AccessSemantics m_accessSemantics = QQmlJSScope::AccessSemantics::None; | 
|---|
| 1121 | QQmlJSScope::ConstPtr m_semanticScope; | 
|---|
| 1122 | }; | 
|---|
| 1123 |  | 
|---|
| 1124 | class QMLDOM_EXPORT QmlComponent final : public Component | 
|---|
| 1125 | { | 
|---|
| 1126 | public: | 
|---|
| 1127 | constexpr static DomType kindValue = DomType::QmlComponent; | 
|---|
| 1128 | DomType kind() const override { return kindValue; } | 
|---|
| 1129 |  | 
|---|
| 1130 | QmlComponent(const QString &name = QString()) : Component(name) | 
|---|
| 1131 | { | 
|---|
| 1132 | setIsComposite(true); | 
|---|
| 1133 | setIsCreatable(true); | 
|---|
| 1134 | } | 
|---|
| 1135 |  | 
|---|
| 1136 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override; | 
|---|
| 1137 |  | 
|---|
| 1138 | const QMultiMap<QString, Id> &ids() const & { return m_ids; } | 
|---|
| 1139 | Path nextComponentPath() const { return m_nextComponentPath; } | 
|---|
| 1140 | void setIds(QMultiMap<QString, Id> ids) { m_ids = ids; } | 
|---|
| 1141 | void setNextComponentPath(const Path &p) { m_nextComponentPath = p; } | 
|---|
| 1142 | void updatePathFromOwner(const Path &newPath) override; | 
|---|
| 1143 | Path addId(const Id &id, AddOption option = AddOption::Overwrite, Id **idPtr = nullptr) | 
|---|
| 1144 | { | 
|---|
| 1145 | // warning does nor remove old idStr when overwriting... | 
|---|
| 1146 | return insertUpdatableElementInMultiMap(mapPathFromOwner: pathFromOwner().field(name: Fields::ids), mmap&: m_ids, key: id.name, | 
|---|
| 1147 | value: id, option, valuePtr: idPtr); | 
|---|
| 1148 | } | 
|---|
| 1149 | void writeOut(const DomItem &self, OutWriter &) const override; | 
|---|
| 1150 | QList<QString> subComponentsNames(const DomItem &self) const; | 
|---|
| 1151 | QList<DomItem> subComponents(const DomItem &self) const; | 
|---|
| 1152 |  | 
|---|
| 1153 | void setSemanticScope(const QQmlJSScope::ConstPtr &scope) { m_semanticScope = scope; } | 
|---|
| 1154 | QQmlJSScope::ConstPtr semanticScope() const { return m_semanticScope; } | 
|---|
| 1155 | ScriptElementVariant nameIdentifiers() const { return m_nameIdentifiers; } | 
|---|
| 1156 | void setNameIdentifiers(const ScriptElementVariant &name) { m_nameIdentifiers = name; } | 
|---|
| 1157 |  | 
|---|
| 1158 | private: | 
|---|
| 1159 | friend class QQmlDomAstCreator; | 
|---|
| 1160 | Path m_nextComponentPath; | 
|---|
| 1161 | QMultiMap<QString, Id> m_ids; | 
|---|
| 1162 | QQmlJSScope::ConstPtr m_semanticScope; | 
|---|
| 1163 | // m_nameIdentifiers contains the name of the component as FieldMemberExpression, and therefore | 
|---|
| 1164 | // only exists in inline components! | 
|---|
| 1165 | ScriptElementVariant m_nameIdentifiers; | 
|---|
| 1166 | }; | 
|---|
| 1167 |  | 
|---|
| 1168 | class QMLDOM_EXPORT GlobalComponent final : public Component | 
|---|
| 1169 | { | 
|---|
| 1170 | public: | 
|---|
| 1171 | constexpr static DomType kindValue = DomType::GlobalComponent; | 
|---|
| 1172 | DomType kind() const override { return kindValue; } | 
|---|
| 1173 |  | 
|---|
| 1174 | GlobalComponent(const Path &pathFromOwner = Path()) : Component(pathFromOwner) { } | 
|---|
| 1175 | }; | 
|---|
| 1176 |  | 
|---|
| 1177 | static ErrorGroups importErrors = { .groups: { DomItem::domErrorGroup, NewErrorGroup( "importError") } }; | 
|---|
| 1178 |  | 
|---|
| 1179 | class QMLDOM_EXPORT ImportScope | 
|---|
| 1180 | { | 
|---|
| 1181 | Q_DECLARE_TR_FUNCTIONS(ImportScope) | 
|---|
| 1182 | public: | 
|---|
| 1183 | constexpr static DomType kindValue = DomType::ImportScope; | 
|---|
| 1184 |  | 
|---|
| 1185 | ImportScope() = default; | 
|---|
| 1186 | ~ImportScope() = default; | 
|---|
| 1187 |  | 
|---|
| 1188 | const QList<Path> &importSourcePaths() const & { return m_importSourcePaths; } | 
|---|
| 1189 |  | 
|---|
| 1190 | const QMap<QString, ImportScope> &subImports() const & { return m_subImports; } | 
|---|
| 1191 |  | 
|---|
| 1192 | QList<Path> allSources(const DomItem &self) const; | 
|---|
| 1193 |  | 
|---|
| 1194 | QSet<QString> importedNames(const DomItem &self) const | 
|---|
| 1195 | { | 
|---|
| 1196 | QSet<QString> res; | 
|---|
| 1197 | const auto sources = allSources(self); | 
|---|
| 1198 | for (const Path &p : sources) { | 
|---|
| 1199 | QSet<QString> ks = self.path(p: p.field(name: Fields::exports), h: self.errorHandler()).keys(); | 
|---|
| 1200 | res += ks; | 
|---|
| 1201 | } | 
|---|
| 1202 | return res; | 
|---|
| 1203 | } | 
|---|
| 1204 |  | 
|---|
| 1205 | QList<DomItem> importedItemsWithName(const DomItem &self, const QString &name) const | 
|---|
| 1206 | { | 
|---|
| 1207 | QList<DomItem> res; | 
|---|
| 1208 | const auto sources = allSources(self); | 
|---|
| 1209 | for (const Path &p : sources) { | 
|---|
| 1210 | DomItem source = self.path(p: p.field(name: Fields::exports), h: self.errorHandler()); | 
|---|
| 1211 | DomItem els = source.key(name); | 
|---|
| 1212 | int nEls = els.indexes(); | 
|---|
| 1213 | for (int i = 0; i < nEls; ++i) | 
|---|
| 1214 | res.append(t: els.index(i)); | 
|---|
| 1215 | if (nEls == 0 && els) { | 
|---|
| 1216 | self.addError(msg: importErrors.warning( | 
|---|
| 1217 | message: tr(sourceText: "Looking up '%1' expected a list of exports, not %2") | 
|---|
| 1218 | .arg(args: name, args: els.toString()))); | 
|---|
| 1219 | } | 
|---|
| 1220 | } | 
|---|
| 1221 | return res; | 
|---|
| 1222 | } | 
|---|
| 1223 |  | 
|---|
| 1224 | QList<Export> importedExportsWithName(const DomItem &self, const QString &name) const | 
|---|
| 1225 | { | 
|---|
| 1226 | QList<Export> res; | 
|---|
| 1227 | for (const DomItem &i : importedItemsWithName(self, name)) | 
|---|
| 1228 | if (const Export *e = i.as<Export>()) | 
|---|
| 1229 | res.append(t: *e); | 
|---|
| 1230 | else | 
|---|
| 1231 | self.addError(msg: importErrors.warning( | 
|---|
| 1232 | message: tr(sourceText: "Expected Export looking up '%1', not %2").arg(args: name, args: i.toString()))); | 
|---|
| 1233 | return res; | 
|---|
| 1234 | } | 
|---|
| 1235 |  | 
|---|
| 1236 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const; | 
|---|
| 1237 |  | 
|---|
| 1238 | void addImport(QStringList p, const Path &targetExports) | 
|---|
| 1239 | { | 
|---|
| 1240 | if (!p.isEmpty()) { | 
|---|
| 1241 | const QString current = p.takeFirst(); | 
|---|
| 1242 | m_subImports[current].addImport(p: std::move(p), targetExports); | 
|---|
| 1243 | } else if (!m_importSourcePaths.contains(t: targetExports)) { | 
|---|
| 1244 | m_importSourcePaths.append(t: targetExports); | 
|---|
| 1245 | } | 
|---|
| 1246 | } | 
|---|
| 1247 |  | 
|---|
| 1248 | private: | 
|---|
| 1249 | QList<Path> m_importSourcePaths; | 
|---|
| 1250 | QMap<QString, ImportScope> m_subImports; | 
|---|
| 1251 | }; | 
|---|
| 1252 |  | 
|---|
| 1253 | class BindingValue | 
|---|
| 1254 | { | 
|---|
| 1255 | public: | 
|---|
| 1256 | BindingValue(); | 
|---|
| 1257 | BindingValue(const QmlObject &o); | 
|---|
| 1258 | BindingValue(const std::shared_ptr<ScriptExpression> &o); | 
|---|
| 1259 | BindingValue(const QList<QmlObject> &l); | 
|---|
| 1260 | ~BindingValue(); | 
|---|
| 1261 | BindingValue(const BindingValue &o); | 
|---|
| 1262 | BindingValue &operator=(const BindingValue &o); | 
|---|
| 1263 |  | 
|---|
| 1264 | DomItem value(const DomItem &binding) const; | 
|---|
| 1265 | void updatePathFromOwner(const Path &newPath); | 
|---|
| 1266 |  | 
|---|
| 1267 | private: | 
|---|
| 1268 | friend class Binding; | 
|---|
| 1269 | void clearValue(); | 
|---|
| 1270 |  | 
|---|
| 1271 | BindingValueKind kind; | 
|---|
| 1272 | union { | 
|---|
| 1273 | int dummy; | 
|---|
| 1274 | QmlObject object; | 
|---|
| 1275 | std::shared_ptr<ScriptExpression> scriptExpression; | 
|---|
| 1276 | QList<QmlObject> array; | 
|---|
| 1277 | }; | 
|---|
| 1278 | }; | 
|---|
| 1279 |  | 
|---|
| 1280 | } // end namespace Dom | 
|---|
| 1281 | } // end namespace QQmlJS | 
|---|
| 1282 | QT_END_NAMESPACE | 
|---|
| 1283 | #endif // QQMLDOMELEMENTS_P_H | 
|---|
| 1284 |  | 
|---|