14#include <QtQml/private/qqmljslexer_p.h>
15#include <QtQml/private/qqmljsparser_p.h>
16#include <QtQml/private/qqmljsengine_p.h>
17#include <QtQml/private/qqmljsastvisitor_p.h>
18#include <QtQml/private/qqmljsast_p.h>
20#include <QtCore/QBasicMutex>
21#include <QtCore/QCborArray>
22#include <QtCore/QDebug>
24#include <QtCore/QFile>
25#include <QtCore/QFileInfo>
26#include <QtCore/QPair>
27#include <QtCore/QRegularExpression>
28#include <QtCore/QScopeGuard>
30# include <QtCore/QThread>
76 return knownFields[
f];
79 auto objs = m_extraOwningItems;
81 auto endO = objs.cend();
83 cont = cont && self.dvItemField(visitor, toField(itO.key()), [&self, &itO]() {
84 return std::visit([&self](auto &&el) { return self.copy(el); }, *itO);
91void DomTop::clearExtraOwningItems()
94 m_extraOwningItems.clear();
130 const auto next = [] {
131 Q_CONSTINIT
static std::atomic<int>
counter(0);
132 return counter.fetch_add(1, std::memory_order_relaxed) + 1;
137 return std::make_shared<DomUniverse>(
143 auto res = std::make_shared<DomUniverse>(universeName,
options);
156 cont = cont && self.dvValueField(visitor, Fields::name,
name());
157 cont = cont && self.dvValueField(visitor, Fields::options,
int(
options()));
158 cont = cont && self.dvItemField(visitor, Fields::globalScopeWithName, [
this, &self]() {
159 return self.subMapItem(
Map(
164 cont = cont && self.dvItemField(visitor, Fields::qmlDirectoryWithPath, [
this, &self]() {
165 return self.subMapItem(
Map(
170 cont = cont && self.dvItemField(visitor, Fields::qmldirFileWithPath, [
this, &self]() {
171 return self.subMapItem(
Map(
176 cont = cont && self.dvItemField(visitor, Fields::qmlFileWithPath, [
this, &self]() {
177 return self.subMapItem(
Map(
182 cont = cont && self.dvItemField(visitor, Fields::jsFileWithPath, [
this, &self]() {
183 return self.subMapItem(
Map(
188 cont = cont &&
self.dvItemField(visitor, Fields::jsFileWithPath, [
this, &self]() {
194 cont = cont &&
self.dvItemField(visitor, Fields::queue, [
this, &self]() {
199 if (
i >= 0 &&
i <
q.size())
200 return list.subDataItem(PathEls::Index(
i),
q.at(
i).toCbor(),
214 auto m =
r.match(m_name);
217 newName =
QStringLiteral(u
"%1Copy%2").arg(m_name).arg(
m.captured(1).toInt() + 1);
220 auto res = std::make_shared<DomUniverse>(newName);
229 }
else if (canonicalFilePath.
endsWith(u
".qmltypes")) {
235 }
else if (
QFileInfo(canonicalFilePath).isDir()) {
240 "Could not detect type of file %1")
241 .
arg(canonicalFilePath))
248 LoadOptions loadOptions, std::optional<DomType>
fileType)
264 .
error(
tr(
"Ignoring request to load file %1 of unexpected type %2, "
265 "calling callback immediately")
268 Q_ASSERT(
false &&
"loading non supported file type");
281 std::shared_ptr<ExternalItemPair<T>> oldValue;
282 std::shared_ptr<ExternalItemPair<T>> newValue;
290 QString oldCode = oldValue->current->code();
291 QString newCode = newItem->code();
292 if (!oldCode.
isNull() && !newCode.
isNull() && oldCode == newCode) {
294 if (newValue->current->lastDataUpdateAt() < newItem->lastDataUpdateAt())
295 newValue->current->refreshedDataAt(newItem->lastDataUpdateAt());
296 }
else if (oldValue->current->lastDataUpdateAt() > newItem->lastDataUpdateAt()) {
300 newValue = oldValue->
makeCopy(oldValueObj);
301 newValue->current = newItem;
302 newValue->currentExposedAt =
now;
303 if (newItem->isValid()) {
304 newValue->valid = newItem;
305 newValue->validExposedAt =
now;
310 newValue = std::make_shared<ExternalItemPair<T>>(
311 (newItem->isValid() ? newItem : std::shared_ptr<T>()), newItem,
now,
now);
324 if (m_queue.isEmpty())
326 t = m_queue.dequeue();
328 shared_ptr<DomUniverse> topPtr =
t.requestingUniverse.lock();
332 .
error(
tr(
"Ignoring callback for loading of %1: universe is not valid anymore")
341 bool skipParse =
false;
349 auto getValue = [&
t,
this, &
canonicalPath]() -> std::shared_ptr<ExternalItemPairBase> {
371 auto value = getValue();
376 ||
path.lastModified() <
value->currentItem()->lastDataUpdateAt())) {
402 if (
auto value = getValue()) {
404 if (
value &&
value->currentItem() && !oldCode.
isNull() && oldCode == code) {
407 if (
value->currentItem()->lastDataUpdateAt() < contentDate)
408 value->currentItem()->refreshedDataAt(contentDate);
415 auto qmlFile = std::make_shared<QmlFile>(
canonicalPath, code, contentDate);
416 std::shared_ptr<DomEnvironment> envPtr;
417 if (
auto ptr =
t.file.environment().lock())
418 envPtr = std::move(
ptr);
420 envPtr = std::make_shared<DomEnvironment>(
422 envPtr->addQmlFile(qmlFile);
424 if (qmlFile->isValid()) {
431 errs +=
m.toString();
438 auto change = updateEntry<QmlFile>(univ, qmlFile, m_qmlFileWithPath,
mutex());
439 oldValue = univ.
copy(change.first);
440 newValue = univ.
copy(change.second);
442 auto qmltypesFile = std::make_shared<QmltypesFile>(
446 auto change = updateEntry<QmltypesFile>(univ, qmltypesFile, m_qmltypesFileWithPath,
448 oldValue = univ.
copy(change.first);
449 newValue = univ.
copy(change.second);
451 shared_ptr<QmldirFile> qmldirFile =
454 updateEntry<QmldirFile>(univ, qmldirFile, m_qmldirFileWithPath,
mutex());
455 oldValue = univ.
copy(change.first);
456 newValue = univ.
copy(change.second);
458 auto qmlDirectory = std::make_shared<QmlDirectory>(
460 auto change = updateEntry<QmlDirectory>(univ, qmlDirectory, m_qmlDirectoryWithPath,
462 oldValue = univ.
copy(change.first);
463 newValue = univ.
copy(change.second);
484 t.callback(
p, oldValue, newValue);
487 Q_ASSERT(
false &&
"Unhandled kind in queue");
494 auto toDelete = [
path](
auto it) {
496 return p.startsWith(
path) && (
p.size() ==
path.size() ||
p.at(
path.size()) == u
'/');
498 m_qmlDirectoryWithPath.removeIf(toDelete);
499 m_qmldirFileWithPath.removeIf(toDelete);
500 m_qmlFileWithPath.removeIf(toDelete);
501 m_jsFileWithPath.removeIf(toDelete);
502 m_qmltypesFileWithPath.removeIf(toDelete);
507 auto res = std::make_shared<LoadInfo>(*
this);
510 u
"This is a copy of a LoadInfo still in progress, artificially ending it, if you "
511 u
"use this you will *not* resume loading"));
514 sink(u
"Copying an in progress LoadInfo, which is most likely an error (");
522 res->m_inProgress.clear();
523 res->m_endCallbacks.clear();
536 cont = cont && self.dvValueField(visitor, Fields::status,
int(
status()));
537 cont = cont && self.dvValueField(visitor, Fields::nLoaded,
nLoaded());
539 && self.dvValueField(visitor, Fields::elementCanonicalPath,
541 cont = cont && self.dvValueField(visitor, Fields::nNotdone,
nNotDone());
542 cont = cont && self.dvValueField(visitor, Fields::nCallbacks,
nCallbacks());
558 m_endCallbacks.append(callback);
573 bool depValid =
false;
583 if (!m_toDo.isEmpty()) {
584 dep = m_toDo.dequeue();
585 m_inProgress.append(dep);
597 doAddDependencies(self);
602 if (m_toDo.isEmpty() && m_inProgress.isEmpty())
615 self.loadModuleDependency(
618 finishedLoadingDep(self, dep);
620 self.errorHandler());
623 DomItem env = self.environment();
628 finishedLoadingDep(self, dep);
631 self.errorHandler());
633 Q_ASSERT(
false &&
"missing environment");
635 Q_ASSERT(
false &&
"dependency without uri and filePath");
639 tr(
"advanceLoad called but found no work, which should never happen")));
645 "advanceLoad called after work should have been done, which should never happen")));
652 bool didRemove =
false;
653 bool unexpectedState =
false;
657 didRemove = m_inProgress.removeOne(
d);
662 unexpectedState =
true;
667 if (m_toDo.isEmpty() && m_inProgress.isEmpty()) {
676 sink(u
"LoadInfo::finishedLoadingDep did not find its dependency in those inProgress "
682 &&
"LoadInfo::finishedLoadingDep did not find its dependency in those inProgress");
684 if (unexpectedState) {
686 sink(u
"LoadInfo::finishedLoadingDep found an unexpected state (");
690 Q_ASSERT(
false &&
"LoadInfo::finishedLoadingDep did find an unexpected state");
699 bool unexpectedState =
false;
703 endCallbacks = m_endCallbacks;
704 m_endCallbacks.clear();
706 Q_ASSERT(!unexpectedState &&
"LoadInfo::execEnd found an unexpected state");
712 bool unexpectedState2 =
false;
717 otherCallbacks = m_endCallbacks;
718 m_endCallbacks.clear();
720 Q_ASSERT(!unexpectedState2 &&
"LoadInfo::execEnd found an unexpected state");
721 for (
auto const &
cb : otherCallbacks) {
726 for (
auto const &
cb : endCallbacks) {
733void LoadInfo::doAddDependencies(
DomItem &self)
737 .
error(
tr(
"Uninitialized LoadInfo %1").
arg(self.canonicalPath().toString()))
745 DomItem currentFile =
el.field(Fields::currentItem);
746 DomItem currentImports = currentFile.field(Fields::imports);
747 QString currentFilePath = currentFile.canonicalFilePath();
748 int iEnd = currentImports.indexes();
749 for (
int i = 0;
i < iEnd; ++
i) {
750 DomItem import = currentImports.index(
i);
751 if (
const Import *importPtr =
import.as<Import>()) {
752 if (importPtr->uri.isDirectory()) {
753 QString path = importPtr->uri.absoluteLocalPath(currentFilePath);
754 if (!
path.isEmpty()) {
760 tr(
"Ignoring dependencies for non resolved path import %1")
761 .
arg(importPtr->uri.toString())));
765 Dependency { importPtr->uri.moduleUri(), importPtr->version,
770 DomItem currentQmltypesFiles = currentFile.field(Fields::qmltypesFiles);
771 int qEnd = currentQmltypesFiles.indexes();
772 for (
int i = 0;
i < qEnd; ++
i) {
773 DomItem qmltypesRef = currentQmltypesFiles.index(
i);
774 if (
const Reference *
ref = qmltypesRef.as<Reference>()) {
782 DomItem currentQmlFiles = currentFile.field(Fields::qmlFiles);
784 return els.visitIndexes([
this, &self](
DomItem &
el) {
785 if (
const Reference *
ref =
el.as<Reference>()) {
786 Path canonicalPath = ref->referredObjectPath[2];
787 if (canonicalPath && !canonicalPath.headName().isEmpty())
789 Dependency { QString(), Version(), canonicalPath.headName(),
795 }
else if (shared_ptr<ModuleIndex> elPtr =
el.ownerAs<ModuleIndex>()) {
796 const auto qmldirs = elPtr->qmldirsToLoad(
el);
797 for (
const Path &qmldirPath : qmldirs) {
806 for (
const Path &
p : qmldirs) {
808 if (std::shared_ptr<QmldirFile> qmldirFilePtr = qmldir.ownerAs<QmldirFile>()) {
809 qmldirFilePtr->ensureInModuleIndex(qmldir, uri);
815 tr(
"Ignoring dependencies for empty (invalid) type %1")
821 elementCanonicalPath().
toString())));
825void LoadInfo::addDependency(
DomItem &self,
const Dependency &dep)
827 bool unexpectedState =
false;
830 unexpectedState = m_status != Status::Starting;
833 Q_ASSERT(!unexpectedState &&
"LoadInfo::addDependency found an unexpected state");
835 env.ownerAs<
DomEnvironment>()->addWorkForLoadInfo(elementCanonicalPath());
852 std::shared_ptr<DomEnvironment> ePtr = self.ownerAs<
DomEnvironment>();
853 std::weak_ptr<DomEnvironment> selfPtr = ePtr;
854 std::shared_ptr<DomEnvironment> basePtr = ePtr->
base();
855 return [selfPtr, basePtr,
map, lookupF, loadCallback, allDirectDepsCallback,
857 shared_ptr<DomEnvironment> envPtr = selfPtr.lock();
861 shared_ptr<ExternalItemInfo<T>> oldValue;
862 shared_ptr<ExternalItemInfo<T>> newValue;
863 shared_ptr<T> newItemPtr;
864 if (envPtr->options() & DomEnvironment::Option::KeepValid)
865 newItemPtr = newItem.field(Fields::validItem).ownerAs<T>();
867 newItemPtr = newItem.field(Fields::currentItem).ownerAs<T>();
868 Q_ASSERT(newItemPtr &&
"callbackForQmlFile reached without current qmlFile");
871 oldValue = ((*envPtr).*
map).
value(newItem.canonicalFilePath());
880 EnvLookup::BaseOnly);
884 newValue = oldValue->
makeCopy(oldValueObj);
885 if (newValue->current != newItemPtr) {
886 newValue->current = newItemPtr;
890 newValue = std::make_shared<ExternalItemInfo<T>>(
895 auto value = ((*envPtr).*
map).
value(newItem.canonicalFilePath());
897 oldValue = newValue =
value;
899 ((*envPtr).*
map).
insert(newItem.canonicalFilePath(), newValue);
905 auto depLoad =
qScopeGuard([
p, &env, envPtr, allDirectDepsCallback, endCallback] {
906 if (!(envPtr->options() & DomEnvironment::Option::NoDependencies)) {
907 auto loadInfo = std::make_shared<LoadInfo>(p);
910 DomItem loadInfoObj = env.copy(loadInfo);
911 loadInfo->addEndCallback(loadInfoObj, allDirectDepsCallback);
912 envPtr->addLoadInfo(env, loadInfo);
915 envPtr->addAllLoadedCallback(env,
917 DomItem el = env.path(p);
918 endCallback(p, el, el);
924 loadCallback(
p, oldValueObj, newValueObj);
926 if ((envPtr->options() & DomEnvironment::Option::NoDependencies)
927 && allDirectDepsCallback) {
930 env.
addError(DomEnvironment::myErrors().warning(
931 QLatin1String(
"calling allDirectDepsCallback immediately for load with "
932 "NoDependencies of %1")
933 .
arg(newItem.canonicalFilePath())));
934 allDirectDepsCallback(
p, oldValueObj, newValueObj);
950Path DomEnvironment::canonicalPath()
const
952 return Path::Root(u
"env");
958 cont = cont && DomTop::iterateDirectSubpaths(self, visitor);
960 cont = cont && self.dvItemField(visitor, Fields::universe, [
this]() {
return universe(); });
961 cont = cont && self.dvValueField(visitor, Fields::options,
int(options()));
962 cont = cont && self.dvItemField(visitor, Fields::base, [
this]() {
return base(); });
964 && self.dvValueLazyField(visitor, Fields::loadPaths, [
this]() {
return loadPaths(); });
965 cont = cont && self.dvValueField(visitor, Fields::globalScopeName, globalScopeName());
966 cont = cont && self.dvItemField(visitor, Fields::globalScopeWithName, [
this, &self]() {
967 return self.subMapItem(
Map(
968 Path::Field(Fields::globalScopeWithName),
970 return map.copy(globalScopeWithName(self,
key));
972 [&self,
this](
DomItem &) {
return globalScopeNames(self); },
975 cont = cont && self.dvItemField(visitor, Fields::qmlDirectoryWithPath, [
this, &self]() {
976 return self.subMapItem(
Map(
977 Path::Field(Fields::qmlDirectoryWithPath),
979 return map.copy(qmlDirectoryWithPath(self,
key));
981 [&self,
this](
DomItem &) {
return qmlDirectoryPaths(self); },
984 cont = cont && self.dvItemField(visitor, Fields::qmldirFileWithPath, [
this, &self]() {
985 return self.subMapItem(
Map(
986 Path::Field(Fields::qmldirFileWithPath),
988 return map.copy(qmldirFileWithPath(self,
key));
990 [&self,
this](
DomItem &) {
return qmldirFilePaths(self); },
993 cont = cont && self.dvItemField(visitor, Fields::qmldirWithPath, [
this, &self]() {
994 return self.subMapItem(
Map(
995 Path::Field(Fields::qmldirWithPath),
997 return map.copy(qmlDirWithPath(self,
key));
1001 cont = cont && self.dvItemField(visitor, Fields::qmlFileWithPath, [
this, &self]() {
1002 return self.subMapItem(
Map(
1003 Path::Field(Fields::qmlFileWithPath),
1005 return map.copy(qmlFileWithPath(self,
key));
1009 cont = cont && self.dvItemField(visitor, Fields::jsFileWithPath, [
this, &self]() {
1010 return self.subMapItem(
Map(
1011 Path::Field(Fields::jsFileWithPath),
1014 return map.copy(jsFileWithPath(mapOw,
key));
1018 return jsFilePaths(mapOw);
1022 cont = cont && self.dvItemField(visitor, Fields::qmltypesFileWithPath, [
this, &self]() {
1023 return self.subMapItem(
Map(
1024 Path::Field(Fields::qmltypesFileWithPath),
1027 return map.copy(qmltypesFileWithPath(mapOw,
key));
1031 return qmltypesFilePaths(mapOw);
1035 cont = cont && self.dvItemField(visitor, Fields::moduleIndexWithUri, [
this, &self]() {
1036 return self.subMapItem(
Map(
1037 Path::Field(Fields::moduleIndexWithUri),
1039 return map.subMapItem(
Map(
1043 int i = subKey.toInt(&ok);
1045 if (subKey.isEmpty())
1046 i = Version::Undefined;
1047 else if (subKey.compare(u
"Latest", Qt::CaseInsensitive) == 0)
1048 i = Version::Latest;
1053 std::shared_ptr<ModuleIndex> mIndex =
1054 moduleIndexWithUri(subMapOw,
key,
i);
1055 return submap.
copy(mIndex);
1061 moduleIndexMajorVersions(subMapOw,
key, EnvLookup::Normal))
1062 if (mVersion == Version::Undefined)
1074 return moduleIndexUris(mapOw);
1078 bool loadedLoadInfo =
false;
1081 int nAllLoadedCallbacks;
1082 auto ensureInfo = [&]() {
1083 if (!loadedLoadInfo) {
1085 loadedLoadInfo =
true;
1086 loadsWithWork = m_loadsWithWork;
1087 inProgress = m_inProgress;
1088 nAllLoadedCallbacks = m_allLoadedCallback.
size();
1092 && self.dvItemField(
1093 visitor, Fields::loadsWithWork, [&ensureInfo, &self, &loadsWithWork]() {
1095 return self.subListItem(List(
1096 Path::Field(Fields::loadsWithWork),
1098 if (
i >= 0 &&
i < loadsWithWork.
size())
1099 return list.subDataItem(PathEls::Index(
i),
1100 loadsWithWork.
at(
i).toString());
1110 &&
self.dvItemField(visitor, Fields::inProgress, [&self, &ensureInfo, &inProgress]() {
1113 Path::Field(Fields::inProgress),
1115 if (
i >= 0 &&
i < inProgress.
size())
1116 return list.subDataItem(PathEls::Index(
i),
1117 inProgress.
at(
i).toString());
1124 cont = cont &&
self.dvItemField(visitor, Fields::loadInfo, [&self,
this]() {
1126 Path::Field(Fields::loadInfo),
1128 bool hasErrors =
false;
1131 case ErrorLevel::Debug:
1132 case ErrorLevel::Info:
1134 case ErrorLevel::Warning:
1135 case ErrorLevel::Error:
1136 case ErrorLevel::Fatal:
1142 return map.copy(loadInfo(
p));
1147 const auto infoPaths = loadInfoPaths();
1148 for (
const Path &
p : infoPaths)
1154 cont = cont &&
self.dvWrapField(visitor, Fields::imports, m_implicitImports);
1156 &&
self.dvValueLazyField(visitor, Fields::nAllLoadedCallbacks,
1157 [&nAllLoadedCallbacks, &ensureInfo]() {
1159 return nAllLoadedCallbacks;
1166 return DomTop::field(self,
name);
1169std::shared_ptr<DomEnvironment> DomEnvironment::makeCopy(
DomItem &self)
const
1171 return std::static_pointer_cast<DomEnvironment>(doCopy(self));
1174std::shared_ptr<OwningItem> DomEnvironment::doCopy(
DomItem &)
const
1176 shared_ptr<DomEnvironment>
res;
1178 res = std::make_shared<DomEnvironment>(m_base, m_loadPaths,
m_options);
1180 res = std::make_shared<DomEnvironment>(
1187 LoadOptions loadOptions, std::optional<DomType>
fileType,
1190 if (
file.canonicalPath().isEmpty()) {
1191 if (!
file.content() ||
file.content()->data.isNull()) {
1194 .error(
tr(
"Non existing path to load: '%1'").
arg(
file.logicalPath()))
1197 loadCallback(
Path(), DomItem::empty, DomItem::empty);
1198 if (directDepsCallback)
1199 directDepsCallback(
Path(), DomItem::empty, DomItem::empty);
1202 endCallback(
Path(), DomItem::empty, DomItem::empty);
1207 file.canonicalPath() =
file.logicalPath();
1211 shared_ptr<ExternalItemInfoBase> oldValue, newValue;
1215 case DomType::QmlDirectory: {
1218 auto it = m_qmlDirectoryWithPath.
find(
file.canonicalPath());
1219 if (
it != m_qmlDirectoryWithPath.
end())
1220 oldValue = newValue = *
it;
1222 if (!newValue && (options() & Option::NoReload) && m_base) {
1223 if (
auto v = m_base->qmlDirectoryWithPath(self,
file.canonicalPath(),
1224 EnvLookup::Normal)) {
1227 auto newV = std::make_shared<ExternalItemInfo<QmlDirectory>>(
1228 v->current,
now,
v->revision(),
v->lastDataUpdateAt());
1231 auto it = m_qmlDirectoryWithPath.
find(
file.canonicalPath());
1232 if (
it != m_qmlDirectoryWithPath.
end())
1233 oldValue = newValue = *
it;
1235 m_qmlDirectoryWithPath.
insert(
file.canonicalPath(), newV);
1239 self.universe().loadFile(
1241 callbackForQmlDirectory(self, loadCallback, directDepsCallback, endCallback),
1242 loadOptions, fType);
1246 case DomType::QmlFile: {
1249 auto it = m_qmlFileWithPath.
find(
file.canonicalPath());
1250 if (
it != m_qmlFileWithPath.
end())
1251 oldValue = newValue = *
it;
1253 if (!newValue && (options() & Option::NoReload) && m_base) {
1254 if (
auto v = m_base->qmlFileWithPath(self,
file.canonicalPath(), EnvLookup::Normal)) {
1257 auto newV = std::make_shared<ExternalItemInfo<QmlFile>>(
1258 v->current,
now,
v->revision(),
v->lastDataUpdateAt());
1261 auto it = m_qmlFileWithPath.
find(
file.canonicalPath());
1262 if (
it != m_qmlFileWithPath.
end())
1263 oldValue = newValue = *
it;
1265 m_qmlFileWithPath.
insert(
file.canonicalPath(), newV);
1269 self.universe().loadFile(
1270 file, callbackForQmlFile(self, loadCallback, directDepsCallback, endCallback),
1271 loadOptions, fType);
1275 case DomType::QmltypesFile: {
1278 auto it = m_qmltypesFileWithPath.
find(
file.canonicalPath());
1279 if (
it != m_qmltypesFileWithPath.
end())
1280 oldValue = newValue = *
it;
1282 if (!newValue && (options() & Option::NoReload) && m_base) {
1283 if (
auto v = m_base->qmltypesFileWithPath(self,
file.canonicalPath(),
1284 EnvLookup::Normal)) {
1287 auto newV = std::make_shared<ExternalItemInfo<QmltypesFile>>(
1288 v->current,
now,
v->revision(),
v->lastDataUpdateAt());
1291 auto it = m_qmltypesFileWithPath.
find(
file.canonicalPath());
1292 if (
it != m_qmltypesFileWithPath.
end())
1293 oldValue = newValue = *
it;
1295 m_qmltypesFileWithPath.
insert(
file.canonicalPath(), newV);
1299 self.universe().loadFile(
1301 callbackForQmltypesFile(self, loadCallback, directDepsCallback, endCallback),
1302 loadOptions, fType);
1306 case DomType::QmldirFile: {
1309 auto it = m_qmldirFileWithPath.
find(
file.canonicalPath());
1310 if (
it != m_qmldirFileWithPath.
end())
1311 oldValue = newValue = *
it;
1313 if (!newValue && (options() & Option::NoReload) && m_base) {
1315 m_base->qmldirFileWithPath(self,
file.canonicalPath(), EnvLookup::Normal)) {
1318 auto newV = std::make_shared<ExternalItemInfo<QmldirFile>>(
1319 v->current,
now,
v->revision(),
v->lastDataUpdateAt());
1322 auto it = m_qmldirFileWithPath.
find(
file.canonicalPath());
1323 if (
it != m_qmldirFileWithPath.
end())
1324 oldValue = newValue = *
it;
1326 m_qmldirFileWithPath.
insert(
file.canonicalPath(), newV);
1330 self.universe().loadFile(
1332 callbackForQmldirFile(self, loadCallback, directDepsCallback, endCallback),
1333 loadOptions, fType);
1338 myErrors().error(
tr(
"Unexpected file to load: '%1'").
arg(
file.canonicalPath())).handle(
h);
1340 loadCallback(self.canonicalPath(), DomItem::empty, DomItem::empty);
1341 if (directDepsCallback)
1342 directDepsCallback(self.canonicalPath(), DomItem::empty, DomItem::empty);
1344 endCallback(self.canonicalPath(), DomItem::empty, DomItem::empty);
1348 Path p = self.copy(newValue).canonicalPath();
1349 std::shared_ptr<LoadInfo> lInfo = loadInfo(
p);
1352 DomItem oldValueObj = self.copy(oldValue);
1353 DomItem newValueObj = self.copy(newValue);
1354 loadCallback(
p, oldValueObj, newValueObj);
1356 if (directDepsCallback) {
1357 DomItem lInfoObj = self.copy(lInfo);
1358 lInfo->addEndCallback(lInfoObj, directDepsCallback);
1361 self.addError(myErrors().
error(
tr(
"missing load info in ")));
1363 loadCallback(self.canonicalPath(), DomItem::empty, DomItem::empty);
1364 if (directDepsCallback)
1365 directDepsCallback(self.canonicalPath(), DomItem::empty, DomItem::empty);
1370 endCallback(
p,
el,
el);
1379 Path p = Paths::moduleIndexPath(uri,
v.majorVersion);
1380 if (
v.majorVersion == Version::Latest) {
1384 bool commonV =
false;
1385 QString lastComponent = subPathComponents.last();
1386 subPathComponents.removeLast();
1387 QString subPathV = subPathComponents.join(u
'/');
1390 const auto lPaths = loadPaths();
1395 for (
const QString &dirNow : eList) {
1396 auto m = vRe.
match(dirNow);
1399 if (majorV > maxV) {
1406 if (!commonV && dirNow == lastComponent) {
1414 QAtomicInt toLoad((commonV ? 1 : 0) + ((maxV >= 0) ? 1 : 0));
1415 auto loadCallback2 = (loadCallback ? [
p, loadCallback, toLoad](
Path,
DomItem &,
DomItem &elV)
mutable {
1416 if (--toLoad == 0) {
1418 loadCallback(
p,
el,
el);
1422 loadModuleDependency(self, uri,
Version(maxV,
v.minorVersion), loadCallback2,
nullptr);
1424 loadModuleDependency(self, uri,
Version(Version::Undefined,
v.minorVersion),
1425 loadCallback2,
nullptr);
1426 else if (maxV < 0) {
1427 if (uri != u
"QML") {
1428 addErrorLocal(myErrors()
1429 .warning(
tr(
"Failed to find main qmldir file for %1 %2")
1430 .
arg(uri,
v.stringValue()))
1434 loadCallback(
p, DomItem::empty, DomItem::empty);
1437 std::shared_ptr<ModuleIndex> mIndex = moduleIndexWithUri(
1438 self, uri,
v.majorVersion, EnvLookup::Normal, Changeable::Writable, errorHandler);
1439 std::shared_ptr<LoadInfo> lInfo = loadInfo(
p);
1441 DomItem lInfoObj = self.copy(lInfo);
1442 lInfo->addEndCallback(lInfoObj, loadCallback);
1445 myErrors().warning(
tr(
"Missing loadInfo for %1").
arg(
p.toString())).handle());
1447 loadCallback(
p, DomItem::empty, DomItem::empty);
1453 endCallback(
p,
el,
el);
1460 const auto lPaths = loadPaths();
1465 self.loadFile(FileToLoad::fromFileSystem(self.ownerAs<
DomEnvironment>(),
1467 callback, LoadOption::DefaultLoad);
1471 myErrors().error(
tr(
"Could not find builtins.qmltypes file")).handle(
h);
1477 auto toDelete = [
path](
auto it) {
1479 return p.startsWith(
path) && (
p.size() ==
path.size() ||
p.at(
path.size()) == u
'/');
1481 m_qmlDirectoryWithPath.
removeIf(toDelete);
1482 m_qmldirFileWithPath.removeIf(toDelete);
1483 m_qmlFileWithPath.removeIf(toDelete);
1484 m_jsFileWithPath.removeIf(toDelete);
1485 m_qmltypesFileWithPath.removeIf(toDelete);
1488shared_ptr<DomUniverse> DomEnvironment::universe()
const {
1492 return m_base->universe();
1502 if (options != EnvLookup::NoBase && m_base) {
1506 if (options != EnvLookup::BaseOnly) {
1525 return this->getStrings<QMap<int, std::shared_ptr<ModuleIndex>>>(
1526 [
this, &baseObj] {
return m_base->moduleIndexUris(baseObj, EnvLookup::Normal); },
1527 m_moduleIndexWithUri, lookup);
1533 if (lookup != EnvLookup::NoBase && m_base) {
1535 res = m_base->moduleIndexMajorVersions(baseObj, uri, EnvLookup::Normal);
1537 if (lookup != EnvLookup::BaseOnly) {
1541 map = m_moduleIndexWithUri.
value(uri);
1553std::shared_ptr<ModuleIndex> DomEnvironment::lookupModuleInEnv(
const QString &uri,
int majorVersion)
const
1556 auto it = m_moduleIndexWithUri.
find(uri);
1557 if (
it == m_moduleIndexWithUri.
end())
1561 if (majorVersion == Version::Latest)
1564 return it->value(majorVersion);
1567DomEnvironment::ModuleLookupResult DomEnvironment::moduleIndexWithUriHelper(
DomItem &self,
QString uri,
int majorVersion, EnvLookup options)
const
1569 std::shared_ptr<ModuleIndex>
res;
1570 if (options != EnvLookup::BaseOnly)
1571 res = lookupModuleInEnv(uri, majorVersion);
1574 if (options == EnvLookup::NoBase || !m_base)
1575 return {std::move(
res), ModuleLookupResult::FromGlobal };
1576 const std::shared_ptr existingMod =
1577 m_base->moduleIndexWithUri(self, uri, majorVersion, options, Changeable::ReadOnly);
1579 return { std::move(existingMod), ModuleLookupResult::FromBase };
1581 return {std::move(
res), ModuleLookupResult::FromGlobal };
1587 if (majorVersion == Version::Latest) {
1588 if (
res->majorVersion() >= existingMod->majorVersion())
1589 return { std::move(
res), ModuleLookupResult::FromGlobal };
1591 return { std::move(existingMod), ModuleLookupResult::FromBase };
1595 return { std::move(
res), ModuleLookupResult::FromGlobal };
1599std::shared_ptr<ModuleIndex> DomEnvironment::moduleIndexWithUri(
DomItem &self,
QString uri,
1605 Q_ASSERT((changeable == Changeable::ReadOnly
1606 || (majorVersion >= 0 || majorVersion == Version::Undefined))
1607 &&
"A writeable moduleIndexWithUri call should have a version (not with "
1608 "Version::Latest)");
1609 if (changeable == Changeable::Writable && (
m_options & Option::Exported))
1610 myErrors().error(
tr(
"A mutable module was requested in a multithreaded environment")).handle(errorHandler);
1614 auto [candidate, origin] = moduleIndexWithUriHelper(self, uri, majorVersion, options);
1617 if (candidate && origin == ModuleLookupResult::FromGlobal)
1621 if (changeable == Changeable::ReadOnly)
1625 std::shared_ptr<ModuleIndex> newModulePtr = [&, candidate = candidate](){
1628 return std::make_shared<ModuleIndex>(uri, majorVersion);
1630 DomItem existingModObj = self.copy(candidate);
1631 return candidate->makeCopy(existingModObj);
1634 DomItem newModule = self.copy(newModulePtr);
1638 auto &modsNow = m_moduleIndexWithUri[uri];
1641 if (
auto it = modsNow.
find(majorVersion);
it != modsNow.
end())
1643 modsNow.
insert(majorVersion, newModulePtr);
1646 auto lInfo = std::make_shared<LoadInfo>(
p);
1647 addLoadInfo(self, lInfo);
1650 .error(
tr(
"Could not get path for newly created ModuleIndex %1 %2")
1653 .handle(errorHandler);
1656 return newModulePtr;
1659std::shared_ptr<ModuleIndex> DomEnvironment::moduleIndexWithUri(
DomItem &self,
QString uri,
1663 return moduleIndexWithUriHelper(self, uri, majorVersion, options).module;
1668std::shared_ptr<ExternalItemInfo<QmlDirectory>>
1671 if (options != EnvLookup::BaseOnly) {
1673 if (m_qmlDirectoryWithPath.contains(
path))
1674 return m_qmlDirectoryWithPath.value(
path);
1676 if (options != EnvLookup::NoBase && m_base) {
1677 return m_base->qmlDirectoryWithPath(self,
path, options);
1684 return getStrings<std::shared_ptr<ExternalItemInfo<QmlDirectory>>>(
1687 return m_base->qmlDirectoryPaths(baseObj, EnvLookup::Normal);
1689 m_qmlDirectoryWithPath, options);
1692std::shared_ptr<ExternalItemInfo<QmldirFile>>
1695 if (options != EnvLookup::BaseOnly) {
1698 if (
it != m_qmldirFileWithPath.
end())
1701 if (options != EnvLookup::NoBase && m_base)
1702 return m_base->qmldirFileWithPath(self,
path, options);
1708 return getStrings<std::shared_ptr<ExternalItemInfo<QmldirFile>>>(
1711 return m_base->qmldirFilePaths(baseObj, EnvLookup::Normal);
1713 m_qmldirFileWithPath, lOptions);
1719 if (
auto qmldirFile = qmldirFileWithPath(self,
path +
QLatin1String(
"/qmldir"), options))
1721 return qmlDirectoryWithPath(self,
path, options);
1727 const auto qmldirFiles = qmldirFilePaths(self, options);
1728 for (
const QString &
p : qmldirFiles) {
1729 if (
p.endsWith(u
"/qmldir")) {
1730 res.insert(
p.left(
p.size() - 7));
1733 .warning(
tr(
"Unexpected path not ending with qmldir in qmldirFilePaths: %1")
1741std::shared_ptr<ExternalItemInfo<QmlFile>>
1744 if (options != EnvLookup::BaseOnly) {
1747 if (
it != m_qmlFileWithPath.
end())
1750 if (options != EnvLookup::NoBase && m_base)
1751 return m_base->qmlFileWithPath(self,
path, options);
1757 return getStrings<std::shared_ptr<ExternalItemInfo<QmlFile>>>(
1760 return m_base->qmlFilePaths(baseObj, EnvLookup::Normal);
1762 m_qmlFileWithPath, lookup);
1765std::shared_ptr<ExternalItemInfo<JsFile>>
1768 if (options != EnvLookup::BaseOnly) {
1770 if (m_jsFileWithPath.contains(
path))
1771 return m_jsFileWithPath.value(
path);
1773 if (options != EnvLookup::NoBase && m_base)
1774 return m_base->jsFileWithPath(self,
path, EnvLookup::Normal);
1780 return getStrings<std::shared_ptr<ExternalItemInfo<JsFile>>>(
1783 return m_base->jsFilePaths(baseObj, EnvLookup::Normal);
1785 m_jsFileWithPath, lookup);
1788std::shared_ptr<ExternalItemInfo<QmltypesFile>>
1791 if (options != EnvLookup::BaseOnly) {
1793 if (m_qmltypesFileWithPath.contains(
path))
1794 return m_qmltypesFileWithPath.value(
path);
1796 if (options != EnvLookup::NoBase && m_base)
1797 return m_base->qmltypesFileWithPath(self,
path, EnvLookup::Normal);
1803 return getStrings<std::shared_ptr<ExternalItemInfo<QmltypesFile>>>(
1806 return m_base->qmltypesFilePaths(baseObj, EnvLookup::Normal);
1808 m_qmltypesFileWithPath, lookup);
1811std::shared_ptr<ExternalItemInfo<GlobalScope>>
1814 if (lookupOptions != EnvLookup::BaseOnly) {
1816 auto id = m_globalScopeWithName.find(
name);
1817 if (
id != m_globalScopeWithName.end())
1820 if (lookupOptions != EnvLookup::NoBase && m_base)
1821 return m_base->globalScopeWithName(self,
name, lookupOptions);
1825std::shared_ptr<ExternalItemInfo<GlobalScope>>
1828 if (
auto current = globalScopeWithName(self,
name, lookupOptions))
1830 if (
auto u = universe()) {
1831 if (
auto newVal = u->ensureGlobalScopeWithName(
name)) {
1832 if (
auto current = newVal->current) {
1834 auto newScope = current->
makeCopy(currentObj);
1835 auto newCopy = std::make_shared<ExternalItemInfo<GlobalScope>>(
1838 if (
auto oldVal = m_globalScopeWithName.value(
name))
1840 m_globalScopeWithName.insert(
name, newCopy);
1845 Q_ASSERT_X(
false,
"DomEnvironment::ensureGlobalScopeWithName",
"could not ensure globalScope");
1852 if (lookupOptions != EnvLookup::NoBase && m_base) {
1855 res = m_base->globalScopeNames(baseObj, EnvLookup::Normal);
1858 if (lookupOptions != EnvLookup::BaseOnly) {
1862 map = m_globalScopeWithName;
1874void DomEnvironment::addLoadInfo(
DomItem &self, std::shared_ptr<LoadInfo> loadInfo)
1878 Path p = loadInfo->elementCanonicalPath();
1879 bool addWork = loadInfo->status() != LoadInfo::Status::Done;
1880 std::shared_ptr<LoadInfo> oldVal;
1883 oldVal = m_loadInfos.value(
p);
1884 m_loadInfos.insert(
p, loadInfo);
1886 m_loadsWithWork.enqueue(
p);
1888 if (oldVal && oldVal->status() != LoadInfo::Status::Done) {
1889 self.addError(myErrors()
1890 .
error(
tr(
"addLoadinfo replaces unfinished load info for %1")
1896std::shared_ptr<LoadInfo> DomEnvironment::loadInfo(
Path path)
const
1899 return m_loadInfos.value(
path);
1910 auto lInfos = loadInfos();
1911 return lInfos.keys();
1915 Callback allDirectDepsCallback,
1916 Callback endCallback)
1918 return envCallbackForFile<QmlDirectory>(self, &DomEnvironment::m_qmlDirectoryWithPath,
1919 &DomEnvironment::qmlDirectoryWithPath, loadCallback,
1920 allDirectDepsCallback, endCallback);
1923DomItem::Callback DomEnvironment::callbackForQmlFile(
DomItem &self, Callback loadCallback,
1924 Callback allDirectDepsCallback,
1925 Callback endCallback)
1927 return envCallbackForFile<QmlFile>(self, &DomEnvironment::m_qmlFileWithPath,
1928 &DomEnvironment::qmlFileWithPath, loadCallback,
1929 allDirectDepsCallback, endCallback);
1932DomTop::Callback DomEnvironment::callbackForQmltypesFile(
DomItem &self,
1933 DomTop::Callback loadCallback,
1934 Callback allDirectDepsCallback,
1935 DomTop::Callback endCallback)
1937 return envCallbackForFile<QmltypesFile>(
1938 self, &DomEnvironment::m_qmltypesFileWithPath, &DomEnvironment::qmltypesFileWithPath,
1940 DomItem newFile = newV.field(Fields::currentItem);
1941 if (std::shared_ptr<QmltypesFile> newFilePtr = newFile.ownerAs<QmltypesFile>())
1942 newFilePtr->ensureInModuleIndex(newFile);
1944 loadCallback(
p, oldV, newV);
1946 allDirectDepsCallback, endCallback);
1949DomTop::Callback DomEnvironment::callbackForQmldirFile(
DomItem &self, DomTop::Callback loadCallback,
1950 Callback allDirectDepsCallback,
1951 DomTop::Callback endCallback)
1953 return envCallbackForFile<QmldirFile>(self, &DomEnvironment::m_qmldirFileWithPath,
1954 &DomEnvironment::qmldirFileWithPath, loadCallback,
1955 allDirectDepsCallback, endCallback);
1959 shared_ptr<DomUniverse> universe)
1961 m_universe(
DomUniverse::guaranteeUniverse(universe)),
1962 m_loadPaths(loadPaths),
1963 m_implicitImports(defaultImplicitImports())
1969 auto envPtr = std::make_shared<DomEnvironment>(
loadPaths,
options, universePtr);
1977 m_loadPaths(loadPaths),
1978 m_implicitImports(defaultImplicitImports())
1982std::shared_ptr<ExternalItemInfo<T>>
1989 auto eInfo = std::make_shared<ExternalItemInfo<T>>(
2013 return addExternalItem<QmlFile>(
file,
file->canonicalFilePath(), m_qmlFileWithPath,
options,
2017std::shared_ptr<ExternalItemInfo<QmlDirectory>>
2020 return addExternalItem<QmlDirectory>(
file,
file->canonicalFilePath(), m_qmlDirectoryWithPath,
2024std::shared_ptr<ExternalItemInfo<QmldirFile>>
2027 return addExternalItem<QmldirFile>(
file,
file->canonicalFilePath(), m_qmldirFileWithPath,
2031std::shared_ptr<ExternalItemInfo<QmltypesFile>>
2034 return addExternalItem<QmltypesFile>(
file,
file->canonicalFilePath(), m_qmltypesFileWithPath,
2041 return addExternalItem<JsFile>(
file,
file->canonicalFilePath(), m_jsFileWithPath,
options,
2045std::shared_ptr<ExternalItemInfo<GlobalScope>>
2048 return addExternalItem<GlobalScope>(scope, scope->name(), m_globalScopeWithName,
options,
2066 my_moduleIndexWithUri = m_moduleIndexWithUri;
2067 my_globalScopeWithName = m_globalScopeWithName;
2068 my_qmlDirectoryWithPath = m_qmlDirectoryWithPath;
2069 my_qmldirFileWithPath = m_qmldirFileWithPath;
2070 my_qmlFileWithPath = m_qmlFileWithPath;
2071 my_jsFileWithPath = m_jsFileWithPath;
2072 my_qmltypesFileWithPath = m_qmltypesFileWithPath;
2073 my_loadInfos = m_loadInfos;
2077 m_base->m_globalScopeWithName.insert(my_globalScopeWithName);
2078 m_base->m_qmlDirectoryWithPath.insert(my_qmlDirectoryWithPath);
2079 m_base->m_qmldirFileWithPath.insert(my_qmldirFileWithPath);
2080 m_base->m_qmlFileWithPath.insert(my_qmlFileWithPath);
2081 m_base->m_jsFileWithPath.insert(my_jsFileWithPath);
2082 m_base->m_qmltypesFileWithPath.insert(my_qmltypesFileWithPath);
2083 m_base->m_loadInfos.insert(my_loadInfos);
2085 auto it = my_moduleIndexWithUri.
cbegin();
2086 auto end = my_moduleIndexWithUri.
cend();
2089 m_base->m_moduleIndexWithUri[
it.key()];
2091 auto end2 =
it.value().
cend();
2092 while (it2 != end2) {
2093 auto oldV = myVersions.
value(it2.key());
2094 DomItem it2Obj = self.copy(it2.value());
2095 auto newV = it2.value()->makeCopy(it2Obj);
2096 newV->mergeWith(oldV);
2097 myVersions.
insert(it2.key(), newV);
2106 validEnvPtr->mutex());
2107 validEnvPtr->m_globalScopeWithName.insert(my_globalScopeWithName);
2108 validEnvPtr->m_qmlDirectoryWithPath.insert(my_qmlDirectoryWithPath);
2109 validEnvPtr->m_qmldirFileWithPath.insert(my_qmldirFileWithPath);
2112 if (
it.value() &&
it.value()->current &&
it.value()->current->isValid())
2113 validEnvPtr->m_qmlFileWithPath.insert(
it.key(),
it.value());
2117 if (
it.value() &&
it.value()->current &&
it.value()->current->isValid())
2118 validEnvPtr->m_jsFileWithPath.insert(
it.key(),
it.value());
2120 validEnvPtr->m_qmltypesFileWithPath.insert(my_qmltypesFileWithPath);
2121 validEnvPtr->m_loadInfos.insert(my_loadInfos);
2122 for (
auto it = my_moduleIndexWithUri.
cbegin(),
end = my_moduleIndexWithUri.
cend();
2125 validEnvPtr->m_moduleIndexWithUri[
it.key()];
2126 for (
auto it2 =
it.value().
cbegin(), end2 =
it.value().
cend(); it2 != end2; ++it2) {
2127 auto oldV = myVersions.
value(it2.key());
2128 DomItem it2Obj = self.copy(it2.value());
2129 auto newV = it2.value()->makeCopy(it2Obj);
2130 newV->mergeWith(oldV);
2131 myVersions.
insert(it2.key(), newV);
2142 std::shared_ptr<LoadInfo>
loadInfo;
2145 if (m_loadsWithWork.isEmpty())
2147 elToDo = m_loadsWithWork.dequeue();
2148 m_inProgress.append(elToDo);
2149 loadInfo = m_loadInfos.value(elToDo);
2152 auto cleanup =
qScopeGuard([
this, elToDo, &self] {
2156 m_inProgress.removeOne(elToDo);
2157 if (m_inProgress.isEmpty() && m_loadsWithWork.isEmpty()) {
2158 endCallbacks = m_allLoadedCallback;
2159 m_allLoadedCallback.
clear();
2162 for (
const Callback &
cb : std::as_const(endCallbacks))
2163 cb(self.canonicalPath(), self, self);
2166 loadInfo->advanceLoad(loadInfoObj);
2168 self.addError(
myErrors().
error(u
"DomEnvironment::loadPendingDependencies could not "
2169 u
"find loadInfo listed in m_loadsWithWork"));
2172 m_inProgress.removeOne(elToDo);
2175 &&
"DomEnvironment::loadPendingDependencies could not find loadInfo listed in "
2183 bool hasPendingLoads =
true;
2185 for (
int i = 0;
i < waitMSec / 10 + 2; ++
i) {
2189 auto end = lInfos.cend();
2190 hasPendingLoads =
false;
2193 hasPendingLoads =
true;
2195 if (!hasPendingLoads)
2202#if QT_FEATURE_thread
2206 return !hasPendingLoads;
2212 m_loadsWithWork.enqueue(elementCanonicalPath);
2240 return m_qmldirFileWithPath.keys();
2245 return m_globalScopeName;
2256 return m_implicitImports;
2262 bool immediate =
false;
2265 if (m_loadsWithWork.isEmpty() && m_inProgress.isEmpty())
2268 m_allLoadedCallback.
append(
c);
2271 c(
Path(), self, self);
2277 m_referenceCache.clear();
2282 shared_ptr<ExternalOwningItem> current =
currentItem();
2284 return current->canonicalFilePath(currentObj);
2289 if (!self.dvValueLazyField(visitor, Fields::currentRevision,
2290 [
this, &self]() { return currentRevision(self); }))
2292 if (!self.dvValueLazyField(visitor, Fields::lastRevision,
2293 [
this, &self]() { return lastRevision(self); }))
2295 if (!self.dvValueLazyField(visitor, Fields::lastValidRevision,
2296 [
this, &self]() { return lastValidRevision(self); }))
2301 if (!self.dvValueLazyField(visitor, Fields::currentExposedAt,
2315 DomItem lastValue = self.universe()[
p.mid(1,
p.length() - 1)].field(u
"revision");
2322 DomItem lastValidValue = self.universe()[
p.mid(1,
p.length() - 2)].field(u
"validItem").field(u
"revision");
2328 shared_ptr<ExternalOwningItem> current =
currentItem();
2329 return current->canonicalFilePath();
2334 shared_ptr<ExternalOwningItem> current =
currentItem();
2335 return current->canonicalPath().dropTail();
2340 if (!self.dvValueLazyField(visitor, Fields::currentIsValid,
2341 [
this]() { return currentIsValid(); }))
2348 if (!self.dvValueField(visitor, Fields::validExposedAt,
validExposedAt))
2350 if (!self.dvValueField(visitor, Fields::currentExposedAt,
currentExposedAt))
2370 <<
el.internalKindStr() <<
el.canonicalPath();
2381 bool didSet =
false;
2415#include "moc_qqmldomtop_p.cpp"
qint64 toInteger(qint64 defaultValue=0) const
Returns the integer value stored in this QCborValue, if it is of the integer type.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
\inmodule QtCore\reentrant
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
QDateTime addMSecs(qint64 msecs) const
Returns a QDateTime object containing a datetime msecs milliseconds later than the datetime of this o...
qint64 msecsTo(const QDateTime &) const
Returns the number of milliseconds from this datetime to the other datetime.
static QDateTime currentDateTimeUtc()
QDate date() const
Returns the date part of the datetime.
QStringList entryList(Filters filters=NoFilter, SortFlags sort=NoSort) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
FileError error() const
Returns the file error status.
void close() override
Calls QFileDevice::flush() and closes the file.
\inmodule QtCore \reentrant
bool isFile() const
Returns true if this object points to a file or to a symbolic link to a file.
QString canonicalFilePath() const
Returns the canonical path including the file name, i.e.
bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
QString errorString() const
Returns a human-readable description of the last device error that occurred.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void append(parameter_type t)
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue=T()) const
const_iterator cend() const
const_iterator cbegin() const
iterator find(const Key &key)
key_iterator keyBegin() const
Key key(const T &value, const Key &defaultKey=Key()) const
key_iterator keyEnd() const
Represents a consistent set of types organized in modules, it is the top level of the DOM.
void clearReferenceCache()
std::shared_ptr< ExternalItemInfo< QmlDirectory > > addQmlDirectory(std::shared_ptr< QmlDirectory > file, AddOption option=AddOption::KeepExisting)
void loadPendingDependencies(DomItem &self)
QString globalScopeName() const
QStringList qmldirFiles() const
std::shared_ptr< LoadInfo > loadInfo(Path path) const
std::shared_ptr< ExternalItemInfo< QmldirFile > > addQmldirFile(std::shared_ptr< QmldirFile > file, AddOption option=AddOption::KeepExisting)
void addWorkForLoadInfo(Path elementCanonicalPath)
void addAllLoadedCallback(DomItem &self, Callback c)
static ErrorGroups myErrors()
static QList< Import > defaultImplicitImports()
void setLoadPaths(const QStringList &v)
std::shared_ptr< ExternalItemInfo< JsFile > > addJsFile(std::shared_ptr< JsFile > file, AddOption option=AddOption::KeepExisting)
std::shared_ptr< DomEnvironment > base() const
std::shared_ptr< ExternalItemInfo< QmltypesFile > > addQmltypesFile(std::shared_ptr< QmltypesFile > file, AddOption option=AddOption::KeepExisting)
std::shared_ptr< ExternalItemInfo< GlobalScope > > addGlobalScope(std::shared_ptr< GlobalScope > file, AddOption option=AddOption::KeepExisting)
static DomItem create(QStringList loadPaths, Options options=Option::SingleThreaded, DomItem &universe=DomItem::empty)
std::shared_ptr< ExternalItemInfo< QmlFile > > addQmlFile(std::shared_ptr< QmlFile > file, AddOption option=AddOption::KeepExisting)
std::shared_ptr< DomUniverse > universe() const
DomEnvironment(QStringList loadPaths, Options options=Option::SingleThreaded, std::shared_ptr< DomUniverse > universe=nullptr)
QList< Import > implicitImports() const
QHash< Path, std::shared_ptr< LoadInfo > > loadInfos() const
bool finishLoadingDependencies(DomItem &self, int waitMSec=30000)
bool commitToBase(DomItem &self, std::shared_ptr< DomEnvironment > validEnv=nullptr)
QStringList loadPaths() const
std::shared_ptr< T > ownerAs()
function< void(Path, DomItem &, DomItem &)> Callback
bool iterateErrors(function_ref< bool(DomItem source, ErrorMessage msg)> visitor, bool iterate, Path inPath=Path())
DomItem copy(Owner owner, Path ownerPath, T base)
MutableDomItem makeCopy(CopyOption option=CopyOption::EnvConnected)
DomItem path(Path p, ErrorHandler h=&defaultErrorHandler)
QString canonicalFilePath()
void addError(ErrorMessage msg)
bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override
DomItem containingObject(DomItem &) const override
virtual Path canonicalPath() const =0
DomItem::Callback Callback
Represents a set of parsed/loaded modules libraries and a plugins.
bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override
QSet< QString > globalScopeNames() const
std::shared_ptr< ExternalItemPair< QmltypesFile > > qmltypesFileWithPath(QString path) const
std::shared_ptr< ExternalItemPair< QmlDirectory > > qmlDirectoryWithPath(QString path) const
std::shared_ptr< ExternalItemPair< GlobalScope > > globalScopeWithName(QString name) const
static ErrorGroups myErrors()
QSet< QString > qmltypesFilePaths() const
std::shared_ptr< ExternalItemPair< QmldirFile > > qmldirFileWithPath(QString path) const
std::shared_ptr< ExternalItemPair< QmlFile > > qmlFileWithPath(QString path) const
std::shared_ptr< ExternalItemPair< JsFile > > jsFileWithPath(QString path) const
void removePath(const QString &dir)
static std::shared_ptr< DomUniverse > guaranteeUniverse(std::shared_ptr< DomUniverse > univ)
std::shared_ptr< OwningItem > doCopy(DomItem &self) const override
QSet< QString > qmlDirectoryPaths() const
QSet< QString > jsFilePaths() const
QSet< QString > qmldirFilePaths() const
static DomItem create(QString universeName, Options options=Option::SingleThreaded)
void loadFile(DomItem &self, const FileToLoad &file, Callback callback, LoadOptions loadOptions, std::optional< DomType > fileType=std::optional< DomType >())
Path canonicalPath() const override
QQueue< ParsingTask > queue() const
QSet< QString > qmlFilePaths() const
Represents a set of tags grouping a set of related error messages.
ErrorMessage warning(QString message) const
ErrorMessage error(QString message) const
Represents an error message connected to the dom.
ErrorMessage handle(const ErrorHandler &errorHandler=nullptr)
int lastRevision(DomItem &self) const
QDateTime currentExposedAt() const
virtual std::shared_ptr< ExternalOwningItem > currentItem() const =0
bool iterateDirectSubpaths(DomItem &self, DirectVisitor) final override
int currentRevision(DomItem &self) const
QString canonicalFilePath(DomItem &) const final override
int lastValidRevision(DomItem &self) const
QDateTime currentExposedAt
bool iterateDirectSubpaths(DomItem &self, DirectVisitor) final override
bool currentIsValid() const
Path canonicalPath(DomItem &self) const final override
QString canonicalFilePath(DomItem &) const final override
virtual std::shared_ptr< ExternalOwningItem > currentItem() const =0
virtual std::shared_ptr< ExternalOwningItem > validItem() const =0
static FileToLoad fromFileSystem(const std::weak_ptr< DomEnvironment > &environment, const QString &canonicalPath, DomCreationOptions options=None)
static Import fromUriString(QString importStr, Version v=Version(), QString importId=QString(), ErrorHandler handler=nullptr)
std::shared_ptr< OwningItem > doCopy(DomItem &self) const override
void addEndCallback(DomItem &self, std::function< void(Path, DomItem &, DomItem &)> callback)
void execEnd(DomItem &self)
Path canonicalPath(DomItem &self) const override
bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override
Path elementCanonicalPath() const
void advanceLoad(DomItem &self)
void finishedLoadingDep(DomItem &self, const Dependency &d)
QBasicMutex * mutex() const
void addErrorLocal(ErrorMessage msg)
bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override
virtual void refreshedDataAt(QDateTime tNew)
static Path Root(PathRoot r)
Path key(QString name) const
Path field(QString name) const
static Path Field(QStringView s=u"")
static QmlUri fromUriString(const QString &importStr)
static std::shared_ptr< QmldirFile > fromPathAndCode(QString path, QString code)
static bool addForPath(DomItem &el, Path canonicalPath, const RefCacheEntry &entry, AddOption addOption=AddOption::KeepExisting)
static RefCacheEntry forPath(DomItem &el, Path canonicalPath)
Represents an immutable JsonPath like path in the Qml code model (from a DomItem to another DomItem)
QString captured(int nth=0) const
Returns the substring captured by the nth capturing group.
\inmodule QtCore \reentrant
static QString escape(const QString &str)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QRegularExpressionMatch match(const QString &subject, qsizetype offset=0, MatchType matchType=NormalMatch, MatchOptions matchOptions=NoMatchOption) const
Attempts to match the regular expression against the given subject string, starting at the position o...
static QString anchoredPattern(const QString &expression)
const_iterator cend() const noexcept
iterator find(const T &value)
const_iterator cbegin() const noexcept
iterator insert(const T &value)
qsizetype removeIf(Pred predicate)
\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 ...
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
bool isNull() const
Returns true if this string is null; otherwise returns false.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QChar * data()
Returns a pointer to the data stored in the QString.
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static void msleep(unsigned long)
QMap< QString, QString > map
[6]
cache insert(employee->id(), employee)
QSet< QString >::iterator it
Path qmlDirectoryInfoPath(QString path)
Path qmldirFileInfoPath(QString path)
Path qmlFileInfoPath(QString canonicalFilePath)
Path qmltypesFileInfoPath(QString path)
void createDom(MutableDomItem qmlFile, DomCreationOptions options=None)
std::function< void(const ErrorMessage &)> ErrorHandler
DomTop::Callback envCallbackForFile(DomItem &self, QMap< QString, std::shared_ptr< ExternalItemInfo< T > > > DomEnvironment::*map, std::shared_ptr< ExternalItemInfo< T > >(DomEnvironment::*lookupF)(DomItem &, QString, EnvLookup) const, DomTop::Callback loadCallback, DomTop::Callback allDirectDepsCallback, DomTop::Callback endCallback)
std::shared_ptr< ExternalItemInfo< T > > addExternalItem(std::shared_ptr< T > file, QString key, QMap< QString, std::shared_ptr< ExternalItemInfo< T > > > &map, AddOption option, QBasicMutex *mutex)
QMLDOM_EXPORT QString domTypeToString(DomType k)
static QString toString(const UiQualifiedId *qualifiedId, QChar delimiter=QLatin1Char('.'))
static DomType fileTypeForPath(DomItem &self, QString canonicalFilePath)
QPair< std::shared_ptr< ExternalItemPair< T > >, std::shared_ptr< ExternalItemPair< T > > > updateEntry(DomItem &univ, std::shared_ptr< T > newItem, QMap< QString, std::shared_ptr< ExternalItemPair< T > > > &map, QBasicMutex *mutex)
Combined button and popup list for selecting options.
SharedPointerFileDialogOptions m_options
std::pair< T1, T2 > QPair
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qCWarning(category,...)
static ControlElement< T > * ptr(QWidget *widget)
GLsizei const GLfloat * v
[13]
GLuint64 GLenum void * handle
GLfloat GLfloat GLfloat GLfloat h
GLdouble GLdouble GLdouble GLdouble q
GLsizei const GLchar *const * path
GLsizei GLenum GLboolean sink
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
#define NewErrorGroup(name)
QT_BEGIN_NAMESPACE typedef void(* Callback)(QQmlNotifierEndpoint *, void **)
#define Q_ASSERT_X(cond, x, msg)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
static QString canonicalPath(const QString &rootPath)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static FileType fileType(const QFileInfo &fi)
static int compare(quint64 a, quint64 b)
if(qFloatDistance(a, b)<(1<< 7))
[0]
char * toString(const MyType &t)
[31]
\inmodule QtCore \reentrant
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent