11#include <QtQml/private/qqmljslexer_p.h>
12#include <QtQml/private/qqmljsparser_p.h>
13#include <QtQml/private/qqmljsengine_p.h>
14#include <QtQml/private/qqmljsastvisitor_p.h>
15#include <QtQml/private/qqmljsast_p.h>
17#include <QtCore/QScopeGuard>
18#include <QtCore/QFileInfo>
19#include <QtCore/QRegularExpressionMatch>
32 int derivedFrom,
const QString &code)
34 m_canonicalFilePath(filePath),
80void QmldirFile::parse()
91void QmldirFile::setFromQmldir()
105 QString exportFilePath = baseDir.filePath(
el.fileName);
107 if (canonicalExportFilePath.isEmpty())
109 canonicalExportFilePath = exportFilePath;
111 exp.exportSourcePath = exportSource;
112 exp.isSingleton =
el.singleton;
113 exp.isInternal =
el.internal;
115 Version((
el.version.hasMajorVersion() ?
el.version.majorVersion() : majorVersion),
116 el.version.hasMinorVersion() ?
el.version.minorVersion() : 0);
117 exp.typeName =
el.typeName;
120 m_exports.insert(exp.typeName, exp);
121 if (exp.version.majorVersion > 0)
122 m_majorVersions.
insert(exp.version.majorVersion);
124 for (
auto const &
el : m_qmldir.scripts()) {
125 QString exportFilePath = baseDir.filePath(
el.fileName);
127 if (canonicalExportFilePath.isEmpty())
129 canonicalExportFilePath = exportFilePath;
131 exp.exportSourcePath = exportSource;
132 exp.isSingleton =
true;
133 exp.isInternal =
false;
135 Version((
el.version.hasMajorVersion() ?
el.version.majorVersion() : majorVersion),
136 el.version.hasMinorVersion() ?
el.version.minorVersion() : 0);
139 exp.typeName =
el.nameSpace;
140 m_exports.insert(exp.typeName, exp);
141 if (exp.version.majorVersion > 0)
142 m_majorVersions.
insert(exp.version.majorVersion);
151 v =
Version((imp.version.hasMajorVersion() ? imp.version.majorVersion()
153 (imp.version.hasMinorVersion() ? imp.version.minorVersion()
157 m_autoExports.append(
163 qCDebug(QQmlJSDomImporting) <<
"QmldirFile::setFromQmlDir: ignoring initial version"
164 " 'auto' in depends command, using latest version"
168 (imp.version.hasMajorVersion() ? imp.version.majorVersion() : int(
Version::Latest)),
169 (imp.version.hasMinorVersion() ? imp.version.minorVersion()
173 bool hasInvalidTypeinfo =
false;
174 for (
auto const &
el : m_qmldir.typeInfos()) {
177 if (elPath.isRelative())
178 elPath =
QFileInfo(baseDir.filePath(elStr));
179 QString typeInfoPath = elPath.canonicalFilePath();
180 if (typeInfoPath.isEmpty()) {
181 hasInvalidTypeinfo =
true;
182 typeInfoPath = elPath.absoluteFilePath();
186 if (m_qmltypesFilePaths.isEmpty() || hasInvalidTypeinfo) {
192 if (!m_qmltypesFilePaths.contains(
p))
193 m_qmltypesFilePaths.append(
p);
196 bool hasErrors =
false;
204 m_plugins = m_qmldir.
plugins();
209 return m_autoExports;
214 m_autoExports = autoExport;
224 DomItem env = self.environment();
226 for (
int majorV : m_majorVersions) {
246 cont = cont && self.dvValueField(visitor, Fields::uri,
uri().
toString());
247 cont = cont && self.dvValueField(visitor, Fields::designerSupported,
designerSupported());
248 cont = cont && self.dvReferencesField(visitor, Fields::qmltypesFiles, m_qmltypesFilePaths);
249 cont = cont && self.dvWrapField(visitor, Fields::exports, m_exports);
250 cont = cont && self.dvWrapField(visitor, Fields::imports, m_imports);
251 cont = cont && self.dvItemField(visitor, Fields::plugins, [
this, &self]() {
253 return self.subListItem(List::fromQListRef<QQmlDirParser::Plugin>(
254 self.pathFromOwner().field(Fields::plugins), m_plugins,
257 return list.subDataItem(p, pluginData(plugin, cNames));
262 cont = cont && self.dvItemField(visitor, Fields::qmlFiles, [
this, &self]() {
263 const QMap<QString, QString> typeFileMap =
qmlFiles();
264 return self.subMapItem(
Map(
265 self.pathFromOwner().field(Fields::qmlFiles),
267 QString path = typeFileMap.value(typeV);
271 return map.subReferencesItem(
273 QList<Path>({ Paths::qmlFileObjectPath(path) }));
275 [typeFileMap](
const DomItem &) {
276 return QSet<QString>(typeFileMap.keyBegin(), typeFileMap.keyEnd());
280 cont = cont && self.dvWrapField(visitor, Fields::autoExports, m_autoExports);
284QMap<QString, QString> QmldirFile::qmlFiles()
const
289 QMap<QString, QString>
res;
290 for (
const auto &e : m_exports)
292 e.typePath[2].headName());
299 :
ExternalOwningItem(filePath, lastDataUpdateAt, Paths::qmlFilePath(filePath), derivedFrom,
302 m_engine = std::make_shared<QQmlJS::Engine>();
303 LegacyDirectivesCollector directivesCollector(*
this);
304 m_engine->setDirectives(&directivesCollector);
308 QQmlJS::Parser parser(m_engine.get());
311 bool isValid = isESM ? parser.parseModule() : parser.parseProgram();
314 const auto diagnostics = parser.diagnosticMessages();
320 auto astComments = std::make_shared<AstComments>(m_engine);
324 m_script = std::make_shared<ScriptExpression>(
code, m_engine, parser.rootNode(), astComments,
339 cont = cont && self.dvWrapField(visitor, Fields::fileLocationsTree, m_fileLocationsTree);
341 cont = cont && self.dvItemField(visitor, Fields::expression, [
this, &self]() {
342 return self.subOwnerItem(
PathEls::Field(Fields::expression), m_script);
349 writeOutDirectives(ow);
351 if (
DomItem script = self.field(Fields::expression)) {
360 import.fileName = jsfile;
361 import.asIdentifier =
module;
362 m_imports.
append(std::move(
import));
369 import.version = version;
370 import.asIdentifier =
module;
371 m_imports.
append(std::move(
import));
374void JsFile::LegacyPragmaLibrary::writeOut(
OutWriter &lw)
const
379void JsFile::LegacyImport::writeOut(OutWriter &lw)
const
384 lw.write(u
".import").space();
386 lw.write(uri).space();
387 if (!version.isEmpty()) {
388 lw.write(version).space();
391 lw.write(u
"\"").write(
fileName).write(u
"\"").space();
408void JsFile::writeOutDirectives(OutWriter &ow)
const
410 if (m_pragmaLibrary.has_value()) {
411 m_pragmaLibrary->writeOut(ow);
413 for (
const auto &
import : m_imports) {
420 auto res = std::make_shared<QmlFile>(*
this);
451 QQmlJS::Parser parser(m_engine.get());
453 parser.setIdentifierInsertionEnabled(
true);
454 parser.setIncompleteBindingsEnabled(
true);
457 const auto diagnostics = parser.diagnosticMessages();
462 m_ast = parser.ast();
476 cont = cont && self.dvWrapField(visitor, Fields::components,
members.m_components);
477 cont = cont && self.dvWrapField(visitor, Fields::pragmas,
members.m_pragmas);
478 cont = cont && self.dvWrapField(visitor, Fields::imports,
members.m_imports);
479 cont = cont && self.dvWrapField(visitor, Fields::importScope,
members.m_importScope);
481 && self.dvWrapField(visitor, Fields::fileLocationsTree,
members.m_fileLocationsTree);
482 cont = cont && self.dvWrapField(visitor, Fields::comments,
members.m_comments);
483 cont = cont && self.dvWrapField(visitor, Fields::astComments,
members.m_astComments);
490 if (
name == Fields::components)
491 return self.wrapField(Fields::components, lazyMembers().m_components);
497 self.containingObject().addError(std::move(msg));
503 for (
const DomItem &
p : self.field(Fields::pragmas).values()) {
506 for (
auto i : self.field(Fields::imports).values()) {
516 auto res = std::make_shared<GlobalScope>(
531 DomItem env = self.environment();
535 for (
int majorV :
it.value()) {
538 mIndex->addQmltypeFilePath(self.canonicalPath());
548 cont = cont && self.dvWrapField(visitor, Fields::components, m_components);
549 cont = cont && self.dvWrapField(visitor, Fields::exports, m_exports);
550 cont = cont && self.dvItemField(visitor, Fields::uris, [
this, &self]() {
551 return self.subMapItem(Map::fromMapRef<QSet<int>>(
552 self.pathFromOwner().field(Fields::uris), m_uris,
554 QList<int> l(el.cbegin(), el.cend());
555 std::sort(l.begin(), l.end());
556 return map.subListItem(
557 List::fromQList<int>(map.pathFromOwner().appendComponent(p), l,
558 [](const DomItem &list, const PathEls::PathComponent &p,
559 int el) { return list.subDataItem(p, el); }));
562 cont = cont && self.dvWrapField(visitor, Fields::imports, m_imports);
566QmlDirectory::QmlDirectory(
569 :
ExternalOwningItem(filePath, lastDataUpdateAt, Paths::qmlDirectoryPath(filePath), derivedFrom,
580 cont = cont && self.dvWrapField(visitor, Fields::exports, m_exports);
581 cont = cont && self.dvItemField(visitor, Fields::qmlFiles, [
this, &self]() ->
DomItem {
583 return self.subMapItem(
Map(
584 self.pathFromOwner().field(Fields::qmlFiles),
587 auto it = m_qmlFiles.find(key);
588 while (it != m_qmlFiles.end() && it.key() == key) {
589 res.append(Paths::qmlFilePath(
590 QFileInfo(baseDir.filePath(it.value())).canonicalFilePath()));
597 return QSet<QString>(
keys.begin(),
keys.end());
599 u
"List<Reference>"_s));
608 uR
"((?<compName>[a-zA-z0-9_]+)\.(?:qml|qmlannotation|ui\.qml))")
611 if (
m.hasMatch() && !m_qmlFiles.
values(
m.captured(u
"compName")).
contains(relativePath)) {
612 m_qmlFiles.
insert(
m.captured(u
"compName"), relativePath);
\inmodule QtCore\reentrant
void append(const QCborValue &value)
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
static QDateTime currentDateTimeUtc()
QString suffix() const
Returns the suffix (extension) of the file.
QString canonicalFilePath() const
Returns the file system entry's canonical path, including the entry's name, that is,...
QDir dir() const
Returns a QDir object representing the path of the parent directory of the file system entry that thi...
void append(parameter_type t)
QList< Key > keys() const
iterator insert(const Key &key, const T &value)
QList< T > values() const
bool parse(const QString &source)
url is used for generating errors.
QString typeNamespace() const
QList< Plugin > plugins() const
virtual DomItem field(const DomItem &self, QStringView name) const
Represents a consistent set of types organized in modules, it is the top level of the DOM.
static ErrorGroup domErrorGroup
std::shared_ptr< T > ownerAs() const
Represents a set of tags grouping a set of related error messages.
Represents an error message connected to the dom.
A OwningItem that refers to an external resource (file,...)
Path canonicalPath() const
const QString & code() const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
QString m_canonicalFilePath
QString canonicalFilePath() const
void setIsValid(bool val)
ExternalOwningItem(const QString &filePath, const QDateTime &lastDataUpdateAt, const Path &pathFromTop, int derivedFrom=0, const QString &code=QString())
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
std::shared_ptr< OwningItem > doCopy(const DomItem &) const override
void addModuleImport(const QString &uri, const QString &version, const QString &module)
void addFileImport(const QString &jsfile, const QString &module)
static ErrorGroups myParsingErrors()
void writeOut(const DomItem &self, OutWriter &lw) const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
OutWriter & ensureNewline(int nNewlines=1)
OutWriter & write(QStringView v, LineWriter::TextAddType t=LineWriter::TextAddType::Normal)
virtual QDateTime lastDataUpdateAt() const
virtual int revision() const
void addErrorLocal(ErrorMessage &&msg)
Path field(const QString &name) const
static Path Field(QStringView s=u"")
bool addQmlFilePath(const QString &relativePath)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
std::shared_ptr< OwningItem > doCopy(const DomItem &self) const override
void addError(const DomItem &self, ErrorMessage &&msg) override
static ErrorGroups myParsingErrors()
QmlFile(const QString &filePath=QString(), const QString &code=QString(), const QDateTime &lastDataUpdate=QDateTime::fromMSecsSinceEpoch(0, QTimeZone::UTC), int derivedFrom=0, RecoveryOption option=DisableParserRecovery)
void writeOut(const DomItem &self, OutWriter &lw) const override
DomItem field(const DomItem &self, QStringView name) const override
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
static QmlUri fromDirectoryString(const QString &importStr)
static QmlUri fromUriString(const QString &importStr)
static ErrorGroups myParsingErrors()
const QList< Import > & imports() const &
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
QList< ModuleAutoExport > autoExports() const
void ensureInModuleIndex(const DomItem &self, const QString &uri) const
QMap< QString, QString > qmlFiles() const
QStringList classNames() const
void setAutoExports(const QList< ModuleAutoExport > &autoExport)
bool designerSupported() const
static std::shared_ptr< QmldirFile > fromPathAndCode(const QString &path, const QString &code)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
void ensureInModuleIndex(const DomItem &self) const
static constexpr qint32 Undefined
static constexpr qint32 Latest
void setCode(const QString &code, int lineno, bool qmlMode=true, CodeContinuation codeContinuation=CodeContinuation::Reset)
\inmodule QtCore \reentrant
\inmodule QtCore \reentrant
static QString anchoredPattern(const QString &expression)
iterator insert(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
int toInt(bool *ok=nullptr, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
QString & insert(qsizetype i, QChar c)
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
Path qmltypesFilePath(const QString &path)
Path jsFilePath(const QString &path)
Path qmlFileObjectPath(const QString &canonicalFilePath)
QCborValue pluginData(const QQmlDirParser::Plugin &pl, const QStringList &cNames)
static QString toString(const UiQualifiedId *qualifiedId, QChar delimiter=QLatin1Char('.'))
Combined button and popup list for selecting options.
DBusConnection const char DBusError * error
#define qCDebug(category,...)
GLsizei const GLfloat * v
[13]
GLint GLenum GLint components
GLsizei const GLchar *const * path
#define NewErrorGroup(name)
Members members(const Members &candidates, QTypeRevision maxMajorVersion, Postprocess &&process)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &errorSource, qsizetype errorPosition)
QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9))
[0]
\inmodule QtCore \reentrant
bool contains(const AT &t) const noexcept