18#include <QtQml/private/qqmljslexer_p.h>
19#include <QtQml/private/qqmljsparser_p.h>
20#include <QtQml/private/qqmljsengine_p.h>
21#include <QtQml/private/qqmljsastvisitor_p.h>
22#include <QtQml/private/qqmljsast_p.h>
24#include <QtCore/QCborArray>
25#include <QtCore/QCborMap>
26#include <QtCore/QDebug>
28#include <QtCore/QFile>
29#include <QtCore/QFileInfo>
30#include <QtCore/QJsonDocument>
31#include <QtCore/QJsonValue>
32#include <QtCore/QMutexLocker>
33#include <QtCore/QPair>
34#include <QtCore/QRegularExpression>
35#include <QtCore/QScopeGuard>
36#include <QtCore/QtGlobal>
37#include <QtCore/QTimeZone>
49template<
class... TypeList>
50struct CheckDomElementT;
53struct CheckDomElementT<
std::
variant<Ts...>> : std::conjunction<IsInlineDom<Ts>...>
75static_assert(CheckDomElementT<ElementT>::value,
76 "Types in ElementT must either be a pointer to a class inheriting "
77 "from DomBase or (for internal Dom structures) implement a smart "
78 "pointer pointing to a class inheriting from DomBase");
135 QMetaEnum metaEnum = QMetaEnum::fromType<DomType>();
157 QMetaEnum metaEnum = QMetaEnum::fromType<DomKind>();
245 return parent.canonicalFilePath();
252 <<
self.canonicalPath();
259bool ConstantData::iterateDirectSubpaths(
DomItem &self, DirectVisitor visitor)
267 return knownFields[
f];
269 if (m_value.isMap()) {
275 PathEls::PathComponent comp;
277 case ConstantData::Options::MapIsMap:
278 comp = PathEls::Key(
key);
280 case ConstantData::Options::FirstMapIsFields:
281 comp = PathEls::Field(toField(
key));
284 auto val =
it.value();
285 if (!
self.dvValue(visitor, comp,
val))
290 }
else if (m_value.isArray()){
296 if (!
self.dvValue(visitor, PathEls::Index(
i++), *
it++))
310DomKind ConstantData::domKind()
const
312 if (m_value.isMap()) {
314 case ConstantData::Options::MapIsMap:
316 case ConstantData::Options::FirstMapIsFields:
317 return DomKind::Object;
320 if (m_value.isArray())
321 return DomKind::List;
322 return DomKind::Value;
360FileToLoad::FileToLoad(
const std::weak_ptr<DomEnvironment> &environment,
362 std::optional<InMemoryContents> content, DomCreationOptions options)
363 : m_environment(environment),
365 m_logicalPath(logicalPath),
371FileToLoad FileToLoad::fromMemory(
const std::weak_ptr<DomEnvironment> &environment,
373 DomCreationOptions options)
379FileToLoad FileToLoad::fromFileSystem(
const std::weak_ptr<DomEnvironment> &environment,
390ErrorGroups DomItem::myErrors()
392 static ErrorGroups
res = {{domErrorGroup}};
396ErrorGroups DomItem::myResolveErrors()
402Path DomItem::canonicalPath()
404 Path
res = visitEl([
this](
auto &&
el) {
return el->canonicalPath(*
this); });
405 if (!(!
res ||
res.headKind() == Path::Kind::Root)) {
406 qCWarning(domLog) <<
"non anchored canonical path:" <<
res.toString();
413DomItem DomItem::containingObject()
415 return visitEl([
this](
auto &&
el) {
return el->containingObject(*
this); });
424DomItem DomItem::qmlObject(GoTo options, FilterUpOptions filterOptions)
426 if (
DomItem res = filterUp([](DomType k,
DomItem &) {
return k == DomType::QmlObject; },
429 if (options == GoTo::MostLikely) {
431 return comp.field(Fields::objects).index(0);
436DomItem DomItem::fileObject(GoTo options)
440 if (k == DomType::List || k == DomType::Map) {
441 res =
res.containingObject();
442 k =
res.internalKind();
444 if (k == DomType::ExternalItemInfo || (options == GoTo::MostLikely && k == DomType::ExternalItemPair))
445 return field(Fields::currentItem);
447 k =
res.internalKind();
448 while (k != DomType::Empty) {
449 if (k == DomType::QmlFile || k == DomType::QmldirFile || k == DomType::QmltypesFile
450 || k == DomType::JsFile)
452 res =
res.containingObject();
454 k =
res.internalKind();
459DomItem DomItem::rootQmlObject(GoTo options)
461 if (
DomItem res = filterUp([](DomType k,
DomItem &) {
return k == DomType::QmlObject; },
462 FilterUpOptions::ReturnInner))
464 if (options == GoTo::MostLikely) {
466 return comp.field(Fields::objects).index(0);
473 Path
path = pathFromOwner();
476 Source
s =
path.split();
477 if (
s.pathFromSource.length() > 1)
478 return containingObject().path(
s.pathFromSource.dropTail());
479 return containingObject();
484 if (internalKind() == DomType::GlobalScope)
487 if (shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>()) {
488 return env.copy(envPtr->ensureGlobalScopeWithName(env, envPtr->globalScopeName())->current,
503 [
this](
auto &&
el) {
return DomItem(this->m_top,
el, this->m_ownerPath,
el.get()); },
511 return std::visit([](
auto &&
el) {
return DomItem(
el,
el, Path(),
el.get()); }, *m_top);
517 if (
res.internalKind() == DomType::DomEnvironment)
525 if (
res.internalKind() == DomType::DomUniverse)
527 if (
res.internalKind() == DomType::DomEnvironment)
528 return res.field(Fields::universe);
538DomItem DomItem::containingFile()
540 if (
DomItem res = filterUp([](DomType k,
DomItem &) {
return k == DomType::QmlFile; },
541 FilterUpOptions::ReturnOuter))
555 top().field(Fields::qmlFileWithPath).key(
canonicalPath).field(Fields::currentItem);
578DomItem DomItem::filterUp(function_ref<
bool(DomType k,
DomItem &)>
filter, FilterUpOptions options)
583 case FilterUpOptions::ReturnOuter:
584 case FilterUpOptions::ReturnOuterNoSelf: {
585 bool checkTop = (options == FilterUpOptions::ReturnOuter);
586 while (k != DomType::Empty) {
594 Path pp =
it.pathFromOwner();
600 for (Path
p : pp.mid(0, pp.
length() - 1)) {
608 if (k != DomType::Empty)
612 it =
it.containingObject();
613 k =
it.internalKind();
616 case FilterUpOptions::ReturnInner:
617 while (k != DomType::Empty) {
620 Path pp = pathFromOwner();
630 it =
it.containingObject();
631 k =
it.internalKind();
638DomItem DomItem::scope(FilterUpOptions options)
644std::optional<QQmlJSScope::Ptr> DomItem::nearestSemanticScope()
646 std::optional<QQmlJSScope::Ptr> scope;
648 scope =
item.semanticScope();
654std::optional<QQmlJSScope::Ptr> DomItem::semanticScope()
656 std::optional<QQmlJSScope::Ptr> scope = std::visit(
657 [](
auto &&
e) -> std::optional<QQmlJSScope::Ptr> {
658 using T = std::remove_cv_t<std::remove_reference_t<
decltype(
e)>>;
659 if constexpr (std::is_same_v<T, QmlObject *>) {
660 return e->semanticScope();
661 }
else if constexpr (std::is_same_v<T, QmlComponent *>) {
662 return e->semanticScope();
663 }
else if constexpr (std::is_same_v<T, ScriptElementDomWrapper>) {
664 return e.element().base()->semanticScope();
674 if (
const Reference *refPtr = as<Reference>())
675 return refPtr->get(*
this,
h, visitedRefs);
681 if (
const Reference *refPtr = as<Reference>())
682 return refPtr->getAll(*
this,
h, visitedRefs);
691 switch (
el.internalKind()) {
692 case DomType::Binding:
693 pInfo.bindings.append(el);
695 case DomType::PropertyDefinition:
696 pInfo.propertyDefs.append(el);
718DomItem DomItem::component(GoTo options)
722 return kind == DomType::QmlComponent || kind == DomType::QmltypesComponent
723 || kind == DomType::GlobalComponent;
725 FilterUpOptions::ReturnInner))
727 if (options == GoTo::MostLikely) {
730 if (kind == DomType::List || kind == DomType::Map) {
732 kind =
item.internalKind();
735 case DomType::ExternalItemPair:
736 case DomType::ExternalItemInfo:
737 item = fileObject(options);
739 case DomType::QmlFile:
740 return item.field(Fields::components).key(
QString()).index(0);
756 QMetaEnum metaEnum = QMetaEnum::fromType<LookupType>();
766bool DomItem::resolve(Path
path, DomItem::Visitor visitor, ErrorHandler errorHandler,
767 ResolveOptions options, Path fullPath,
QList<Path> *visitedRefs)
770 Path fPath = fullPath;
771 if (fullPath.length() == 0)
773 if (
path.length()==0)
774 return visitor(fPath, *
this);
778 if (
path.headKind() == Path::Kind::Root) {
782 case PathRoot::Modules:
783 root = root.environment().field(Fields::moduleIndexWithUri);
786 root = root.environment()[Fields::qmltypesFileWithPath];
789 root = root.environment()[Fields::plugins];
795 root = root.environment();
797 case PathRoot::Universe:
798 root = root.environment()[u
"universe"];
800 case PathRoot::Other:
801 myResolveErrors().error(
tr(
"Root context %1 is not known").
arg(
path.headName())).handle(errorHandler);
804 toDos[0] = {root, 1};
806 toDos[0] = {*
this, 0};
808 while (!toDos.isEmpty()) {
809 auto toDo = toDos.last();
812 auto idNow = toDo.item.id();
813 if (idNow ==
quintptr(0) && toDo.item == *
this)
818 int iPath = toDo.pathIndex;
820 bool branchExhausted =
false;
821 while (iPath <
path.length() &&
it && !branchExhausted) {
822 auto idNow =
it.id();
823 if (idNow ==
quintptr() && toDo.item == *
this)
827 if (visited[vPair.second].contains(vPair.first))
829 visited[vPair.second].insert(vPair.first);
831 if (options & ResolveOption::TraceVisit && !visitor(
path.mid(0,iPath),
it))
833 auto cNow =
path[iPath++];
834 switch (cNow.headKind()) {
835 case Path::Kind::Key:
836 it =
it.key(cNow.headName());
838 case Path::Kind::Field:
839 if (cNow.checkHeadName(Fields::get) &&
it.internalKind() == DomType::Reference) {
840 Path toResolve =
it.as<
Reference>()->referredObjectPath;
841 Path refRef =
it.canonicalPath();
842 if (visitedRefs ==
nullptr) {
843 visitedRefs = &vRefs;
845 if (visitedRefs->
contains(refRef)) {
847 .error([visitedRefs, refRef](Sink
sink) {
850 for (
const Path &vPath : *visitedRefs) {
860 visitedRefs->
append(refRef);
868 errorHandler, ResolveOption::None, toResolve, visitedRefs);
872 it =
it.field(cNow.headName());
875 case Path::Kind::Index:
876 it =
it.index(cNow.headIndex());
878 case Path::Kind::Empty:
883 if (iPath >=
path.length()) {
884 myResolveErrors().warning(
tr(
"Resolve with path ending with empty path, matches nothing."))
885 .handle(errorHandler);
886 branchExhausted =
true;
889 toFind =
path[iPath++];
890 }
while (toFind.headKind() == Path::Kind::Empty);
891 QVector<Path::Kind> validFind({Path::Kind::Key, Path::Kind::Field, Path::Kind::Field, Path::Kind::Index});
892 if (!validFind.contains(toFind.headKind())) {
893 myResolveErrors().error(
tr(
"After an empty path only key, field or indexes are supported, not %1.").
arg(toFind.toString()))
894 .handle(errorHandler);
895 branchExhausted =
true;
898 if (!branchExhausted)
901 [toFind, &toDos, iPath](Path,
DomItem &
item,
bool) {
905 toDos.append({ newItem, iPath });
908 VisitOption::VisitSelf | VisitOption::Recurse
909 | VisitOption::VisitAdopted | VisitOption::NoPath);
910 branchExhausted =
true;
913 case Path::Kind::Root:
914 myResolveErrors().error(
tr(
"Root path is supported only at the beginning, and only once, found %1 at %2 in %3")
915 .
arg(cNow.toString()).arg(iPath -1).arg(
path.toString())).handle(errorHandler);
917 case Path::Kind::Current:
921 case PathCurrent::Other:
923 case PathCurrent::Obj:
924 if (domKind() != DomKind::Object)
925 it =
it.containingObject();
927 case PathCurrent::ObjChain: {
928 bool cont =
it.visitPrototypeChain(
929 [&toDos, iPath](
DomItem &subEl) {
930 toDos.append({ subEl, iPath });
933 VisitPrototypesOption::Normal, errorHandler,
nullptr,
937 branchExhausted =
true;
940 case PathCurrent::ScopeChain: {
941 bool cont =
it.visitScopeChain(
942 [&toDos, iPath](
DomItem &subEl) {
943 toDos.append({ subEl, iPath });
946 LookupOption::Normal, errorHandler);
949 branchExhausted =
true;
952 case PathCurrent::Component:
955 case PathCurrent::Module:
956 case PathCurrent::Ids:
957 it =
it.component().ids();
959 case PathCurrent::Types:
960 it =
it.component()[Fields::exports];
962 case PathCurrent::LookupStrict:
963 case PathCurrent::LookupDynamic:
964 case PathCurrent::Lookup: {
965 LookupOptions
opt = LookupOption::Normal;
966 if (current == PathCurrent::Lookup) {
968 DomItem strict = comp.field(u
"~strictLookup~");
971 strict = env.field(u
"defaultStrictLookup");
973 if (strict && strict.value().toBool())
974 opt =
opt | LookupOption::Strict;
975 }
else if (current == PathCurrent::LookupStrict) {
976 opt =
opt | LookupOption::Strict;
978 if (
it.internalKind() == DomType::ScriptExpression) {
980 .error(
tr(
"Javascript lookups not yet implemented"))
981 .handle(errorHandler);
985 auto idNow =
it.id();
986 if (idNow ==
quintptr(0) && toDo.item == *
this)
990 if (visited[vPair.second].contains(vPair.first))
992 visited[vPair.second].insert(vPair.first);
994 if (options & ResolveOption::TraceVisit && !visitor(
path.mid(0, iPath),
it))
996 if (iPath + 1 >=
path.length()) {
998 .error(
tr(
"Premature end of path, expected a field specifying the "
999 "type, and a key specifying the name to search after a "
1000 "lookup directive in %2")
1002 .handle(errorHandler);
1005 Path cNow =
path[iPath++];
1006 if (cNow.headKind() != Path::Kind::Field) {
1008 .error(
tr(
"Expected a key path specifying the type to search after "
1009 "a lookup directive, not %1 at component %2 of %3")
1010 .
arg(cNow.toString())
1012 .arg(
path.toString()))
1013 .handle(errorHandler);
1016 QString expectedType = cNow.headName();
1020 auto m = lookupTypeToStringMap();
1025 lookupType =
it.key();
1032 it = lookupTypeToStringMap().
begin();
1034 if (!
types.isEmpty())
1040 .error(
tr(
"Type for lookup was expected to be one of '%1', not "
1043 .handle(errorHandler);
1047 cNow =
path[iPath++];
1048 if (cNow.headKind() != Path::Kind::Key) {
1050 .error(
tr(
"Expected a key specifying the path to search after the "
1051 "@lookup directive and type, not %1 at component %2 of "
1053 .
arg(cNow.toString())
1055 .arg(
path.toString()))
1056 .handle(errorHandler);
1062 .warning(
tr(
"Path with empty lookup at component %1 of %2 will "
1063 "match nothing in %3.")
1066 .arg(
it.canonicalPath().toString()))
1067 .handle(errorHandler);
1072 [&toDos, iPath](
DomItem &subEl) {
1073 toDos.append({ subEl, iPath });
1076 lookupType,
opt, errorHandler, &(visited[iPath]), visitedRefs);
1077 branchExhausted =
true;
1083 case Path::Kind::Any:
1087 toDos.append({
item, iPath });
1090 VisitOption::VisitSelf | VisitOption::Recurse | VisitOption::VisitAdopted);
1091 branchExhausted =
true;
1093 case Path::Kind::Filter:
1094 if (cNow.headFilter() && !cNow.headFilter()(
it))
1095 branchExhausted =
true;
1100 if (!branchExhausted && iPath ==
path.length() && !visitor(fPath,
it))
1106DomItem DomItem::path(Path
p, ErrorHandler errorHandler)
1120 return path(Path::fromString(
p, errorHandler));
1125 return path(Path::fromString(
p, errorHandler));
1130 return visitEl([
this](
auto &&
el) {
return el->fields(*
this); });
1135 return visitEl([
this,
name](
auto &&
el) {
return el->field(*
this,
name); });
1140 return visitEl([
this](
auto &&
el) {
return el->indexes(*
this); });
1143DomItem DomItem::index(index_type
i)
1145 return visitEl([
this,
i](
auto &&
el) {
return el->index(*
this,
i); });
1148bool DomItem::visitIndexes(function_ref<
bool(
DomItem &)> visitor)
1151 int nIndexes = indexes();
1152 for (
int i = 0;
i < nIndexes; ++
i) {
1162 return visitEl([
this](
auto &&
el) {
return el->keys(*
this); });
1169 std::sort(sortedKs.begin(), sortedKs.end());
1175 return visitEl([
this,
name](
auto &&
el) {
return el->key(*
this,
name); });
1178bool DomItem::visitKeys(function_ref<
bool(
QString,
DomItem &)> visitor)
1181 for (
auto k : sortedKeys()) {
1192 visitEl([
this, &
res](
auto &&
el) {
1193 return el->iterateDirectSubpathsConst(
1194 *
this, [&
res](
const PathEls::PathComponent &, function_ref<
DomItem()>
item) {
1202void DomItem::writeOutPre(OutWriter &ow)
1204 if (hasAnnotations()) {
1205 DomItem anns = field(Fields::annotations);
1206 for (
auto ann : anns.
values()) {
1207 if (ann.annotations().indexes() == 0) {
1212 DomItem annAnn = ann.annotations();
1213 Q_ASSERT_X(annAnn.indexes() == 1 && annAnn.index(0).name() == u
"duplicate",
1214 "DomItem::writeOutPre",
"Unexpected annotation of annotation");
1218 ow.itemStart(*
this);
1221void DomItem::writeOut(OutWriter &ow)
1224 visitEl([
this, &ow](
auto &&
el) {
el->writeOut(*
this, ow); });
1228void DomItem::writeOutPost(OutWriter &ow)
1233DomItem DomItem::writeOutForFile(OutWriter &ow, WriteOutChecks extraChecks)
1235 ow.indentNextlines =
true;
1240 if (extraChecks & WriteOutCheck::All) {
1244 if (extraChecks & WriteOutCheck::DumpOnFailure) {
1249 obj.dump(objDumpPath);
1250 dumped.append(objDumpPath);
1254 auto dumpedDumper = [&dumped](
Sink s) {
1255 if (dumped.isEmpty())
1258 for (
auto dumpPath : dumped) {
1267 maybeDump(obj1, obj1Name);
1268 maybeDump(obj2, obj2Name);
1269 qCWarning(writeOutLog).noquote().nospace()
1270 << obj2Name <<
" writeOut of " << this->canonicalFilePath()
1271 <<
" has changes:\n"
1279 auto checkStability = [&maybeDump, &dumpedDumper, &dumped, &ow,
1281 LineWriter lw2([](
QStringView) {}, ow.lineWriter.fileName(), ow.lineWriter.options());
1283 ow2.indentNextlines =
true;
1287 DomItem fObj = this->fileObject();
1288 maybeDump(fObj, u
"initial");
1289 maybeDump(
obj, objName);
1290 qCWarning(writeOutLog).noquote().nospace()
1291 << objName <<
" non stable writeOut of " << this->canonicalFilePath() <<
":"
1298 if ((extraChecks & WriteOutCheck::UpdatedDomCompare)
1299 && !
compare(fObj, u
"initial",
copy, u
"reformatted", FieldFilter::noLocationFilter()))
1301 if (extraChecks & WriteOutCheck::UpdatedDomStable)
1302 checkStability(ow.writtenStr,
copy, u
"reformatted");
1304 & (WriteOutCheck::Reparse | WriteOutCheck::ReparseCompare
1305 | WriteOutCheck::ReparseStable)) {
1306 DomItem newEnv = environment().makeCopy().item();
1307 if (std::shared_ptr<DomEnvironment> newEnvPtr = newEnv.ownerAs<DomEnvironment>()) {
1308 auto newFilePtr = std::make_shared<QmlFile>(
1309 canonicalFilePath(), ow.writtenStr);
1310 newEnvPtr->addQmlFile(newFilePtr, AddOption::Overwrite);
1311 DomItem newFile = newEnv.copy(newFilePtr, Path());
1312 if (newFilePtr->isValid()) {
1314 & (WriteOutCheck::ReparseCompare | WriteOutCheck::ReparseStable)) {
1315 MutableDomItem newFileMutable(newFile);
1317 if ((extraChecks & WriteOutCheck::ReparseCompare)
1318 && !
compare(
copy, u
"reformatted", newFile, u
"reparsed",
1319 FieldFilter::compareNoCommentsFilter()))
1321 if ((extraChecks & WriteOutCheck::ReparseStable))
1322 checkStability(ow.writtenStr, newFile, u
"reparsed");
1325 qCWarning(writeOutLog).noquote().nospace()
1326 <<
"writeOut of " << canonicalFilePath()
1327 <<
" created invalid code:\n----------\n"
1328 << ow.writtenStr <<
"\n----------" << [&newFile](
Sink s) {
1329 newFile.iterateErrors(
1346DomItem DomItem::writeOut(
QString path,
int nBackups,
const LineWriterOptions &options,
1347 FileWriter *fw, WriteOutChecks extraChecks)
1357 LineWriter lw([&ts](QStringView s) { ts << s; },
path, options);
1359 copy = writeOutForFile(ow, extraChecks);
1363 case FileWriter::Status::ShouldWrite:
1364 case FileWriter::Status::SkippedDueToFailure:
1367 case FileWriter::Status::DidWrite:
1368 case FileWriter::Status::SkippedEqual:
1377 bool isChild =
false;
1378 if (
item.isOwningItem()) {
1383 isChild = itemOw == selfOw &&
item.pathFromOwner().dropTail() == pathFromOwner();
1388bool DomItem::hasAnnotations()
1390 bool hasAnnotations =
false;
1391 DomType iKind = internalKind();
1394 if (
const Id *myPtr = as<Id>())
1395 hasAnnotations = !myPtr->annotations.isEmpty();
1397 case DomType::PropertyDefinition:
1398 if (
const PropertyDefinition *myPtr = as<PropertyDefinition>())
1399 hasAnnotations = !myPtr->annotations.isEmpty();
1401 case DomType::MethodInfo:
1402 if (
const MethodInfo *myPtr = as<MethodInfo>())
1403 hasAnnotations = !myPtr->annotations.isEmpty();
1405 case DomType::QmlObject:
1406 if (
const QmlObject *myPtr = as<QmlObject>())
1407 hasAnnotations = !myPtr->annotations().isEmpty();
1409 case DomType::Binding:
1410 if (
const Binding *myPtr = as<Binding>())
1411 hasAnnotations = !myPtr->annotations().isEmpty();
1416 return hasAnnotations;
1436bool DomItem::visitTree(Path basePath, DomItem::ChildrenVisitor visitor, VisitOptions options,
1437 DomItem::ChildrenVisitor openingVisitor,
1438 DomItem::ChildrenVisitor closingVisitor)
1442 if (options & VisitOption::VisitSelf && !visitor(basePath, *
this,
true))
1444 if (options & VisitOption::VisitSelf && !openingVisitor(basePath, *
this,
true))
1446 auto atEnd =
qScopeGuard([closingVisitor, basePath,
this, options]() {
1447 if (options & VisitOption::VisitSelf) {
1448 closingVisitor(basePath, *
this,
true);
1451 return visitEl([
this, basePath, visitor, openingVisitor, closingVisitor, options](
auto &&
el) {
1452 return el->iterateDirectSubpathsConst(
1454 [
this, basePath, visitor, openingVisitor, closingVisitor,
1455 options](
const PathEls::PathComponent &
c, function_ref<
DomItem()> itemF) {
1457 if (!(options & VisitOption::NoPath)) {
1459 pNow = pNow.appendComponent(
c);
1462 bool directChild = isCanonicalChild(
item);
1463 if (!directChild && !(options & VisitOption::VisitAdopted))
1465 if (!directChild || !(options & VisitOption::Recurse)) {
1466 if (!visitor(pNow,
item, directChild))
1471 if (!openingVisitor(pNow,
item, directChild))
1473 closingVisitor(pNow,
item, directChild);
1475 return item.visitTree(pNow, visitor, options | VisitOption::VisitSelf,
1476 openingVisitor, closingVisitor);
1483 DomItem &derivedFromPrototype, ErrorHandler
h,
1484 QList<Path> *visitedRefs, VisitPrototypesOptions options,
1487 Path elId = prototype.canonicalPath();
1491 visitedRefs->
append(elId);
1494 if (std::shared_ptr<DomEnvironment> envPtr =
1495 derivedFromPrototype.environment().ownerAs<DomEnvironment>())
1496 if (!(envPtr->options() & DomEnvironment::Option::NoDependencies))
1497 derivedFromPrototype.myErrors()
1498 .warning(derivedFromPrototype.tr(
"could not resolve prototype %1 (%2)")
1499 .arg(current.canonicalPath().toString(),
1500 prototype.field(Fields::referredObjectPath)
1503 .withItem(derivedFromPrototype)
1510 derivedFromPrototype.myErrors()
1511 .warning(derivedFromPrototype
1512 .
tr(
"Multiple definitions found, using first only, resolving "
1513 "prototype %1 (%2): %3")
1514 .
arg(current.canonicalPath().toString(),
1515 prototype.field(Fields::referredObjectPath)
1519 .withItem(derivedFromPrototype)
1524 for (
int i = nProtos;
i != 0;) {
1526 if (proto.internalKind() == DomType::Export) {
1527 if (!(options & VisitPrototypesOption::ManualProceedToScope))
1528 proto = proto.proceedToScope(
h, visitedRefs);
1530 }
else if (proto.internalKind() == DomType::QmlObject) {
1533 derivedFromPrototype.myErrors()
1534 .warning(derivedFromPrototype.tr(
"Unexpected prototype type %1 (%2)")
1535 .arg(current.canonicalPath().toString(),
1536 prototype.field(Fields::referredObjectPath)
1539 .withItem(derivedFromPrototype)
1547bool DomItem::visitPrototypeChain(function_ref<
bool(
DomItem &)> visitor,
1548 VisitPrototypesOptions options, ErrorHandler
h,
1553 visited = &visitedLocal;
1556 visitedRefs = &refsLocal;
1557 bool shouldVisit = !(options & VisitPrototypesOption::SkipFirst);
1558 DomItem current = qmlObject();
1560 myErrors().warning(
tr(
"Prototype chain called outside object")).withItem(*this).handle(
h);
1566 current = current.proceedToScope(
h, visitedRefs);
1567 if (visited->
contains(current.id())) {
1571 if (options & VisitPrototypesOption::RevisitWarn)
1573 .warning(
tr(
"Detected multiple visit of %1 visiting prototypes of %2")
1574 .
arg(current.canonicalPath().toString(),
1580 visited->
insert(current.id());
1581 if (shouldVisit && !visitor(current))
1584 current.field(Fields::prototypes)
1585 .visitIndexes([&toDo, ¤t,
this, &
h, visitedRefs, options](
DomItem &
el) {
1586 return visitPrototypeIndex(toDo, current, *
this,
h, visitedRefs, options,
el);
1592bool DomItem::visitDirectAccessibleScopes(function_ref<
bool(
DomItem &)> visitor,
1593 VisitPrototypesOptions options, ErrorHandler
h,
1599 if (k == DomType::QmlObject)
1600 return visitPrototypeChain(visitor, options,
h, visited, visitedRefs);
1601 if (visited &&
id() != 0) {
1606 if (k == DomType::Id || k == DomType::Reference || k == DomType::Export) {
1608 DomItem v = proceedToScope(
h, visitedRefs);
1609 if (
v.internalKind() == DomType::QmlObject)
1610 return v.visitPrototypeChain(visitor, options,
h, visited, visitedRefs);
1612 if (k == DomType::Binding) {
1615 if (
v.internalKind() == DomType::QmlObject)
1616 return v.visitPrototypeChain(visitor, options,
h, visited, visitedRefs);
1618 if (k == DomType::PropertyDefinition) {
1620 DomItem t = field(Fields::type).proceedToScope(
h, visitedRefs);
1621 if (
t.internalKind() == DomType::QmlObject)
1622 return t.visitPrototypeChain(visitor, options,
h, visited, visitedRefs);
1624 if (!(options & VisitPrototypesOption::SkipFirst) && isScope() && !visitor(*
this))
1639bool DomItem::visitStaticTypePrototypeChains(function_ref<
bool(
DomItem &)> visitor,
1640 VisitPrototypesOptions options, ErrorHandler
h,
1645 visited = &visitedLocal;
1646 DomItem current = qmlObject();
1647 DomItem comp = current.component();
1648 if (comp.field(Fields::isSingleton).value().toBool(
false)
1649 && !current.visitPrototypeChain(visitor, options,
h, visited, visitedRefs))
1651 if (
DomItem attachedT = current.component().field(Fields::attachedType).field(Fields::get))
1652 if (!attachedT.visitPrototypeChain(
1653 visitor, options & ~VisitPrototypesOptions(VisitPrototypesOption::SkipFirst),
h,
1654 visited, visitedRefs))
1662bool DomItem::visitUp(function_ref<
bool(
DomItem &)> visitor)
1665 while (
p.length() > 0) {
1667 if (!visitor(current))
1677bool DomItem::visitScopeChain(function_ref<
bool(
DomItem &)> visitor, LookupOptions options,
1682 visited = &visitedLocal;
1685 visitedRefs = &visitedRefsLocal;
1688 myResolveErrors().warning(
tr(
"Called visitScopeChain outside scopes")).handle(
h);
1692 bool visitFirst = !(options & LookupOption::SkipFirstScope);
1693 bool visitCurrent = visitFirst;
1698 if (visited->
contains(current.id()))
1700 visited->
insert(current.id());
1701 if (visitCurrent && !visitor(current))
1703 visitCurrent =
true;
1704 switch (current.internalKind()) {
1705 case DomType::QmlObject: {
1706 if (!current.visitPrototypeChain(visitor, VisitPrototypesOption::SkipFirst,
h, visited,
1709 DomItem root = current.rootQmlObject();
1710 if (root && root != current) {
1714 FilterUpOptions::ReturnOuterNoSelf)) {
1718 case DomType::ScriptExpression:
1720 if (
DomItem next = current.scope(FilterUpOptions::ReturnOuterNoSelf))
1723 case DomType::QmlComponent: {
1724 if ((options & LookupOption::Strict) == 0) {
1725 if (
DomItem comp = current.field(Fields::nextComponent))
1728 if (
first && visitFirst && (options & LookupOption::VisitTopClassType)
1729 && *
this == current) {
1730 if (
DomItem attachedT = current.field(Fields::attachedType).field(Fields::get))
1733 if (
DomItem next = current.scope(FilterUpOptions::ReturnOuterNoSelf))
1736 DomItem owner = current.owner();
1737 Path pathToComponentMap = current.pathFromOwner().dropTail(2);
1738 DomItem componentMap = owner.path(pathToComponentMap);
1739 if (alreadyAddedComponentMaps.
contains(componentMap.id()))
1741 alreadyAddedComponentMaps.
insert(componentMap.id());
1743 DomItem componentList = componentMap.key(
x);
1744 for (
int i = 0;
i < componentList.indexes(); ++
i) {
1753 case DomType::QmlFile:
1755 current.field(Fields::importScope))
1759 case DomType::MethodInfo:
1761 if (
DomItem next = current.scope(FilterUpOptions::ReturnOuterNoSelf))
1764 case DomType::ImportScope:
1766 if (
auto globalC = globalScope().field(Fields::rootComponent))
1769 case DomType::JsResource:
1770 case DomType::GlobalComponent:
1772 if (
DomItem next = current.field(Fields::objects).index(0))
1775 case DomType::QmltypesComponent:
1781 .error(
tr(
"Unexpected non scope object %1 (%2) reached in visitScopeChain")
1783 current.canonicalPath().toString()))
1792QSet<QString> DomItem::localSymbolNames(LocalSymbolsTypes typeFilter)
1795 if (typeFilter == LocalSymbolsType::None)
1797 switch (internalKind()) {
1798 case DomType::QmlObject:
1799 if (typeFilter & LocalSymbolsType::Attributes) {
1800 res += propertyDefs().keys();
1801 res += bindings().keys();
1803 if (typeFilter & LocalSymbolsType::Methods) {
1804 if ((typeFilter & LocalSymbolsType::Methods) == LocalSymbolsType::Methods) {
1807 bool shouldAddSignals = bool(typeFilter & LocalSymbolsType::Signals);
1808 if (
const QmlObject *objPtr = as<QmlObject>()) {
1809 auto methods = objPtr->methods();
1811 if (
bool(
it.value().methodType == MethodInfo::MethodType::Signal)
1812 == shouldAddSignals)
1819 case DomType::ScriptExpression:
1822 case DomType::QmlComponent:
1823 if (typeFilter & LocalSymbolsType::Ids)
1826 case DomType::QmlFile:
1827 if (typeFilter & LocalSymbolsType::Components) {
1828 DomItem comps = field(Fields::components);
1829 for (
auto k : comps.
keys())
1834 case DomType::ImportScope: {
1835 const ImportScope *currentPtr = as<ImportScope>();
1836 if (typeFilter & LocalSymbolsType::Types) {
1837 if ((typeFilter & LocalSymbolsType::Types) == LocalSymbolsType::Types) {
1838 res += currentPtr->importedNames(*
this);
1840 bool qmlTypes = bool(typeFilter & LocalSymbolsType::QmlTypes);
1847 if (typeFilter & LocalSymbolsType::Namespaces) {
1848 for (
const auto &k : currentPtr->subImports().
keys())
1853 case DomType::QmltypesComponent:
1854 case DomType::JsResource:
1855 case DomType::GlobalComponent:
1856 if (typeFilter & LocalSymbolsType::Globals)
1857 res += enumerations().keys();
1859 case DomType::MethodInfo: {
1860 if (typeFilter & LocalSymbolsType::MethodParameters) {
1864 res.insert(pPtr->name);
1876bool DomItem::visitLookup1(
QString symbolName, function_ref<
bool(
DomItem &)> visitor,
1880 return visitScopeChain(
1882 return obj.visitLocalSymbolsNamed(symbolName,
1885 opts,
h, visited, visitedRefs);
1892 CppTypeInfo() =
default;
1898 uR
"(QList<(?<list>[a-zA-Z_0-9:]+) *(?<listPtr>\*?)>|QMap< *(?<mapKey>[a-zA-Z_0-9:]+) *, *(?<mapValue>[a-zA-Z_0-9:]+) *(?<mapPtr>\*?)>|(?<baseType>[a-zA-Z_0-9:]+) *(?<ptr>\*?))"));
1901 if (!
m.hasMatch()) {
1902 DomItem::myResolveErrors()
1903 .error(
tr(
"Unexpected complex CppType %1").
arg(
target))
1908 if (!
m.captured(u
"list").isEmpty()) {
1910 res.baseType =
m.captured(u
"list");
1911 res.isPointer = !
m.captured(u
"listPtr").isEmpty();
1913 if (!
m.captured(u
"mapValue").isEmpty()) {
1915 if (
m.captured(u
"mapKey") != u
"QString") {
1916 DomItem::myResolveErrors()
1917 .error(
tr(
"Unexpected complex CppType %1 (map with non QString key)")
1921 res.baseType =
m.captured(u
"mapValue");
1922 res.isPointer = !
m.captured(u
"mapPtr").isEmpty();
1928 bool isPointer =
false;
1930 bool isList =
false;
1933static bool visitForLookupType(
DomItem el, LookupType lookupType,
1934 function_ref<
bool(
DomItem &)> visitor)
1936 bool correctType =
false;
1938 switch (lookupType) {
1939 case LookupType::Binding:
1940 correctType = (iType == DomType::Binding);
1942 case LookupType::Method:
1943 correctType = (iType == DomType::MethodInfo);
1945 case LookupType::Property:
1946 correctType = (iType == DomType::PropertyDefinition || iType == DomType::Binding);
1948 case LookupType::PropertyDef:
1949 correctType = (iType == DomType::PropertyDefinition);
1951 case LookupType::Type:
1952 correctType = (iType == DomType::Export);
1964 function_ref<
bool(
DomItem &)> visitor, LookupType lookupType,
1965 ErrorHandler &errorHandler,
QList<Path> *visitedRefs)
1968 { ResolveToDo{ newIt, 1 } });
1971 while (!lookupToDos.isEmpty()) {
1972 ResolveToDo tNow = lookupToDos.takeFirst();
1973 auto vNow =
qMakePair(tNow.item.id(), tNow.pathIndex);
1975 int iSubPath = tNow.pathIndex;
1976 Q_ASSERT(iSubPath < subpath.size());
1977 QString subPathNow = subpath[iSubPath++];
1978 DomItem scope = subNow.proceedToScope();
1979 if (iSubPath < subpath.size()) {
1980 if (vNow.first != 0) {
1981 if (lookupVisited[vNow.second].contains(vNow.first))
1984 lookupVisited[vNow.second].insert(vNow.first);
1986 if (scope.internalKind() == DomType::QmlObject)
1987 scope.visitDirectAccessibleScopes(
1988 [&lookupToDos, subPathNow, iSubPath](
DomItem &
el) {
1989 return el.visitLocalSymbolsNamed(
1990 subPathNow, [&lookupToDos, iSubPath](
DomItem &subEl) {
1991 lookupToDos.append({ subEl, iSubPath });
1995 VisitPrototypesOption::Normal, errorHandler, &(lookupVisited[vNow.second]),
1998 bool cont = scope.visitDirectAccessibleScopes(
1999 [&visitor, subPathNow, lookupType](
DomItem &
el) ->
bool {
2000 if (lookupType == LookupType::Symbol)
2001 return el.visitLocalSymbolsNamed(subPathNow, visitor);
2003 return el.visitLocalSymbolsNamed(
2004 subPathNow, [lookupType, &visitor](
DomItem &
el) ->
bool {
2005 return visitForLookupType(
el, lookupType, visitor);
2008 VisitPrototypesOption::Normal, errorHandler, &(lookupVisited[vNow.second]),
2018 LookupType lookupType, LookupOptions opts, ErrorHandler errorHandler,
2023 switch (lookupType) {
2024 case LookupType::Binding:
2025 case LookupType::Method:
2026 case LookupType::Property:
2027 case LookupType::PropertyDef:
2028 case LookupType::Symbol:
2029 case LookupType::Type: {
2031 if (subpath.size() == 1) {
2032 return visitLookup1(subpath.first(), visitor, opts, errorHandler, visited, visitedRefs);
2034 return visitLookup1(
2036 [&subpath, visitor, lookupType, &errorHandler,
2037 visitedRefs](
DomItem &newIt) ->
bool {
2038 return visitQualifiedNameLookup(newIt, subpath, visitor, lookupType,
2039 errorHandler, visitedRefs);
2041 opts, errorHandler, visited, visitedRefs);
2045 case LookupType::CppType: {
2046 QString baseTarget = CppTypeInfo::fromString(
target, errorHandler).baseType;
2047 DomItem localQmltypes = owner();
2048 while (localQmltypes && localQmltypes.internalKind() != DomType::QmltypesFile) {
2049 localQmltypes = localQmltypes.containingObject();
2050 localQmltypes = localQmltypes.owner();
2052 if (localQmltypes) {
2053 if (
DomItem localTypes = localQmltypes.field(Fields::components).key(baseTarget)) {
2054 bool cont = localTypes.visitIndexes([&visitor](
DomItem &els) {
2055 return els.visitIndexes([&visitor](
DomItem &
el) {
2057 return visitor(
obj);
2065 DomItem qmltypes = environment().field(Fields::qmltypesFileWithPath);
2066 return qmltypes.visitKeys([baseTarget, &visitor](
QString,
DomItem &els) {
2068 els.field(Fields::currentItem).field(Fields::components).
key(baseTarget);
2069 return comps.visitIndexes([&visitor](
DomItem &
el) {
2071 return visitor(
obj);
2095 switch (current.internalKind()) {
2096 case DomType::Reference: {
2097 Path currentPath = current.canonicalPath();
2098 current = current.get(
h, visitedRefs);
2101 case DomType::Export:
2102 current = current.field(Fields::type);
2105 current = current.field(Fields::referredObject);
2108 return current.scope();
2116 ErrorHandler errorHandler)
2125 type, opts, errorHandler);
2130 ErrorHandler errorHandler)
2139 type, opts, errorHandler);
2145 return visitEl([](
auto &&
b) {
return b->id(); });
2148Path DomItem::pathFromOwner()
2150 return visitEl([
this](
auto &&
e) {
return e->pathFromOwner(*
this); });
2153QString DomItem::canonicalFilePath()
2155 return visitEl([
this](
auto &&
e) {
return e->canonicalFilePath(*
this); });
2158DomItem DomItem::fileLocationsTree()
2160 if (
DomItem l = field(Fields::fileLocationsTree))
2162 auto res = FileLocations::findAttachedInfo(*
this, AttachedInfo::FindOption::SetFoundTreePath);
2163 if (
res &&
res.foundTreePath.value()) {
2164 return copy(
res.foundTree,
res.foundTreePath.value());
2169DomItem DomItem::fileLocations()
2171 return fileLocationsTree().field(Fields::infoItem);
2174MutableDomItem DomItem::makeCopy(DomItem::CopyOption
option)
2176 if (m_kind == DomType::Empty)
2177 return MutableDomItem();
2179 if (
option == CopyOption::EnvDisconnected) {
2181 [
this, &
o](
auto &&
el) {
2182 auto copyPtr =
el->makeCopy(
o);
2183 return DomItem(m_top, copyPtr, m_ownerPath, copyPtr.get());
2186 return MutableDomItem(newItem.path(pathFromOwner()));
2189 std::shared_ptr<DomEnvironment> newEnvPtr;
2190 if (std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>()) {
2191 newEnvPtr = std::make_shared<DomEnvironment>(
2192 envPtr, envPtr->loadPaths(), envPtr->options());
2193 DomBase *eBase = envPtr.get();
2194 if (std::holds_alternative<DomEnvironment *>(m_element) && eBase
2195 && std::get<DomEnvironment *>(m_element) == eBase)
2196 return MutableDomItem(
DomItem(newEnvPtr));
2197 }
else if (std::shared_ptr<DomUniverse> univPtr =
top().ownerAs<DomUniverse>()) {
2198 newEnvPtr = std::make_shared<DomEnvironment>(
2200 DomEnvironment::Option::SingleThreaded | DomEnvironment::Option::NoDependencies,
2207 [
this, newEnvPtr, &
o](
auto &&
el) {
2208 auto copyPtr =
el->makeCopy(
o);
2209 return DomItem(newEnvPtr, copyPtr, m_ownerPath, copyPtr.get());
2213 switch (
o.internalKind()) {
2214 case DomType::QmlDirectory:
2215 newEnvPtr->addQmlDirectory(newItem.ownerAs<QmlDirectory>(), AddOption::Overwrite);
2217 case DomType::JsFile:
2218 newEnvPtr->addJsFile(newItem.ownerAs<JsFile>(), AddOption::Overwrite);
2220 case DomType::QmlFile:
2221 newEnvPtr->addQmlFile(newItem.ownerAs<QmlFile>(), AddOption::Overwrite);
2223 case DomType::QmltypesFile:
2224 newEnvPtr->addQmltypesFile(newItem.ownerAs<QmltypesFile>(), AddOption::Overwrite);
2226 case DomType::GlobalScope: {
2227 newEnvPtr->addGlobalScope(newItem.ownerAs<GlobalScope>(), AddOption::Overwrite);
2229 case DomType::ModuleIndex:
2230 case DomType::MockOwner:
2231 case DomType::ScriptExpression:
2232 case DomType::AstComments:
2233 case DomType::LoadInfo:
2234 case DomType::AttachedInfo:
2235 case DomType::DomEnvironment:
2236 case DomType::DomUniverse:
2237 qCWarning(domLog) <<
"DomItem::makeCopy " << internalKindStr()
2238 <<
" does not support binding to environment";
2240 return MutableDomItem();
2242 qCWarning(domLog) <<
"DomItem::makeCopy(" << internalKindStr()
2243 <<
") is not an known OwningItem";
2245 return MutableDomItem();
2248 Q_ASSERT(newEnv.path(
o.canonicalPath()).m_owner == newItem.m_owner);
2249 return MutableDomItem(newItem.path(pathFromOwner()));
2252bool DomItem::commitToBase(std::shared_ptr<DomEnvironment> validEnvPtr)
2255 if (std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>()) {
2256 return envPtr->commitToBase(env, validEnvPtr);
2261bool DomItem::visitLocalSymbolsNamed(
QString name, function_ref<
bool(
DomItem &)> visitor)
2270 switch (internalKind()) {
2271 case DomType::QmlObject:
2272 f = field(Fields::propertyDefs);
2274 if (!
v.visitIndexes(visitor))
2276 f = field(Fields::bindings);
2278 if (!
v.visitIndexes(visitor))
2280 f = field(Fields::methods);
2282 if (!
v.visitIndexes(visitor))
2285 case DomType::ScriptExpression:
2288 case DomType::QmlComponent:
2289 f = field(Fields::ids);
2291 if (!
v.visitIndexes(visitor))
2294 case DomType::JsResource:
2295 case DomType::GlobalComponent:
2296 case DomType::QmltypesComponent:
2297 f = field(Fields::enumerations);
2299 if (!
v.visitIndexes(visitor))
2302 case DomType::MethodInfo: {
2305 const MethodParameter *pPtr = p.as<MethodParameter>();
2306 if (pPtr->name == name && !visitor(p))
2313 case DomType::QmlFile: {
2314 f = field(Fields::components);
2316 if (!
v.visitIndexes(visitor))
2320 case DomType::ImportScope: {
2321 f = field(Fields::imported);
2323 if (!
v.visitIndexes(visitor))
2325 f = field(Fields::qualifiedImports);
2327 if (
v && !visitor(
v))
2340 if (internalKind() == DomType::Map)
2342 return field(cName);
2347 if (internalKind() == DomType::Map)
2349 return field(cName);
2359 return base()->value();
2362void DomItem::dumpPtr(Sink
sink)
2364 sink(u
"DomItem{ topPtr:");
2366 sink(u
", ownerPtr:");
2368 sink(u
", ownerPath:");
2369 m_ownerPath.dump(
sink);
2375void DomItem::dump(Sink
s,
int indent,
2378 visitEl([
this,
s, indent,
filter](
auto &&
e) {
e->dump(*
this,
s, indent,
filter); });
2384 int nBackups,
int indent, FileWriter *fw)
2392 this->dump([&ts](QStringView s) { ts << s; }, indent,
filter);
2396 case FileWriter::Status::ShouldWrite:
2397 case FileWriter::Status::SkippedDueToFailure:
2400 case FileWriter::Status::DidWrite:
2401 case FileWriter::Status::SkippedEqual:
2412int DomItem::derivedFrom()
2415 return std::visit([](
auto &&ow) {
return ow->derivedFrom(); }, *m_owner);
2419int DomItem::revision()
2422 return std::visit([](
auto &&ow) {
return ow->revision(); }, *m_owner);
2430 return std::visit([](
auto &&ow) {
return ow->createdAt(); }, *m_owner);
2438 return std::visit([](
auto &&ow) {
return ow->frozenAt(); }, *m_owner);
2446 return std::visit([](
auto &&ow) {
return ow->lastDataUpdateAt(); }, *m_owner);
2456 [
this, &myOwner, &msg](
auto &&ow) { ow->addError(myOwner, msg.withItem(*
this)); },
2468void DomItem::clearErrors(ErrorGroups
groups,
bool iterate)
2471 std::visit([&
groups](
auto &&ow) { ow->clearErrors(
groups); }, *m_owner);
2480bool DomItem::iterateErrors(function_ref<
bool(
DomItem,
ErrorMessage)> visitor,
bool iterate,
2485 if (!std::visit([&ow, visitor,
2486 inPath](
auto &&
el) {
return el->iterateErrors(ow, visitor, inPath); },
2489 if (iterate && !iterateSubOwners([inPath, visitor](
DomItem &
i) {
2490 return i.iterateErrors(visitor,
true, inPath);
2497bool DomItem::iterateSubOwners(function_ref<
bool(
DomItem &)> visitor)
2501 return std::visit([&ow, visitor](
auto &&
o) {
return o->iterateSubOwners(ow, visitor); },
2507bool DomItem::iterateDirectSubpaths(DirectVisitor
v)
2509 return visitMutableEl(
2510 [
this,
v](
auto &&
el)
mutable {
return el->iterateDirectSubpaths(*
this,
v); });
2516 List::fromQList<Path>(pathFromOwner().appendComponent(
c),
paths,
2518 return list.subReferenceItem(
p,
el);
2522DomItem DomItem::subReferenceItem(
const PathEls::PathComponent &
c, Path referencedObject)
2525 return DomItem(m_top, m_owner, m_ownerPath,
Reference(referencedObject, Path(
c)));
2527 return DomItem(m_top, m_owner, m_ownerPath,
2528 Reference(referencedObject, pathFromOwner().appendComponent(
c)));
2532shared_ptr<DomTop> DomItem::topPtr()
2535 return std::visit([](
auto &&
el) -> shared_ptr<DomTop> {
return el; }, *m_top);
2539shared_ptr<OwningItem> DomItem::owningItemPtr()
2542 return std::visit([](
auto &&
el) -> shared_ptr<OwningItem> {
return el; }, *m_owner);
2550const DomBase *DomItem::base()
2552 return visitEl([](
auto &&
el) -> DomBase * {
return el->domBase(); });
2559DomBase *DomItem::mutableBase()
2561 return visitMutableEl([](
auto &&
el) -> DomBase * {
return el->domBase(); });
2565 DomItem(envPtr, envPtr, Path(), envPtr.
get())
2570 DomItem(universePtr, universePtr, Path(), universePtr.
get())
2574void DomItem::loadFile(
const FileToLoad &
file, DomTop::Callback callback, LoadOptions loadOptions,
2578 if (topEl.internalKind() == DomType::DomEnvironment
2579 || topEl.internalKind() == DomType::DomUniverse) {
2580 if (
auto univ = topEl.ownerAs<DomUniverse>())
2581 univ->loadFile(*
this,
file, callback, loadOptions,
fileType);
2582 else if (
auto env = topEl.ownerAs<DomEnvironment>()) {
2583 if (env->options() & DomEnvironment::Option::NoDependencies)
2584 env->loadFile(topEl,
file, callback, DomTop::Callback(), DomTop::Callback(),
2587 env->loadFile(topEl,
file, DomTop::Callback(), DomTop::Callback(), callback,
2590 Q_ASSERT(
false &&
"expected either DomUniverse or DomEnvironment cast to succeed");
2592 addError(myErrors().warning(
tr(
"loadFile called without DomEnvironment or DomUniverse.")));
2593 callback(Paths::qmlFileInfoPath(
file.canonicalPath()), DomItem::empty, DomItem::empty);
2599 ErrorHandler errorHandler)
2602 if (topEl.internalKind() == DomType::DomEnvironment) {
2603 if (
auto envPtr = topEl.ownerAs<DomEnvironment>()) {
2604 if (envPtr->options() & DomEnvironment::Option::NoDependencies)
2605 envPtr->loadModuleDependency(topEl, uri, version, callback,
nullptr, errorHandler);
2607 envPtr->loadModuleDependency(topEl, uri, version,
nullptr, callback, errorHandler);
2609 Q_ASSERT(
false &&
"loadDependency expected the DomEnvironment cast to succeed");
2611 addError(myErrors().warning(
tr(
"loadModuleDependency called without DomEnvironment.")));
2612 callback(Paths::moduleScopePath(uri, version), DomItem::empty, DomItem::empty);
2616void DomItem::loadBuiltins(std::function<
void(Path,
DomItem &,
DomItem &)> callback, ErrorHandler
h)
2619 if (std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>())
2620 envPtr->loadBuiltins(env, callback,
h);
2622 myErrors().error(
tr(
"Cannot load builtins without DomEnvironment")).handle(
h);
2625void DomItem::loadPendingDependencies()
2628 if (std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>())
2629 envPtr->loadPendingDependencies(env);
2631 myErrors().error(
tr(
"Called loadPendingDependencies without environment")).handle();
2654 FileToLoad::fromMemory(env.ownerAs<DomEnvironment>(),
QString(), code),
2655 [&tFile](Path,
const DomItem &,
const DomItem &newIt) { tFile = newIt; },
2656 LoadOption::DefaultLoad, std::make_optional(
fileType));
2657 env.loadPendingDependencies();
2658 return tFile.fileObject();
2664Path Empty::pathFromOwner(
DomItem &)
const
2669Path Empty::canonicalPath(
DomItem &)
const
2674bool Empty::iterateDirectSubpaths(
DomItem &, DirectVisitor)
2684void Empty::dump(
DomItem &, Sink
s,
int,
2685 function_ref<
bool(
DomItem &,
const PathEls::PathComponent &,
DomItem &)>)
const
2690Map::Map(Path pathFromOwner, Map::LookupFunction lookup, Keys
keys,
QString targetType)
2691 : DomElement(pathFromOwner), m_lookup(lookup), m_keys(
keys), m_targetType(targetType)
2699bool Map::iterateDirectSubpaths(
DomItem &self, DirectVisitor visitor)
2703 std::sort(ksList.begin(), ksList.end());
2705 if (!visitor(PathEls::Key(k), [&
self,
this, k]() {
return key(
self, k); }))
2713 return m_keys(
self);
2728 case DomKind::Object:
2729 sink(u
"{ \"~type~\":");
2733 case DomKind::Value:
2738 else if (
v.isBool())
2743 else if (
v.isDouble())
2744 if (
value().isInteger())
2753 case DomKind::Empty:
2762 case DomKind::ScriptElement:
2769 case DomKind::Object:
2773 case DomKind::Value:
2775 case DomKind::Empty:
2785 case DomKind::ScriptElement:
2791 self.iterateDirectSubpaths(
2792 [&comma, &idx, dK,
sink, indent, &self,
filter](
const PathEls::PathComponent &
c,
2793 function_ref<
DomItem()> itemF) {
2802 case Path::Kind::Field:
2804 if (dK != DomKind::Object)
2805 sink(u
"UNEXPECTED ENTRY ERROR:");
2809 case Path::Kind::Key:
2811 if (dK != DomKind::Map)
2812 sink(u
"UNEXPECTED ENTRY ERROR:");
2816 case Path::Kind::Index:
2818 if (dK != DomKind::List)
2819 sink(u
"UNEXPECTED ENTRY ERROR:");
2820 else if (idx++ !=
c.index())
2821 sink(u
"OUT OF ORDER ARRAY:");
2825 sink(u
"UNEXPECTED PATH KIND ERROR (ignored)");
2828 if (
self.isCanonicalChild(
i)) {
2831 sink(uR
"({ "~type~": "Reference", "immediate": true, "referredObjectPath":")");
2841List::List(Path pathFromOwner, List::LookupFunction lookup, List::Length
length,
2842 List::IteratorFunction iterator,
QString elType):
2843 DomElement(pathFromOwner), m_lookup(lookup), m_length(
length), m_iterator(
iterator),
2858 const_cast<List *
>(
this)->iterateDirectSubpaths(
2861 function_ref<
DomItem()> itemF) {
2876bool List::iterateDirectSubpaths(
DomItem &self, DirectVisitor visitor)
2879 return m_iterator(self, [visitor](index_type
i, function_ref<
DomItem()> itemF) {
2880 return visitor(PathEls::Index(
i), itemF);
2884 for (index_type
i = 0;
i <
len; ++
i) {
2885 if (!visitor(PathEls::Index(
i), [
this, &self,
i]() {
return index(self,
i); }))
2893 return m_length(self);
2898 return m_lookup(self,
index);
2901void List::writeOut(
DomItem &self, OutWriter &ow,
bool compact)
const
2903 ow.writeRegion(u
"leftSquareBrace", u
"[");
2904 int baseIndent = ow.increaseIndent(1);
2906 const_cast<List *
>(
this)->iterateDirectSubpaths(
2908 [&ow, &
first, compact](
const PathEls::PathComponent &, function_ref<
DomItem()> elF) {
2912 ow.write(u
", ", LineWriter::TextAddType::Extra);
2914 ow.ensureNewline(1);
2919 if (!compact && !
first)
2921 ow.decreaseIndent(1, baseIndent);
2922 ow.writeRegion(u
"rightSquareBrace", u
"]");
2925DomElement::DomElement(Path pathFromOwner) : m_pathFromOwner(pathFromOwner) { }
2927Path DomElement::pathFromOwner(
DomItem &)
const
2929 Q_ASSERT(m_pathFromOwner &&
"uninitialized DomElement");
2930 return m_pathFromOwner;
2933Path DomElement::canonicalPath(
DomItem &self)
const
2935 Q_ASSERT(m_pathFromOwner &&
"uninitialized DomElement");
2936 return self.owner().canonicalPath().path(m_pathFromOwner);
2941 Q_ASSERT(m_pathFromOwner &&
"uninitialized DomElement");
2942 return DomBase::containingObject(self);
2945void DomElement::updatePathFromOwner(Path newPath)
2948 m_pathFromOwner = newPath;
2951bool Reference::shouldCache()
const
2953 for (Path
p : referredObjectPath) {
2954 switch (
p.headKind()) {
2955 case Path::Kind::Current:
2956 switch (
p.headCurrent()) {
2957 case PathCurrent::Lookup:
2958 case PathCurrent::LookupDynamic:
2959 case PathCurrent::LookupStrict:
2960 case PathCurrent::ObjChain:
2961 case PathCurrent::ScopeChain:
2967 case Path::Kind::Empty:
2968 case Path::Kind::Any:
2969 case Path::Kind::Filter:
2978Reference::Reference(Path referredObject, Path pathFromOwner,
const SourceLocation &)
2979 : DomElement(pathFromOwner), referredObjectPath(referredObject)
2988bool Reference::iterateDirectSubpaths(
DomItem &self, DirectVisitor visitor)
2991 cont = cont &&
self.dvValueLazyField(visitor, Fields::referredObjectPath, [
this]() {
2992 return referredObjectPath.toString();
2995 &&
self.dvItemField(visitor, Fields::get, [
this, &self]() {
return this->
get(self); });
3001 if (Fields::referredObjectPath ==
name)
3002 return self.subDataItemField(Fields::referredObjectPath, referredObjectPath.toString());
3003 if (Fields::get ==
name)
3026 if (referredObjectPath) {
3030 if (shouldCache()) {
3031 env =
self.environment();
3033 selfPath =
self.canonicalPath();
3034 RefCacheEntry cached = RefCacheEntry::forPath(self, selfPath);
3035 switch (cached.cached) {
3036 case RefCacheEntry::Cached::None:
3038 case RefCacheEntry::Cached::First:
3039 case RefCacheEntry::Cached::All:
3040 if (!cached.canonicalPaths.isEmpty())
3041 cachedPath = cached.canonicalPaths.first();
3047 res = env.path(cachedPath);
3049 qCWarning(refLog) <<
"referenceCache outdated, reference at " << selfPath
3050 <<
" leads to invalid path " << cachedPath;
3063 h, ResolveOption::None, referredObjectPath,
3064 (visitedRefs ? visitedRefs : &visitedRefsLocal));
3066 RefCacheEntry::addForPath(
3067 env, selfPath, RefCacheEntry { RefCacheEntry::Cached::First, { cachedPath } });
3075 if (referredObjectPath) {
3079 if (shouldCache()) {
3081 env =
self.environment();
3082 RefCacheEntry cached = RefCacheEntry::forPath(env, selfPath);
3083 switch (cached.cached) {
3084 case RefCacheEntry::Cached::None:
3085 case RefCacheEntry::Cached::First:
3087 case RefCacheEntry::Cached::All:
3088 cachedPaths += cached.canonicalPaths;
3094 bool outdated =
false;
3095 for (Path
p : cachedPaths) {
3099 qCWarning(refLog) <<
"referenceCache outdated, reference at " << selfPath
3100 <<
" leads to invalid path " <<
p;
3118 h, ResolveOption::None, referredObjectPath, visitedRefs);
3123 canonicalPaths.
append(
i.canonicalPath());
3126 <<
"getAll of reference at " << selfPath <<
" visits empty items.";
3128 RefCacheEntry::addForPath(env, selfPath,
3129 RefCacheEntry { RefCacheEntry::Cached::All, canonicalPaths });
3152OwningItem::OwningItem(
int derivedFrom)
3153 : m_derivedFrom(derivedFrom),
3154 m_revision(nextRevision()),
3155 m_createdAt(
QDateTime::currentDateTimeUtc()),
3156 m_lastDataUpdateAt(m_createdAt),
3160OwningItem::OwningItem(
int derivedFrom,
QDateTime lastDataUpdateAt)
3161 : m_derivedFrom(derivedFrom),
3162 m_revision(nextRevision()),
3163 m_createdAt(
QDateTime::currentDateTimeUtc()),
3164 m_lastDataUpdateAt(lastDataUpdateAt),
3168OwningItem::OwningItem(
const OwningItem &
o)
3169 : m_derivedFrom(
o.revision()),
3170 m_revision(nextRevision()),
3171 m_createdAt(
QDateTime::currentDateTimeUtc()),
3172 m_lastDataUpdateAt(
o.lastDataUpdateAt()),
3178 my_errors =
o.m_errors;
3183 m_errors = my_errors;
3188int OwningItem::nextRevision()
3194bool OwningItem::iterateDirectSubpaths(
DomItem &self, DirectVisitor visitor)
3197 cont = cont &&
self.dvItemField(visitor, Fields::errors, [&self,
this]() {
3200 self.pathFromOwner().field(Fields::errors),
3202 auto it = myErrors.find(Path::fromString(key));
3203 if (it != myErrors.end())
3204 return map.subDataItem(PathEls::Key(key), it->toCbor(),
3205 ConstantData::Options::FirstMapIsFields);
3211 auto it = myErrors.keyBegin();
3212 auto end = myErrors.keyEnd();
3214 res.insert(it++->toString());
3225 if (
s.pathFromSource) {
3226 if (!
s.pathToSource)
3228 return self.path(
s.pathToSource);
3233int OwningItem::derivedFrom()
const
3235 return m_derivedFrom;
3238int OwningItem::revision()
const
3243bool OwningItem::frozen()
const
3245 return m_frozenAt > m_createdAt;
3248bool OwningItem::freeze()
3252 if (m_frozenAt <= m_createdAt)
3253 m_frozenAt = m_createdAt.addSecs(1);
3264QDateTime OwningItem::lastDataUpdateAt()
const
3266 return m_lastDataUpdateAt;
3274void OwningItem::refreshedDataAt(
QDateTime tNew)
3276 if (m_lastDataUpdateAt < tNew)
3277 m_lastDataUpdateAt = tNew;
3291 m_errors.insert(msg.path, msg);
3294void OwningItem::clearErrors(ErrorGroups
groups)
3298 while (
it != m_errors.
end()) {
3312 myErrors = m_errors;
3315 auto end = myErrors.
end();
3316 while (
it !=
end &&
it.key().mid(0, inPath.length()) == inPath) {
3317 if (!visitor(self, *
it++))
3323bool OwningItem::iterateSubOwners(
DomItem &self, function_ref<
bool(
DomItem &owner)> visitor)
3325 return self.iterateDirectSubpaths(
3326 [&self, visitor](
const PathEls::PathComponent &, function_ref<
DomItem()> iF) {
3328 if (
i.owningItemPtr() !=
self.owningItemPtr()) {
3330 if (container.id() ==
self.id())
3341 if (o1.m_kind != o2.m_kind)
3343 return o1.visitMutableEl([&o1, &o2](
auto &&el1) {
3344 auto &&
el2 = std::get<std::decay_t<
decltype(el1)>>(o2.m_element);
3345 auto id1 = el1->id();
3346 auto id2 =
el2->id();
3351 if (o1.m_owner != o2.m_owner)
3353 Path
p1 = el1->pathFromOwner(o1);
3354 Path
p2 =
el2->pathFromOwner(o2);
3363 MutableDomItem
self;
3367MutableDomItem MutableDomItem::addPrototypePath(Path prototypePath)
3369 if (QmlObject *
el = mutableAs<QmlObject>()) {
3370 return path(
el->addPrototypePath(prototypePath));
3372 Q_ASSERT(
false &&
"setPrototypePath on non qml scope");
3377MutableDomItem MutableDomItem::setNextScopePath(Path nextScopePath)
3379 if (QmlObject *
el = mutableAs<QmlObject>()) {
3380 el->setNextScopePath(nextScopePath);
3381 return field(Fields::nextScope);
3383 Q_ASSERT(
false &&
"setNextScopePath on non qml scope");
3390 if (QmlObject *
el = mutableAs<QmlObject>()) {
3391 el->setPropertyDefs(propertyDefs);
3392 return field(Fields::propertyDefs);
3394 Q_ASSERT(
false &&
"setPropertyDefs on non qml scope");
3401 if (QmlObject *
el = mutableAs<QmlObject>()) {
3402 el->setBindings(bindings);
3403 return field(Fields::bindings);
3405 Q_ASSERT(
false &&
"setBindings on non qml scope");
3412 if (QmlObject *
el = mutableAs<QmlObject>())
3413 el->setMethods(functionDefs);
3415 Q_ASSERT(
false &&
"setMethods on non qml scope");
3421 if (QmlObject *
el = mutableAs<QmlObject>()) {
3422 el->setChildren(children);
3423 return field(Fields::children);
3425 Q_ASSERT(
false &&
"setChildren on non qml scope");
3431 if (QmlObject *
el = mutableAs<QmlObject>())
3432 el->setAnnotations(annotations);
3433 else if (
Binding *
el = mutableAs<Binding>()) {
3434 el->setAnnotations(annotations);
3435 el->updatePathFromOwner(pathFromOwner());
3436 }
else if (PropertyDefinition *
el = mutableAs<PropertyDefinition>()) {
3437 el->annotations = annotations;
3438 el->updatePathFromOwner(pathFromOwner());
3439 }
else if (MethodInfo *
el = mutableAs<MethodInfo>()) {
3440 el->annotations = annotations;
3441 el->updatePathFromOwner(pathFromOwner());
3442 }
else if (EnumDecl *
el = mutableAs<EnumDecl>()) {
3443 el->setAnnotations(annotations);
3444 el->updatePathFromOwner(pathFromOwner());
3445 }
else if (!annotations.
isEmpty()) {
3446 Q_ASSERT(
false &&
"setAnnotations on element not supporting them");
3448 return field(Fields::annotations);
3450MutableDomItem MutableDomItem::setScript(std::shared_ptr<ScriptExpression> exp)
3452 switch (internalKind()) {
3453 case DomType::Binding:
3454 if (
Binding *
b = mutableAs<Binding>()) {
3455 b->setValue(std::make_unique<BindingValue>(exp));
3456 return field(Fields::value);
3459 case DomType::MethodInfo:
3460 if (MethodInfo *
m = mutableAs<MethodInfo>()) {
3462 return field(Fields::body);
3465 case DomType::MethodParameter:
3466 if (MethodParameter *
p = mutableAs<MethodParameter>()) {
3467 p->defaultValue = exp;
3468 return field(Fields::body);
3471 case DomType::ScriptExpression:
3472 return container().setScript(exp);
3474 qCWarning(domLog) <<
"setScript called on" << internalKindStr();
3476 "setScript supported only on Binding, MethodInfo, MethodParameter, and "
3477 "ScriptExpression contained in them");
3479 return MutableDomItem();
3482MutableDomItem MutableDomItem::setCode(
QString code)
3485 switch (
it.internalKind()) {
3486 case DomType::Binding:
3487 if (
Binding *
b = mutableAs<Binding>()) {
3488 auto exp = std::make_shared<ScriptExpression>(
3489 code, ScriptExpression::ExpressionType::BindingExpression);
3490 b->setValue(std::make_unique<BindingValue>(exp));
3491 return field(Fields::value);
3494 case DomType::MethodInfo:
3495 if (MethodInfo *
m = mutableAs<MethodInfo>()) {
3498 m->body = std::make_shared<ScriptExpression>(
3499 code, ScriptExpression::ExpressionType::FunctionBody, 0, pre, post);
3500 return field(Fields::body);
3503 case DomType::MethodParameter:
3504 if (MethodParameter *
p = mutableAs<MethodParameter>()) {
3505 p->defaultValue = std::make_shared<ScriptExpression>(
3506 code, ScriptExpression::ExpressionType::ArgInitializer);
3507 return field(Fields::defaultValue);
3510 case DomType::ScriptExpression:
3511 if (std::shared_ptr<ScriptExpression> exp = ownerAs<ScriptExpression>()) {
3512 std::shared_ptr<ScriptExpression> newExp = exp->copyWithUpdatedCode(
it, code);
3513 return container().setScript(newExp);
3517 qCWarning(domLog) <<
"setCode called on" << internalKindStr();
3520 "setCode supported only on Binding, MethodInfo, MethodParameter, ScriptExpression");
3522 return MutableDomItem();
3525MutableDomItem MutableDomItem::addPropertyDef(PropertyDefinition propertyDef, AddOption
option)
3527 if (QmlObject *
el = mutableAs<QmlObject>())
3528 return el->addPropertyDef(*
this, propertyDef,
option);
3530 Q_ASSERT(
false &&
"addPropertyDef on non qml scope");
3531 return MutableDomItem();
3534MutableDomItem MutableDomItem::addBinding(
Binding binding, AddOption
option)
3536 if (QmlObject *
el = mutableAs<QmlObject>())
3537 return el->addBinding(*
this, binding,
option);
3539 Q_ASSERT(
false &&
"addBinding on non qml scope");
3540 return MutableDomItem();
3543MutableDomItem MutableDomItem::addMethod(MethodInfo functionDef, AddOption
option)
3545 if (QmlObject *
el = mutableAs<QmlObject>())
3546 return el->addMethod(*
this, functionDef,
option);
3548 Q_ASSERT(
false &&
"addMethod on non qml scope");
3549 return MutableDomItem();
3552MutableDomItem MutableDomItem::addChild(QmlObject
child)
3554 if (QmlObject *
el = mutableAs<QmlObject>()) {
3555 return el->addChild(*
this,
child);
3556 }
else if (QmlComponent *
el = mutableAs<QmlComponent>()) {
3558 return owner().path(
p);
3560 Q_ASSERT(
false &&
"addChild on non qml scope");
3562 return MutableDomItem();
3565MutableDomItem MutableDomItem::addAnnotation(QmlObject annotation)
3568 switch (internalKind()) {
3569 case DomType::QmlObject: {
3571 res =
el->addAnnotation(annotation);
3573 case DomType::Binding: {
3576 res =
el->addAnnotation(m_pathFromOwner, annotation);
3578 case DomType::PropertyDefinition: {
3580 res =
el->addAnnotation(m_pathFromOwner, annotation);
3582 case DomType::MethodInfo: {
3584 res =
el->addAnnotation(m_pathFromOwner, annotation);
3587 Id *
el = mutableAs<Id>();
3588 res =
el->addAnnotation(m_pathFromOwner, annotation);
3591 Q_ASSERT(
false &&
"addAnnotation on element not supporting them");
3593 return MutableDomItem(owner().
item(),
res);
3596MutableDomItem MutableDomItem::addPreComment(
const Comment &comment,
QString regionName)
3599 MutableDomItem rC = field(Fields::comments);
3600 if (
auto rcPtr = rC.mutableAs<RegionComments>()) {
3601 auto &preList = rcPtr->regionComments[regionName].preComments;
3602 idx = preList.size();
3603 preList.append(comment);
3604 MutableDomItem
res =
path(Path::Field(Fields::comments)
3605 .field(Fields::regionComments)
3607 .field(Fields::preComments)
3612 return MutableDomItem();
3615MutableDomItem MutableDomItem::addPostComment(
const Comment &comment,
QString regionName)
3618 MutableDomItem rC = field(Fields::comments);
3619 if (
auto rcPtr = rC.mutableAs<RegionComments>()) {
3620 auto &postList = rcPtr->regionComments[regionName].postComments;
3621 idx = postList.size();
3622 postList.append(comment);
3623 MutableDomItem
res =
path(Path::Field(Fields::comments)
3624 .field(Fields::regionComments)
3626 .field(Fields::postComments)
3631 return MutableDomItem();
3642 MutableDomItem cc(
c);
3644 <<
", " << cc.canonicalPath().toString() <<
")";
3647bool ListPBase::iterateDirectSubpaths(
DomItem &self, DirectVisitor
v)
3650 for (index_type
i = 0;
i <
len; ++
i) {
3651 if (!
v(PathEls::Index(
i), [
this, &self,
i] {
return this->
index(self,
i); }))
3657void ListPBase::writeOut(
DomItem &self, OutWriter &ow,
bool compact)
const
3659 ow.writeRegion(u
"leftSquareBrace", u
"[");
3660 int baseIndent = ow.increaseIndent(1);
3663 for (index_type
i = 0;
i <
len; ++
i) {
3667 ow.write(u
", ", LineWriter::TextAddType::Extra);
3669 ow.ensureNewline(1);
3673 if (!compact && !
first)
3675 ow.decreaseIndent(1, baseIndent);
3676 ow.writeRegion(u
"rightSquareBrace", u
"]");
3679std::optional<QQmlJSScope::Ptr> ScriptElement::semanticScope()
3693#include "moc_qqmldomitem_p.cpp"
static JNINativeMethod methods[]
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
\inmodule QtCore\reentrant
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
static QDateTime currentDateTimeUtc()
static QString tempPath()
Returns the absolute canonical path of the system's temporary directory.
QString filePath(const QString &fileName) const
Returns the path name of a file in the directory.
\inmodule QtCore \reentrant
QString baseName() const
Returns the base name of the file without the path.
QString canonicalFilePath() const
Returns the canonical path including the file name, i.e.
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
static QJsonDocument fromVariant(const QVariant &variant)
Creates a QJsonDocument from the QVariant variant.
QByteArray toJson(JsonFormat format=Indented) const
\inmodule QtCore\reentrant
bool isEmpty() const noexcept
void append(parameter_type t)
const_iterator cend() const
const_iterator cbegin() const
iterator lowerBound(const Key &key)
ConstantData(Path pathFromOwner, QCborValue value, Options options=Options::MapIsMap)
virtual DomType kind() const =0
virtual DomItem containingObject(DomItem &self) const
virtual QString canonicalFilePath(DomItem &self) const
virtual void writeOut(DomItem &self, OutWriter &lw) const
Class that represent a filter on DomItem, when dumping or comparing.
\inmodule QtCore \reentrant
QString captured(int nth=0) const
Returns the substring captured by the nth capturing group.
\inmodule QtCore \reentrant
QRegularExpressionMatch matchView(QStringView subjectView, qsizetype offset=0, MatchType matchType=NormalMatch, MatchOptions matchOptions=NoMatchOption) const
static QString anchoredPattern(const QString &expression)
iterator erase(const_iterator i)
bool contains(const T &value) const
const_iterator cbegin() const noexcept
iterator insert(const T &value)
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
QString toString() const
Returns a deep copy of this string view's data as a QString.
\macro QT_RESTRICTED_CAST_FROM_ASCII
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.
static QString fromUtf16(const char16_t *, qsizetype size=-1)
void clear()
Clears the contents of the string and makes it null.
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QMap< QString, QString > map
[6]
list append(new Employee("Blackpool", "Stephen"))
cache insert(employee->id(), employee)
QSet< QString >::iterator it
typename C::iterator iterator
void createDom(MutableDomItem qmlFile, DomCreationOptions options=None)
constexpr bool domTypeIsOwningItem(DomType)
function_ref< void(QStringView)> Sink
std::function< void(const ErrorMessage &)> ErrorHandler
QMLDOM_EXPORT QString domTypeToString(DomType k)
void defaultErrorHandler(const ErrorMessage &error)
Calls the default error handler (by default errorToQDebug)
QMLDOM_EXPORT bool domTypeIsScope(DomType k)
void sinkEscaped(Sink sink, QStringView s, EscapeOptions options)
dumps a string as quoted string (escaping things like quotes or newlines)
QMLDOM_EXPORT bool domTypeIsExternalItem(DomType k)
void sinkNewline(Sink s, int indent)
sinks a neline and indents by the given amount
QMLDOM_EXPORT QCborValue locationToData(SourceLocation loc, QStringView strValue=u"")
QMLDOM_EXPORT QMap< DomType, QString > domTypeToStringMap()
QStringList domCompareStrList(DomItem &i1, DomItem &i2, function_ref< bool(DomItem &, const PathEls::PathComponent &, DomItem &) const > filter, DomCompareStrList stopAtFirstDiff)
QMLDOM_EXPORT bool domTypeIsTopItem(DomType k)
QString dumperToString(Dumper writer)
Converts a dumper to a string.
QString lineDiff(QString s1, QString s2, int nContext)
QMLDOM_EXPORT QString domKindToString(DomKind k)
QMLDOM_EXPORT bool domTypeIsContainer(DomType k)
QMLDOM_EXPORT QMap< DomKind, QString > domKindToStringMap()
void dumperToQDebug(Dumper dumper, QDebug debug)
Combined button and popup list for selecting options.
static jboolean copy(JNIEnv *, jobject)
SharedPointerFileDialogOptions m_options
#define Q_DECLARE_TR_FUNCTIONS(context)
static QDBusError::ErrorType get(const char *name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint64 GLenum void * handle
GLint GLint GLint GLint GLint x
[0]
GLenum GLenum GLsizei const GLuint * ids
GLsizei GLenum GLenum * types
GLenum GLuint GLenum GLsizei length
GLdouble GLdouble GLdouble GLdouble top
GLsizei const GLuint * paths
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLfloat GLfloat GLfloat GLfloat h
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))))
static qreal component(const QPointF &point, unsigned int i)
#define NewErrorGroup(name)
static bool fromString(const QMetaObject *mo, QString s, Allocate &&allocate)
bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
#define Q_ASSERT_X(cond, x, msg)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
static QString dump(const QByteArray &)
SSL_CTX int(*) void DUMMYARG SSL const unsigned char protos)
static QString canonicalPath(const QString &rootPath)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static FileType fileType(const QFileInfo &fi)
static int compare(quint64 a, quint64 b)
static double UTC(double t, double localTZA)
if(qFloatDistance(a, b)<(1<< 7))
[0]
char * toString(const MyType &t)
[31]
\inmodule QtCore \reentrant
bool contains(const AT &t) const noexcept
IUIAutomation __RPC__in_opt IUIAutomationElement * el2
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent