33 cont = cont && self.dvValueField(visitor, Fields::uri, uri);
34 cont = cont && self.dvWrapField(visitor, Fields::version, version);
35 cont = cont && self.dvItemField(visitor, Fields::exports, [
this, &self]() {
36 int minorVersion = version.minorVersion;
37 return self.subMapItem(Map(
38 self.pathFromOwner().withField(Fields::exports),
39 [minorVersion](
const DomItem &mapExp,
const QString &name) -> DomItem {
40 DomItem mapExpOw = mapExp.owner();
41 QList<DomItem> exports =
42 mapExp.ownerAs<ModuleIndex>()->exportsWithNameAndMinorVersion(
43 mapExpOw, name, minorVersion);
44 return mapExp.subListItem(List::fromQList<DomItem>(
45 mapExp.pathFromOwner().withKey(name), exports,
46 [](
const DomItem &,
const PathEls::PathComponent &,
const DomItem &el) {
49 ListOptions::Normal));
51 [](
const DomItem &mapExp) {
52 DomItem mapExpOw = mapExp.owner();
53 return mapExp.ownerAs<ModuleIndex>()->exportNames(mapExpOw);
55 QLatin1String(
"List<Exports>")));
57 cont = cont && self.dvItemField(visitor, Fields::symbols, [&self]() {
59 return self.subMapItem(Map(
60 self.pathFromOwner().withField(Fields::symbols),
61 [basePath](
const DomItem &mapExp,
const QString &name) -> DomItem {
62 QList<Path> symb({ basePath.withKey(name) });
63 return mapExp.subReferencesItem(PathEls::Key(name), symb);
65 [](
const DomItem &mapExp) {
66 DomItem mapExpOw = mapExp.owner();
67 return mapExp.ownerAs<ModuleIndex>()->exportNames(mapExpOw);
69 QLatin1String(
"List<References>")));
71 cont = cont && self.dvItemField(visitor, Fields::autoExports, [
this, &self]() {
72 return containingObject(self).field(Fields::autoExports);
85 QMap<
int, ModuleScope *> scopes;
87 QMutexLocker l2(o.mutex());
88 m_qmltypesFilesPaths += o.m_qmltypesFilesPaths;
89 m_qmldirPaths += o.m_qmldirPaths;
90 m_directoryPaths += o.m_directoryPaths;
91 scopes = o.m_moduleScope;
93 auto it = scopes.begin();
94 auto end = scopes.end();
119 bool cont = self.dvValueField(visitor, Fields::uri, uri());
120 cont = cont && self.dvValueField(visitor, Fields::majorVersion,
majorVersion());
121 cont = cont && self.dvItemField(visitor, Fields::moduleScope, [
this, &self]() {
122 return self.subMapItem(Map(
123 pathFromOwner().withField(Fields::moduleScope),
124 [](
const DomItem &map,
const QString &minorVersionStr) {
126 int minorVersion = minorVersionStr.toInt(&ok);
127 if (minorVersionStr.isEmpty()
128 || minorVersionStr.compare(u"Latest", Qt::CaseInsensitive) == 0)
129 minorVersion = Version::Latest;
132 return map.copy(map.ownerAs<ModuleIndex>()->ensureMinorVersion(minorVersion));
134 [
this](
const DomItem &) {
136 for (
int el : minorVersions())
138 res.insert(QString::number(el));
139 if (!minorVersions().isEmpty())
140 res.insert(QString());
143 QLatin1String(
"Map<List<Exports>>")));
145 cont = cont && self.dvItemField(visitor, Fields::sources, [
this, &self]() {
146 return self.subReferencesItem(PathEls::Field(Fields::sources), sources());
148 cont = cont && self.dvValueLazyField(visitor, Fields::autoExports, [
this, &self]() {
149 return autoExports(self);
169 RefCacheEntry cached = RefCacheEntry::forPath(self, selfPath);
170 QList<Path> cachedPaths;
171 switch (cached.cached) {
172 case RefCacheEntry::Cached::None:
173 case RefCacheEntry::Cached::First:
175 case RefCacheEntry::Cached::All:
176 cachedPaths += cached.canonicalPaths;
177 if (cachedPaths.isEmpty())
181 if (!cachedPaths.isEmpty()) {
182 bool outdated =
false;
183 for (
const Path &p : cachedPaths) {
184 DomItem newEl = env.path(p);
187 qWarning() <<
"referenceCache outdated, reference at " << selfPath
188 <<
" leads to invalid path " << p;
200 QList<Path> mySources = sources();
201 QSet<QString> knownAutoImportUris;
202 QList<ModuleAutoExport> knownExports;
203 for (
const Path &p : mySources) {
204 DomItem autoExports = self.path(p).field(Fields::autoExports);
205 for (
const DomItem &i : autoExports.values()) {
206 if (
const ModuleAutoExport *iPtr = i.as<ModuleAutoExport>()) {
207 if (!knownAutoImportUris.contains(iPtr->import.uri.toString())
208 || !knownExports.contains(*iPtr)) {
209 knownAutoImportUris.insert(iPtr->import.uri.toString());
210 knownExports.append(*iPtr);
212 cachedPaths.append(i.canonicalPath());
217 RefCacheEntry::addForPath(self, selfPath,
218 RefCacheEntry { RefCacheEntry::Cached::All, cachedPaths });
223 int minorVersion)
const
225 Path myPath = Paths::moduleScopePath(uri(), Version(majorVersion(), minorVersion))
226 .withField(Fields::exports)
228 QList<Path> mySources = sources();
230 QList<DomItem> undef;
231 if (minorVersion < 0)
232 minorVersion =
std::numeric_limits<
int>::max();
233 int vNow = Version::Undefined;
234 for (
int i = 0; i < mySources.size(); ++i) {
236 DomItem exports = source.field(Fields::exports).key(name);
237 int nExports = exports.indexes();
240 for (
int j = 0; j < nExports; ++j) {
241 DomItem exportItem = exports.index(j);
244 Version const *versionPtr = exportItem.field(Fields::version).as<
Version>();
245 if (versionPtr ==
nullptr || !versionPtr
->isValid()) {
246 undef.append(exportItem);
248 if (majorVersion() < 0)
249 self.addError(std::move(myVersioningErrors()
250 .error(tr(
"Module %1 (unversioned) has versioned entries "
253 source.canonicalPath().toString()))
256 || versionPtr->majorVersion == Version::Undefined)
257 && versionPtr->minorVersion >= vNow
258 && versionPtr->minorVersion <= minorVersion) {
259 if (versionPtr->minorVersion > vNow)
261 res.append(exportItem);
262 vNow = versionPtr->minorVersion;
267 if (!undef.isEmpty()) {
268 if (!res.isEmpty()) {
269 self.addError(std::move(myVersioningErrors()
270 .error(tr(
"Module %1 (major version %2) has versioned and "
271 "unversioned entries for '%3'")
272 .arg(uri(), QString::number(majorVersion()), name))
285 QMutexLocker l(mutex());
286 res += m_qmltypesFilesPaths;
287 if (!m_qmldirPaths.isEmpty())
288 res += m_qmldirPaths.first();
289 else if (!m_directoryPaths.isEmpty())
290 res += m_directoryPaths.first();
296 if (minorVersion < 0)
297 minorVersion = Version::Latest;
299 QMutexLocker l(mutex());
300 auto it = m_moduleScope.constFind(minorVersion);
301 if (it != m_moduleScope.cend())
304 ModuleScope *res =
nullptr;
305 ModuleScope *newScope =
new ModuleScope(m_uri, Version(majorVersion(), minorVersion));
306 auto cleanup = qScopeGuard([&newScope] {
delete newScope; });
308 QMutexLocker l(mutex());
309 auto it = m_moduleScope.constFind(minorVersion);
310 if (it != m_moduleScope.cend()) {
315 m_moduleScope.insert(minorVersion, res);
324 QList<Path> qmltypesPaths;
325 QMap<
int, ModuleScope *> scopes;
327 QMutexLocker l2(o->mutex());
328 qmltypesPaths = o->m_qmltypesFilesPaths;
329 scopes = o->m_moduleScope;
332 QMutexLocker l(mutex());
333 for (
const Path &qttPath : qmltypesPaths) {
334 if (!m_qmltypesFilesPaths.contains((qttPath)))
335 m_qmltypesFilesPaths.append(qttPath);
338 auto it = scopes.begin();
339 auto end = scopes.end();
351 std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>();
352 QStringList subPathComponents = uri().split(u'.');
353 QString subPath = subPathComponents.join(u'/');
355 QString subPathV = subPath + QChar::fromLatin1(
'.') + QString::number(majorVersion())
356 + QLatin1String(
"/qmldir");
359 qCDebug(QQmlJSDomImporting)
360 <<
"ModuleIndex::qmldirsToLoad: Searching versioned module" << subPath
361 << majorVersion() <<
"in" << envPtr->loadPaths().join(u", ");
362 for (
const QString &path : envPtr->loadPaths()) {
364 QFileInfo fInfo(dir.filePath(subPathV));
365 if (fInfo.isFile()) {
366 qCDebug(QQmlJSDomImporting)
367 <<
"Found versioned module in " << fInfo.canonicalFilePath();
368 logicalPath = subPathV;
369 dirPath = fInfo.canonicalFilePath();
374 if (dirPath.isEmpty()) {
375 qCDebug(QQmlJSDomImporting) <<
"ModuleIndex::qmldirsToLoad: Searching unversioned module"
376 << subPath <<
"in" << envPtr->loadPaths().join(u", ");
377 for (
const QString &path : envPtr->loadPaths()) {
379 QFileInfo fInfo(dir.filePath(subPath + QLatin1String(
"/qmldir")));
380 if (fInfo.isFile()) {
381 qCDebug(QQmlJSDomImporting)
382 <<
"Found unversioned module in " << fInfo.canonicalFilePath();
383 logicalPath = subPath + QLatin1String(
"/qmldir");
384 dirPath = fInfo.canonicalFilePath();
389 if (!dirPath.isEmpty()) {
390 QMutexLocker l(mutex());
391 m_qmldirPaths = QList<Path>({ Paths::qmldirFilePath(dirPath) });
392 }
else if (uri() != u"QML") {
393 const QString loadPaths = envPtr->loadPaths().join(u", "_s);
394 qCDebug(QQmlJSDomImporting) <<
"ModuleIndex::qmldirsToLoad: qmldir at"
395 << (uri() + u"/qmldir"_s) <<
" was not found in " << loadPaths;
398 .warning(tr(
"Failed to find main qmldir file for %1 %2 in %3.")
399 .arg(uri(), QString::number(majorVersion()), loadPaths))
402 return qmldirPaths();