33 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::uri), uri);
34 cont = cont && self.invokeVisitorOnField(visitor, Fields::version, version);
35 cont = cont && visitor(
PathEls::Field(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 &,
47 const DomItem &el) {
return el; },
48 ListOptions::Normal));
50 [](
const DomItem &mapExp) {
51 DomItem mapExpOw = mapExp.owner();
52 return mapExp.ownerAs<ModuleIndex>()->exportNames(mapExpOw);
54 QLatin1String(
"List<Exports>")));
56 cont = cont && visitor(
PathEls::Field(Fields::symbols), [&self]() {
58 return self.subMapItem(Map(
59 self.pathFromOwner().withField(Fields::symbols),
60 [basePath](
const DomItem &mapExp,
const QString &name) -> DomItem {
61 QList<Path> symb({ basePath.withKey(name) });
62 return mapExp.subReferencesItem(PathEls::Key(name), symb);
64 [](
const DomItem &mapExp) {
65 DomItem mapExpOw = mapExp.owner();
66 return mapExp.ownerAs<ModuleIndex>()->exportNames(mapExpOw);
68 QLatin1String(
"List<References>")));
70 cont = cont && visitor(
PathEls::Field(Fields::autoExports), [
this, &self]() {
71 return containingObject(self).field(Fields::autoExports);
84 QMap<
int, ModuleScope *> scopes;
86 QMutexLocker l2(o.mutex());
87 m_qmltypesFilesPaths += o.m_qmltypesFilesPaths;
88 m_qmldirPaths += o.m_qmldirPaths;
89 m_directoryPaths += o.m_directoryPaths;
90 scopes = o.m_moduleScope;
92 auto it = scopes.begin();
93 auto end = scopes.end();
118 bool cont = self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::uri), uri());
119 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::majorVersion),
121 cont = cont && visitor(
PathEls::Field(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;
133 map.ownerAs<ModuleIndex>()->ensureMinorVersion(minorVersion));
135 [
this](
const DomItem &) {
137 for (
int el : minorVersions())
139 res.insert(QString::number(el));
140 if (!minorVersions().isEmpty())
141 res.insert(QString());
144 QLatin1String(
"Map<List<Exports>>")));
146 cont = cont && visitor(
PathEls::Field(Fields::sources), [
this, &self]() {
147 return self.subReferencesItem(PathEls::Field(Fields::sources), sources());
149 cont = cont && self.invokeVisitorOnLazyField(visitor, Fields::autoExports, [
this, &self]() {
150 return autoExports(self);
170 RefCacheEntry cached = RefCacheEntry::forPath(self, selfPath);
171 QList<Path> cachedPaths;
172 switch (cached.cached) {
173 case RefCacheEntry::Cached::None:
174 case RefCacheEntry::Cached::First:
176 case RefCacheEntry::Cached::All:
177 cachedPaths += cached.canonicalPaths;
178 if (cachedPaths.isEmpty())
182 if (!cachedPaths.isEmpty()) {
183 bool outdated =
false;
184 for (
const Path &p : cachedPaths) {
185 DomItem newEl = env.path(p);
188 qWarning() <<
"referenceCache outdated, reference at " << selfPath
189 <<
" leads to invalid path " << p;
201 QList<Path> mySources = sources();
202 QSet<QString> knownAutoImportUris;
203 QList<ModuleAutoExport> knownExports;
204 for (
const Path &p : mySources) {
205 DomItem autoExports = self.path(p).field(Fields::autoExports);
206 for (
const DomItem &i : autoExports.values()) {
207 if (
const ModuleAutoExport *iPtr = i.as<ModuleAutoExport>()) {
208 if (!knownAutoImportUris.contains(iPtr->import.uri.toString())
209 || !knownExports.contains(*iPtr)) {
210 knownAutoImportUris.insert(iPtr->import.uri.toString());
211 knownExports.append(*iPtr);
213 cachedPaths.append(i.canonicalPath());
219 RefCacheEntry { RefCacheEntry::Cached::All, cachedPaths });
224 int minorVersion)
const
227 .withField(Fields::exports)
229 QList<Path> mySources = sources();
231 QList<DomItem> undef;
232 if (minorVersion < 0)
233 minorVersion =
std::numeric_limits<
int>::max();
234 int vNow = Version::Undefined;
235 for (
int i = 0; i < mySources.size(); ++i) {
237 DomItem exports = source.field(Fields::exports).key(name);
238 int nExports = exports.indexes();
241 for (
int j = 0; j < nExports; ++j) {
242 DomItem exportItem = exports.index(j);
245 Version const *versionPtr = exportItem.field(Fields::version).as<
Version>();
246 if (versionPtr ==
nullptr || !versionPtr
->isValid()) {
247 undef.append(exportItem);
251 .error(tr(
"Module %1 (unversioned) has versioned entries "
257 || versionPtr->majorVersion == Version::Undefined)
258 && versionPtr->minorVersion >= vNow
259 && versionPtr->minorVersion <= minorVersion) {
260 if (versionPtr->minorVersion > vNow)
262 res.append(exportItem);
263 vNow = versionPtr->minorVersion;
268 if (!undef.isEmpty()) {
269 if (!res.isEmpty()) {
271 .error(tr(
"Module %1 (major version %2) has versioned and "
272 "unversioned entries for '%3'")
273 .arg(uri(), QString::number(majorVersion()), name)
)
286 QMutexLocker l(mutex());
287 res += m_qmltypesFilesPaths;
288 if (!m_qmldirPaths.isEmpty())
289 res += m_qmldirPaths.first();
290 else if (!m_directoryPaths.isEmpty())
291 res += m_directoryPaths.first();
297 if (minorVersion < 0)
298 minorVersion = Version::Latest;
300 QMutexLocker l(mutex());
301 auto it = m_moduleScope.constFind(minorVersion);
302 if (it != m_moduleScope.cend())
305 ModuleScope *res =
nullptr;
306 ModuleScope *newScope =
new ModuleScope(m_uri, Version(majorVersion(), minorVersion));
307 auto cleanup = qScopeGuard([&newScope] {
delete newScope; });
309 QMutexLocker l(mutex());
310 auto it = m_moduleScope.constFind(minorVersion);
311 if (it != m_moduleScope.cend()) {
316 m_moduleScope.insert(minorVersion, res);
325 QList<Path> qmltypesPaths;
326 QMap<
int, ModuleScope *> scopes;
328 QMutexLocker l2(o->mutex());
329 qmltypesPaths = o->m_qmltypesFilesPaths;
330 scopes = o->m_moduleScope;
333 QMutexLocker l(mutex());
334 for (
const Path &qttPath : qmltypesPaths) {
335 if (!m_qmltypesFilesPaths.contains((qttPath)))
336 m_qmltypesFilesPaths.append(qttPath);
339 auto it = scopes.begin();
340 auto end = scopes.end();
352 std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>();
353 QStringList subPathComponents = uri().split(u'.');
354 QString subPath = subPathComponents.join(u'/');
356 QString subPathV = subPath + QChar::fromLatin1(
'.') + QString::number(majorVersion())
357 + QLatin1String(
"/qmldir");
360 qCDebug(QQmlJSDomImporting)
361 <<
"ModuleIndex::qmldirsToLoad: Searching versioned module" << subPath
363 for (
const QString &path : envPtr->loadPaths()) {
365 QFileInfo fInfo(dir.filePath(subPathV));
366 if (fInfo.isFile()) {
367 qCDebug(QQmlJSDomImporting)
368 <<
"Found versioned module in " << fInfo.canonicalFilePath();
369 logicalPath = subPathV;
370 dirPath = fInfo.canonicalFilePath();
375 if (dirPath.isEmpty()) {
376 qCDebug(QQmlJSDomImporting) <<
"ModuleIndex::qmldirsToLoad: Searching unversioned module"
377 << subPath <<
"in" << envPtr->loadPaths().join(u", ");
378 for (
const QString &path : envPtr->loadPaths()) {
380 QFileInfo fInfo(dir.filePath(subPath + QLatin1String(
"/qmldir")));
381 if (fInfo.isFile()) {
382 qCDebug(QQmlJSDomImporting)
383 <<
"Found unversioned module in " << fInfo.canonicalFilePath();
384 logicalPath = subPath + QLatin1String(
"/qmldir");
385 dirPath = fInfo.canonicalFilePath();
390 if (!dirPath.isEmpty()) {
391 QMutexLocker l(mutex());
392 m_qmldirPaths = QList<Path>({ Paths::qmldirFilePath(dirPath) });
393 }
else if (uri() != u"QML") {
394 const QString loadPaths = envPtr->loadPaths().join(u", "_s);
395 qCDebug(QQmlJSDomImporting) <<
"ModuleIndex::qmldirsToLoad: qmldir at"
396 << (uri() + u"/qmldir"_s) <<
" was not found in " << loadPaths;
399 .warning(tr(
"Failed to find main qmldir file for %1 %2 in %3.")
400 .arg(uri(), QString::number(majorVersion()), loadPaths)
)
403 return qmldirPaths();
static bool addForPath(const DomItem &el, const Path &canonicalPath, const RefCacheEntry &entry, AddOption addOption=AddOption::KeepExisting)