1 | // Copyright (C) 2020 The Qt Company Ltd. |
---|---|
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QQMLDOMEXTERNALITEMS_P_H |
5 | #define QQMLDOMEXTERNALITEMS_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 "qqmldomelements_p.h" |
20 | #include "qqmldommoduleindex_p.h" |
21 | #include "qqmldomcomments_p.h" |
22 | |
23 | #include <QtQml/private/qqmljsast_p.h> |
24 | #include <QtQml/private/qqmljsengine_p.h> |
25 | #include <QtQml/private/qqmldirparser_p.h> |
26 | #include <QtQmlCompiler/private/qqmljstyperesolver_p.h> |
27 | #include <QtCore/QMetaType> |
28 | #include <QtCore/qregularexpression.h> |
29 | |
30 | #include <limits> |
31 | #include <memory> |
32 | |
33 | Q_DECLARE_METATYPE(QQmlDirParser::Plugin) |
34 | |
35 | QT_BEGIN_NAMESPACE |
36 | |
37 | namespace QQmlJS { |
38 | namespace Dom { |
39 | |
40 | /*! |
41 | \internal |
42 | \class QQmlJS::Dom::ExternalOwningItem |
43 | |
44 | \brief A OwningItem that refers to an external resource (file,...) |
45 | |
46 | Every owning item has a file or directory it refers to. |
47 | |
48 | |
49 | */ |
50 | class QMLDOM_EXPORT ExternalOwningItem: public OwningItem { |
51 | public: |
52 | ExternalOwningItem( |
53 | const QString &filePath, const QDateTime &lastDataUpdateAt, const Path &pathFromTop, |
54 | int derivedFrom = 0, const QString &code = QString()); |
55 | ExternalOwningItem(const ExternalOwningItem &o) = default; |
56 | QString canonicalFilePath(const DomItem &) const override; |
57 | QString canonicalFilePath() const; |
58 | Path canonicalPath(const DomItem &) const override; |
59 | Path canonicalPath() const; |
60 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override |
61 | { |
62 | bool cont = OwningItem::iterateDirectSubpaths(self, visitor); |
63 | cont = cont && self.dvValueLazyField(visitor, f: Fields::canonicalFilePath, valueF: [this]() { |
64 | return canonicalFilePath(); |
65 | }); |
66 | cont = cont |
67 | && self.dvValueLazyField(visitor, f: Fields::isValid, valueF: [this]() { return isValid(); }); |
68 | if (!code().isNull()) |
69 | cont = cont |
70 | && self.dvValueLazyField(visitor, f: Fields::code, valueF: [this]() { return code(); }); |
71 | return cont; |
72 | } |
73 | |
74 | bool iterateSubOwners(const DomItem &self, function_ref<bool(const DomItem &owner)> visitor) override |
75 | { |
76 | bool cont = OwningItem::iterateSubOwners(self, visitor); |
77 | cont = cont && self.field(name: Fields::components).visitKeys(visitor: [visitor](const QString &, const DomItem &comps) { |
78 | return comps.visitIndexes(visitor: [visitor](const DomItem &comp) { |
79 | return comp.field(name: Fields::objects).visitIndexes(visitor: [visitor](const DomItem &qmlObj) { |
80 | if (const QmlObject *qmlObjPtr = qmlObj.as<QmlObject>()) |
81 | return qmlObjPtr->iterateSubOwners(self: qmlObj, visitor); |
82 | Q_ASSERT(false); |
83 | return true; |
84 | }); |
85 | }); |
86 | }); |
87 | return cont; |
88 | } |
89 | |
90 | bool isValid() const { |
91 | QMutexLocker l(mutex()); |
92 | return m_isValid; |
93 | } |
94 | void setIsValid(bool val) { |
95 | QMutexLocker l(mutex()); |
96 | m_isValid = val; |
97 | } |
98 | // null code means invalid |
99 | const QString &code() const { return m_code; } |
100 | |
101 | protected: |
102 | QString m_canonicalFilePath; |
103 | QString m_code; |
104 | Path m_path; |
105 | bool m_isValid = false; |
106 | }; |
107 | |
108 | class QMLDOM_EXPORT QmlDirectory final : public ExternalOwningItem |
109 | { |
110 | protected: |
111 | std::shared_ptr<OwningItem> doCopy(const DomItem &) const override |
112 | { |
113 | return std::make_shared<QmlDirectory>(args: *this); |
114 | } |
115 | |
116 | public: |
117 | constexpr static DomType kindValue = DomType::QmlDirectory; |
118 | DomType kind() const override { return kindValue; } |
119 | QmlDirectory( |
120 | const QString &filePath = QString(), const QStringList &dirList = QStringList(), |
121 | const QDateTime &lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC), |
122 | int derivedFrom = 0); |
123 | QmlDirectory(const QmlDirectory &o) = default; |
124 | |
125 | std::shared_ptr<QmlDirectory> makeCopy(const DomItem &self) const |
126 | { |
127 | return std::static_pointer_cast<QmlDirectory>(r: doCopy(self)); |
128 | } |
129 | |
130 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override; |
131 | |
132 | const QMultiMap<QString, Export> &exports() const & { return m_exports; } |
133 | |
134 | const QMultiMap<QString, QString> &qmlFiles() const & { return m_qmlFiles; } |
135 | |
136 | bool addQmlFilePath(const QString &relativePath); |
137 | |
138 | private: |
139 | QMultiMap<QString, Export> m_exports; |
140 | QMultiMap<QString, QString> m_qmlFiles; |
141 | }; |
142 | |
143 | class QMLDOM_EXPORT QmldirFile final : public ExternalOwningItem |
144 | { |
145 | Q_DECLARE_TR_FUNCTIONS(QmldirFile) |
146 | protected: |
147 | std::shared_ptr<OwningItem> doCopy(const DomItem &) const override |
148 | { |
149 | auto copy = std::make_shared<QmldirFile>(args: *this); |
150 | return copy; |
151 | } |
152 | |
153 | public: |
154 | constexpr static DomType kindValue = DomType::QmldirFile; |
155 | DomType kind() const override { return kindValue; } |
156 | |
157 | static ErrorGroups myParsingErrors(); |
158 | |
159 | QmldirFile( |
160 | const QString &filePath = QString(), const QString &code = QString(), |
161 | const QDateTime &lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC), |
162 | int derivedFrom = 0) |
163 | : ExternalOwningItem(filePath, lastDataUpdateAt, Paths::qmldirFilePath(path: filePath), |
164 | derivedFrom, code) |
165 | { |
166 | } |
167 | QmldirFile(const QmldirFile &o) = default; |
168 | |
169 | static std::shared_ptr<QmldirFile> fromPathAndCode(const QString &path, const QString &code); |
170 | |
171 | std::shared_ptr<QmldirFile> makeCopy(const DomItem &self) const |
172 | { |
173 | return std::static_pointer_cast<QmldirFile>(r: doCopy(self)); |
174 | } |
175 | |
176 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override; |
177 | |
178 | QmlUri uri() const { return m_uri; } |
179 | |
180 | const QSet<int> &majorVersions() const & { return m_majorVersions; } |
181 | |
182 | const QMultiMap<QString, Export> &exports() const & { return m_exports; } |
183 | |
184 | const QList<Import> &imports() const & { return m_imports; } |
185 | |
186 | const QList<Path> &qmltypesFilePaths() const & { return m_qmltypesFilePaths; } |
187 | |
188 | QMap<QString, QString> qmlFiles() const; |
189 | |
190 | bool designerSupported() const { return m_qmldir.designerSupported(); } |
191 | |
192 | QStringList classNames() const { return m_qmldir.classNames(); } |
193 | |
194 | QList<ModuleAutoExport> autoExports() const; |
195 | void setAutoExports(const QList<ModuleAutoExport> &autoExport); |
196 | |
197 | void ensureInModuleIndex(const DomItem &self, const QString &uri) const; |
198 | |
199 | private: |
200 | void parse(); |
201 | void setFromQmldir(); |
202 | |
203 | QmlUri m_uri; |
204 | QSet<int> m_majorVersions; |
205 | QQmlDirParser m_qmldir; |
206 | QList<QQmlDirParser::Plugin> m_plugins; |
207 | QList<Import> m_imports; |
208 | QList<ModuleAutoExport> m_autoExports; |
209 | QMultiMap<QString, Export> m_exports; |
210 | QList<Path> m_qmltypesFilePaths; |
211 | }; |
212 | |
213 | class QMLDOM_EXPORT JsFile final : public ExternalOwningItem |
214 | { |
215 | protected: |
216 | std::shared_ptr<OwningItem> doCopy(const DomItem &) const override |
217 | { |
218 | auto copy = std::make_shared<JsFile>(args: *this); |
219 | return copy; |
220 | } |
221 | |
222 | public: |
223 | constexpr static DomType kindValue = DomType::JsFile; |
224 | DomType kind() const override { return kindValue; } |
225 | JsFile(const QString &filePath = QString(), |
226 | const QDateTime &lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC), |
227 | const Path &pathFromTop = Path(), int derivedFrom = 0) |
228 | : ExternalOwningItem(filePath, lastDataUpdateAt, pathFromTop, derivedFrom) |
229 | { |
230 | } |
231 | JsFile(const QString &filePath = QString(), const QString &code = QString(), |
232 | const QDateTime &lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC), |
233 | int derivedFrom = 0); |
234 | JsFile(const JsFile &o) = default; |
235 | |
236 | std::shared_ptr<JsFile> makeCopy(const DomItem &self) const |
237 | { |
238 | return std::static_pointer_cast<JsFile>(r: doCopy(self)); |
239 | } |
240 | |
241 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const |
242 | override; // iterates the *direct* subpaths, returns false if a quick end was requested |
243 | |
244 | std::shared_ptr<QQmlJS::Engine> engine() const { return m_engine; } |
245 | JsResource rootComponent() const { return m_rootComponent; } |
246 | void setFileLocationsTree(const FileLocations::Tree &v) { m_fileLocationsTree = std::move(v); } |
247 | |
248 | static ErrorGroups myParsingErrors(); |
249 | |
250 | void writeOut(const DomItem &self, OutWriter &lw) const override; |
251 | void setExpression(const std::shared_ptr<ScriptExpression> &script) { m_script = script; } |
252 | |
253 | void initPragmaLibrary() { m_pragmaLibrary = LegacyPragmaLibrary{}; }; |
254 | void addFileImport(const QString &jsfile, const QString &module); |
255 | void addModuleImport(const QString &uri, const QString &version, const QString &module); |
256 | |
257 | private: |
258 | void writeOutDirectives(OutWriter &lw) const; |
259 | |
260 | /* |
261 | Entities with Legacy prefix are here to support formatting of the discouraged |
262 | .import, .pragma directives in .js files. |
263 | Taking into account that usage of these directives is discouraged and |
264 | the fact that current usecase is limited to the formatting of .js, it's arguably should not |
265 | be exposed and kept private. |
266 | |
267 | LegacyPragma corresponds to the only one existing .pragma library |
268 | |
269 | LegacyImport is capable of representing the following import statements: |
270 | .import T_STRING_LITERAL as T_IDENTIFIER |
271 | .import T_IDENTIFIER (. T_IDENTIFIER)* (T_VERSION_NUMBER (. T_VERSION_NUMBER)?)? as T_IDENTIFIER |
272 | |
273 | LegacyDirectivesCollector is a workaround for collecting those directives. |
274 | At the moment of writing .import, .pragma in .js files do not have corresponding |
275 | representative AST::Node-s. Collecting of those is happening during the lexing |
276 | */ |
277 | |
278 | struct LegacyPragmaLibrary |
279 | { |
280 | void writeOut(OutWriter &lw) const; |
281 | }; |
282 | |
283 | struct LegacyImport |
284 | { |
285 | QString fileName; // file import |
286 | QString uri; // module import |
287 | QString version; // used for module import |
288 | QString asIdentifier; // .import ... as T_Identifier |
289 | |
290 | void writeOut(OutWriter &lw) const; |
291 | }; |
292 | |
293 | class LegacyDirectivesCollector : public QQmlJS::Directives |
294 | { |
295 | public: |
296 | LegacyDirectivesCollector(JsFile &file) : m_file(file){}; |
297 | |
298 | void pragmaLibrary() override { m_file.initPragmaLibrary(); }; |
299 | void importFile(const QString &jsfile, const QString &module, int, int) override |
300 | { |
301 | m_file.addFileImport(jsfile, module); |
302 | }; |
303 | void importModule(const QString &uri, const QString &version, const QString &module, int, |
304 | int) override |
305 | { |
306 | m_file.addModuleImport(uri, version, module); |
307 | }; |
308 | |
309 | private: |
310 | JsFile &m_file; |
311 | }; |
312 | |
313 | private: |
314 | std::shared_ptr<QQmlJS::Engine> m_engine; |
315 | std::optional<LegacyPragmaLibrary> m_pragmaLibrary = std::nullopt; |
316 | QList<LegacyImport> m_imports; |
317 | std::shared_ptr<ScriptExpression> m_script; |
318 | JsResource m_rootComponent; |
319 | FileLocations::Tree m_fileLocationsTree; |
320 | }; |
321 | |
322 | class QMLDOM_EXPORT QmlFile final : public ExternalOwningItem |
323 | { |
324 | protected: |
325 | std::shared_ptr<OwningItem> doCopy(const DomItem &self) const override; |
326 | |
327 | public: |
328 | constexpr static DomType kindValue = DomType::QmlFile; |
329 | DomType kind() const override { return kindValue; } |
330 | |
331 | enum RecoveryOption { DisableParserRecovery, EnableParserRecovery }; |
332 | |
333 | QmlFile(const QString &filePath = QString(), const QString &code = QString(), |
334 | const QDateTime &lastDataUpdate = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC), |
335 | int derivedFrom = 0, RecoveryOption option = DisableParserRecovery); |
336 | static ErrorGroups myParsingErrors(); |
337 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const |
338 | override; // iterates the *direct* subpaths, returns false if a quick end was requested |
339 | DomItem field(const DomItem &self, QStringView name) const override; |
340 | std::shared_ptr<QmlFile> makeCopy(const DomItem &self) const |
341 | { |
342 | return std::static_pointer_cast<QmlFile>(r: doCopy(self)); |
343 | } |
344 | void addError(const DomItem &self, ErrorMessage &&msg) override; |
345 | |
346 | const QMultiMap<QString, QmlComponent> &components() const & |
347 | { |
348 | return lazyMembers().m_components; |
349 | } |
350 | void setComponents(const QMultiMap<QString, QmlComponent> &components) |
351 | { |
352 | lazyMembers().m_components = components; |
353 | } |
354 | Path addComponent(const QmlComponent &component, AddOption option = AddOption::Overwrite, |
355 | QmlComponent **cPtr = nullptr) |
356 | { |
357 | QStringList nameEls = component.name().split(sep: QChar::fromLatin1(c: '.')); |
358 | QString key = nameEls.mid(pos: 1).join(sep: QChar::fromLatin1(c: '.')); |
359 | return insertUpdatableElementInMultiMap(mapPathFromOwner: Path::Field(s: Fields::components), mmap&: lazyMembers().m_components, |
360 | key, value: component, option, valuePtr: cPtr); |
361 | } |
362 | |
363 | void writeOut(const DomItem &self, OutWriter &lw) const override; |
364 | |
365 | AST::UiProgram *ast() const |
366 | { |
367 | return m_ast; // avoid making it public? would make moving away from it easier |
368 | } |
369 | const QList<Import> &imports() const & |
370 | { |
371 | return lazyMembers().m_imports; |
372 | } |
373 | void setImports(const QList<Import> &imports) { lazyMembers().m_imports = imports; } |
374 | Path addImport(const Import &i) |
375 | { |
376 | auto &members = lazyMembers(); |
377 | index_type idx = index_type(members.m_imports.size()); |
378 | members.m_imports.append(t: i); |
379 | if (i.uri.isModule()) { |
380 | members.m_importScope.addImport(p: (i.importId.isEmpty() |
381 | ? QStringList() |
382 | : i.importId.split(sep: QChar::fromLatin1(c: '.'))), |
383 | targetExports: i.importedPath()); |
384 | } else { |
385 | QString path = i.uri.absoluteLocalPath(basePath: canonicalFilePath()); |
386 | if (!path.isEmpty()) |
387 | members.m_importScope.addImport( |
388 | p: (i.importId.isEmpty() ? QStringList() |
389 | : i.importId.split(sep: QChar::fromLatin1(c: '.'))), |
390 | targetExports: Paths::qmlDirPath(path)); |
391 | } |
392 | return Path::Field(s: Fields::imports).index(i: idx); |
393 | } |
394 | std::shared_ptr<QQmlJS::Engine> engine() const { return m_engine; } |
395 | RegionComments &comments() { return lazyMembers().m_comments; } |
396 | std::shared_ptr<AstComments> astComments() const { return lazyMembers().m_astComments; } |
397 | void setAstComments(const std::shared_ptr<AstComments> &comm) { lazyMembers().m_astComments = comm; } |
398 | FileLocations::Tree fileLocationsTree() const { return lazyMembers().m_fileLocationsTree; } |
399 | void setFileLocationsTree(const FileLocations::Tree &v) { lazyMembers().m_fileLocationsTree = v; } |
400 | const QList<Pragma> &pragmas() const & { return lazyMembers().m_pragmas; } |
401 | void setPragmas(QList<Pragma> pragmas) { lazyMembers().m_pragmas = pragmas; } |
402 | Path addPragma(const Pragma &pragma) |
403 | { |
404 | auto &members = lazyMembers(); |
405 | int idx = members.m_pragmas.size(); |
406 | members.m_pragmas.append(t: pragma); |
407 | return Path::Field(s: Fields::pragmas).index(i: idx); |
408 | } |
409 | ImportScope &importScope() { return lazyMembers().m_importScope; } |
410 | const ImportScope &importScope() const { return lazyMembers().m_importScope; } |
411 | |
412 | std::shared_ptr<QQmlJSTypeResolver> typeResolver() const |
413 | { |
414 | return lazyMembers().m_typeResolver; |
415 | } |
416 | void setTypeResolverWithDependencies(const std::shared_ptr<QQmlJSTypeResolver> &typeResolver, |
417 | const QQmlJSTypeResolverDependencies &dependencies) |
418 | { |
419 | auto &members = lazyMembers(); |
420 | members.m_typeResolver = typeResolver; |
421 | members.m_typeResolverDependencies = dependencies; |
422 | } |
423 | |
424 | DomCreationOptions creationOptions() const { return lazyMembers().m_creationOptions; } |
425 | |
426 | QQmlJSScope::ConstPtr handleForPopulation() const |
427 | { |
428 | return m_handleForPopulation; |
429 | } |
430 | |
431 | void setHandleForPopulation(const QQmlJSScope::ConstPtr &scope) |
432 | { |
433 | m_handleForPopulation = scope; |
434 | } |
435 | |
436 | |
437 | private: |
438 | // The lazy parts of QmlFile are inside of QmlFileLazy. |
439 | struct QmlFileLazy |
440 | { |
441 | QmlFileLazy(FileLocations::Tree fileLocationsTree, AstComments *astComments) |
442 | : m_fileLocationsTree(fileLocationsTree), m_astComments(astComments) |
443 | { |
444 | } |
445 | RegionComments m_comments; |
446 | QMultiMap<QString, QmlComponent> m_components; |
447 | QList<Pragma> m_pragmas; |
448 | QList<Import> m_imports; |
449 | ImportScope m_importScope; |
450 | FileLocations::Tree m_fileLocationsTree; |
451 | std::shared_ptr<AstComments> m_astComments; |
452 | DomCreationOptions m_creationOptions; |
453 | std::shared_ptr<QQmlJSTypeResolver> m_typeResolver; |
454 | QQmlJSTypeResolverDependencies m_typeResolverDependencies; |
455 | }; |
456 | friend class QQmlDomAstCreator; |
457 | AST::UiProgram *m_ast; // avoid? would make moving away from it easier |
458 | std::shared_ptr<Engine> m_engine; |
459 | QQmlJSScope::ConstPtr m_handleForPopulation; |
460 | mutable std::optional<QmlFileLazy> m_lazyMembers; |
461 | |
462 | void ensurePopulated() const |
463 | { |
464 | if (m_lazyMembers) |
465 | return; |
466 | |
467 | m_lazyMembers.emplace(args: FileLocations::createTree(basePath: canonicalPath()), args: new AstComments(m_engine)); |
468 | |
469 | // populate via the QQmlJSScope by accessing the (lazy) pointer |
470 | if (m_handleForPopulation.factory()) { |
471 | // silence no-discard attribute: |
472 | Q_UNUSED(m_handleForPopulation.data()); |
473 | } |
474 | } |
475 | const QmlFileLazy &lazyMembers() const |
476 | { |
477 | ensurePopulated(); |
478 | return *m_lazyMembers; |
479 | } |
480 | QmlFileLazy &lazyMembers() |
481 | { |
482 | ensurePopulated(); |
483 | return *m_lazyMembers; |
484 | } |
485 | }; |
486 | |
487 | class QMLDOM_EXPORT QmltypesFile final : public ExternalOwningItem |
488 | { |
489 | protected: |
490 | std::shared_ptr<OwningItem> doCopy(const DomItem &) const override |
491 | { |
492 | auto res = std::make_shared<QmltypesFile>(args: *this); |
493 | return res; |
494 | } |
495 | |
496 | public: |
497 | constexpr static DomType kindValue = DomType::QmltypesFile; |
498 | DomType kind() const override { return kindValue; } |
499 | |
500 | QmltypesFile( |
501 | const QString &filePath = QString(), const QString &code = QString(), |
502 | const QDateTime &lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC), |
503 | int derivedFrom = 0) |
504 | : ExternalOwningItem(filePath, lastDataUpdateAt, Paths::qmltypesFilePath(path: filePath), |
505 | derivedFrom, code) |
506 | { |
507 | } |
508 | |
509 | QmltypesFile(const QmltypesFile &o) = default; |
510 | |
511 | void ensureInModuleIndex(const DomItem &self) const; |
512 | |
513 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override; |
514 | std::shared_ptr<QmltypesFile> makeCopy(const DomItem &self) const |
515 | { |
516 | return std::static_pointer_cast<QmltypesFile>(r: doCopy(self)); |
517 | } |
518 | |
519 | void addImport(const Import i) |
520 | { // builder only: not threadsafe... |
521 | m_imports.append(t: i); |
522 | } |
523 | const QList<Import> &imports() const & { return m_imports; } |
524 | const QMultiMap<QString, QmltypesComponent> &components() const & { return m_components; } |
525 | void setComponents(QMultiMap<QString, QmltypesComponent> c) { m_components = std::move(c); } |
526 | Path addComponent(const QmltypesComponent &comp, AddOption option = AddOption::Overwrite, |
527 | QmltypesComponent **cPtr = nullptr) |
528 | { |
529 | for (const Export &e : comp.exports()) |
530 | addExport(e); |
531 | return insertUpdatableElementInMultiMap(mapPathFromOwner: Path::Field(s: u"components"), mmap&: m_components, |
532 | key: comp.name(), value: comp, option, valuePtr: cPtr); |
533 | } |
534 | const QMultiMap<QString, Export> &exports() const & { return m_exports; } |
535 | void setExports(QMultiMap<QString, Export> e) { m_exports = e; } |
536 | Path addExport(const Export &e) |
537 | { |
538 | index_type i = m_exports.values(key: e.typeName).size(); |
539 | m_exports.insert(key: e.typeName, value: e); |
540 | addUri(uri: e.uri, majorVersion: e.version.majorVersion); |
541 | return canonicalPath().field(name: Fields::exports).index(i); |
542 | } |
543 | |
544 | const QMap<QString, QSet<int>> &uris() const & { return m_uris; } |
545 | void addUri(const QString &uri, int majorVersion) |
546 | { |
547 | QSet<int> &v = m_uris[uri]; |
548 | if (!v.contains(value: majorVersion)) { |
549 | v.insert(value: majorVersion); |
550 | } |
551 | } |
552 | |
553 | private: |
554 | QList<Import> m_imports; |
555 | QMultiMap<QString, QmltypesComponent> m_components; |
556 | QMultiMap<QString, Export> m_exports; |
557 | QMap<QString, QSet<int>> m_uris; |
558 | }; |
559 | |
560 | class QMLDOM_EXPORT GlobalScope final : public ExternalOwningItem |
561 | { |
562 | protected: |
563 | std::shared_ptr<OwningItem> doCopy(const DomItem &) const override; |
564 | |
565 | public: |
566 | constexpr static DomType kindValue = DomType::GlobalScope; |
567 | DomType kind() const override { return kindValue; } |
568 | |
569 | GlobalScope( |
570 | const QString &filePath = QString(), |
571 | const QDateTime &lastDataUpdateAt = QDateTime::fromMSecsSinceEpoch(msecs: 0, timeZone: QTimeZone::UTC), |
572 | int derivedFrom = 0) |
573 | : ExternalOwningItem(filePath, lastDataUpdateAt, Paths::globalScopePath(name: filePath), |
574 | derivedFrom) |
575 | { |
576 | setIsValid(true); |
577 | } |
578 | |
579 | bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override; |
580 | std::shared_ptr<GlobalScope> makeCopy(const DomItem &self) const |
581 | { |
582 | return std::static_pointer_cast<GlobalScope>(r: doCopy(self)); |
583 | } |
584 | QString name() const { return m_name; } |
585 | Language language() const { return m_language; } |
586 | GlobalComponent rootComponent() const { return m_rootComponent; } |
587 | void setName(const QString &name) { m_name = name; } |
588 | void setLanguage(Language language) { m_language = language; } |
589 | void setRootComponent(const GlobalComponent &ob) |
590 | { |
591 | m_rootComponent = ob; |
592 | m_rootComponent.updatePathFromOwner(newPath: Path::Field(s: Fields::rootComponent)); |
593 | } |
594 | |
595 | private: |
596 | QString m_name; |
597 | Language m_language; |
598 | GlobalComponent m_rootComponent; |
599 | }; |
600 | |
601 | } // end namespace Dom |
602 | } // end namespace QQmlJS |
603 | QT_END_NAMESPACE |
604 | #endif // QQMLDOMEXTERNALITEMS_P_H |
605 |
Definitions
- ExternalOwningItem
- ExternalOwningItem
- iterateDirectSubpaths
- iterateSubOwners
- isValid
- setIsValid
- code
- QmlDirectory
- doCopy
- kindValue
- kind
- QmlDirectory
- makeCopy
- exports
- qmlFiles
- QmldirFile
- doCopy
- kindValue
- kind
- QmldirFile
- QmldirFile
- makeCopy
- uri
- majorVersions
- exports
- imports
- qmltypesFilePaths
- designerSupported
- classNames
- JsFile
- doCopy
- kindValue
- kind
- JsFile
- JsFile
- makeCopy
- engine
- rootComponent
- setFileLocationsTree
- setExpression
- initPragmaLibrary
- LegacyPragmaLibrary
- LegacyImport
- LegacyDirectivesCollector
- LegacyDirectivesCollector
- pragmaLibrary
- importFile
- importModule
- QmlFile
- kindValue
- kind
- RecoveryOption
- makeCopy
- components
- setComponents
- addComponent
- ast
- imports
- setImports
- addImport
- engine
- comments
- astComments
- setAstComments
- fileLocationsTree
- setFileLocationsTree
- pragmas
- setPragmas
- addPragma
- importScope
- importScope
- typeResolver
- setTypeResolverWithDependencies
- creationOptions
- handleForPopulation
- setHandleForPopulation
- QmlFileLazy
- QmlFileLazy
- ensurePopulated
- lazyMembers
- lazyMembers
- QmltypesFile
- doCopy
- kindValue
- kind
- QmltypesFile
- QmltypesFile
- makeCopy
- addImport
- imports
- components
- setComponents
- addComponent
- exports
- setExports
- addExport
- uris
- addUri
- GlobalScope
- kindValue
- kind
- GlobalScope
- makeCopy
- name
- language
- rootComponent
- setName
- setLanguage
Learn to use CMake with our Intro Training
Find out more