12#if defined(__GNUC__
) && __GNUC__
>= 11
13# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
26#include <QtQml/private/qqmljslexer_p.h>
27#include <QtQml/private/qqmljsparser_p.h>
28#include <QtQml/private/qqmljsengine_p.h>
29#include <QtQml/private/qqmljsastvisitor_p.h>
30#include <QtQml/private/qqmljsast_p.h>
32#include <QtCore/QScopeGuard>
33#include <QtCore/QRegularExpression>
35#include <QtCore/QBasicMutex>
43using namespace Qt::StringLiterals;
52 QString version = QString::number(majorVersion);
53 if (majorVersion == Version::Latest)
54 version = QLatin1String(
"Latest");
55 else if (majorVersion == Version::Undefined)
57 QRegularExpression moduleRe(QLatin1String(R"(\A\w+(?:\.\w+)*\Z)"));
58 auto m = moduleRe.match(uri);
61 .error(Path::tr(
"Invalid module name in import %1").arg(uri))
62 .handle(errorHandler);
69 .withField(Fields::moduleIndexWithUri)
71 .withKey(version.majorSymbolicString())
72 .withField(Fields::moduleScope)
73 .withKey(version.minorString());
78 Version v = Version::fromString(version);
81 return moduleScopePath(uri, v, errorHandler);
95 cont = cont && self.invokeVisitorOnField(visitor, Fields::comments, m_comments);
102 updatePathFromOwnerMultiMap(m_enumerations, newPath.withField(Fields::enumerations));
103 updatePathFromOwnerQList(m_objects, newPath.withField(Fields::objects));
112 bool cont = CommentableDomElement::iterateDirectSubpaths(self, visitor);
113 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), name());
114 cont = cont && self.invokeVisitorOnField(visitor, Fields::enumerations, m_enumerations);
115 cont = cont && self.invokeVisitorOnField(visitor, Fields::objects, m_objects);
116 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isSingleton),
118 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isCreatable),
120 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isComposite),
122 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::attachedTypeName),
124 cont = cont && self.invokeVisitorOnReference(visitor, Fields::attachedType,
attachedTypePath(self
));
130 if (name == Fields::name)
131 return self.wrap(
PathEls::Field(Fields::name), m_name);
132 if (name == Fields::objects)
133 return self.wrap(
PathEls::Field(Fields::objects), m_objects);
135 return DomBase::field(self, name);
140 return appendUpdatableElementInQList(
pathFromOwner().withField(Fields::objects), m_objects, object,
146 bool cont = Component::iterateDirectSubpaths(self, visitor);
147 cont = cont && self.invokeVisitorOnField(visitor, Fields::ids, m_ids);
148 cont = cont && self.invokeVisitorOnLazyField(visitor, Fields::subComponents, [
this, &self]() {
149 return this->subComponents(self);
151 if (m_nameIdentifiers) {
152 cont = cont && visitor(
PathEls::Field(Fields::nameIdentifiers), [
this, &self]() {
153 return self.subScriptElementWrapperItem(m_nameIdentifiers);
162 updatePathFromOwnerMultiMap(m_ids, newPath.withField(Fields::annotations));
167 if (name().contains(QLatin1Char(
'.'))) {
171 .writeRegion(fLoc, ComponentKeywordRegion)
173 .writeRegion(fLoc, IdentifierRegion, name().split(QLatin1Char(
'.')).last())
174 .writeRegion(fLoc, ColonTokenRegion)
177 self.field(Fields::objects).index(0).writeOut(lw);
183 const QSet<QString> cNames = components.keys();
185 if (!myNameDot.isEmpty())
186 myNameDot += QLatin1Char(
'.');
187 QList<QString> subNames;
188 for (
const QString &cName : cNames)
189 if (cName.startsWith(myNameDot)
190 && !QStringView(cName).mid(myNameDot.size()).contains(QLatin1Char(
'.'))
192 subNames.append(cName);
193 std::sort(subNames.begin(), subNames.end());
201 for (
const QString &cName : subComponentsNames(self))
202 for (
const DomItem &comp : components.key(cName).values())
210 return Version(Latest, Latest);
211 QRegularExpression r(
212 QRegularExpression::anchoredPattern(QStringLiteral(uR"(([0-9]*)(?:\.([0-9]*))?)")));
213 auto m = r.matchView(v);
216 int majorV = m.capturedView(1).toInt(&ok);
218 majorV = Version::Undefined;
219 int minorV = m.capturedView(2).toInt(&ok);
221 minorV = Version::Undefined;
222 return Version(majorV, minorV);
231 return majorVersion == Latest && minorVersion == Latest;
236 return majorVersion >= 0 && minorVersion >= 0;
243 if (minorVersion < 0) {
244 if (majorVersion < 0)
245 return QLatin1String(
".");
247 return QString::number(majorVersion);
249 if (majorVersion < 0)
250 return QLatin1String(
".") + QString::number(minorVersion);
251 return QString::number(majorVersion) + QChar::fromLatin1(
'.') + QString::number(minorVersion);
257 cont = cont && self.invokeVisitorOnField(visitor, Fields::majorVersion, majorVersion);
258 cont = cont && self.invokeVisitorOnField(visitor, Fields::minorVersion, minorVersion);
259 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isLatest),
isLatest());
260 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isValid),
isValid());
261 cont = cont && self.invokeVisitorOnLazyField(visitor, Fields::stringValue, [
this]() {
262 return this->stringValue();
269 static QRegularExpression res(QRegularExpression::anchoredPattern(QStringLiteral(
270 uR"((?<uri>\w+(?:\.\w+)*)(?:\W+(?<version>[0-9]+(?:\.[0-9]*)?))?(?:\W+as\W+(?<id>\w+))?$)")));
277 auto m = importRe().match(importStr);
279 if (v.majorVersion == Version::Undefined && v.minorVersion == Version::Undefined)
280 v = Version::fromString(m.captured(2));
281 else if (!m.captured(u"version").isEmpty())
283 .warning(tr(
"Version %1 in import string '%2' overridden by explicit "
285 .arg(m.captured(2), importStr, v.stringValue())
)
287 QString resolvedImportId;
288 if (importId.isEmpty()) {
289 resolvedImportId = m.captured(u"importId");
291 if (!m.captured(u"importId").isEmpty()) {
293 .warning(tr(
"namespace %1 in import string '%2' overridden by explicit "
295 .arg(m.captured(u"importId"), importStr, importId)
)
298 resolvedImportId = importId;
301 return Import(QmlUri::fromUriString(m.captured(u"uri").trimmed()), v, resolvedImportId);
304 .error(tr(
"Unexpected URI format in import '%1'").arg(importStr)
)
310 const QString &importStr,
const QString &importId,
const ErrorHandler &)
312 return Import(QmlUri::fromDirectoryString(importStr),
Version(), importId);
318 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::uri), uri.toString());
319 cont = cont && self.invokeVisitorOnField(visitor, Fields::version, version);
320 if (!importId.isEmpty())
321 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::importId), importId);
323 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::implicit),
implicit);
324 cont = cont && self.invokeVisitorOnField(visitor, Fields::comments, comments);
335 if (std::shared_ptr<QmlFile> qmlFilePtr = self.ownerAs<QmlFile>())
336 code = qmlFilePtr->code();
343 quint32 start = fLoc->info().fullRegion.offset;
344 if (size_t(code.size()) >= start) {
346 QChar c = code.at(--start);
348 if (++preNewlines == 2)
350 }
else if (!c.isSpace())
354 if (preNewlines == 0)
357 ow.ensureNewline(preNewlines);
358 ow.writeRegion(fLoc, ImportTokenRegion).ensureSpace();
359 ow.writeRegion(fLoc, ImportUriRegion, uri.toString());
360 if (uri.isModule()) {
361 QString vString = version.stringValue();
362 if (!vString.isEmpty())
363 ow.ensureSpace().writeRegion(fLoc, VersionRegion, vString);
365 if (!importId.isEmpty()) {
367 .writeRegion(fLoc, AsTokenRegion)
369 .writeRegion(fLoc, IdNameRegion, importId);
378 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), name);
379 cont = cont && self.invokeVisitorOnReference(visitor, Fields::referredObject, referredObjectPath);
380 cont = cont && self.invokeVisitorOnField(visitor, Fields::comments, comments);
381 cont = cont && self.invokeVisitorOnField(visitor, Fields::annotations, annotations);
382 cont = cont && self.invokeVisitorOnField(visitor, Fields::value, value);
388 updatePathFromOwnerQList(annotations, newPath.withField(Fields::annotations));
393 return appendUpdatableElementInQList(selfPathFromOwner.withField(Fields::annotations), annotations,
401 bool cont = CommentableDomElement::iterateDirectSubpaths(self, visitor);
402 if (!idStr().isEmpty())
403 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::idStr), idStr());
404 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), name());
405 if (!prototypePaths().isEmpty())
406 cont = cont && self.invokeVisitorOnReferences(visitor, Fields::prototypes, m_prototypePaths);
408 cont = cont && self.invokeVisitorOnReference(visitor, Fields::nextScope,
nextScopePath());
409 cont = cont && self.invokeVisitorOnField(visitor, Fields::propertyDefs, m_propertyDefs);
410 cont = cont && self.invokeVisitorOnField(visitor, Fields::bindings, m_bindings);
411 cont = cont && self.invokeVisitorOnField(visitor, Fields::methods, m_methods);
412 cont = cont && self.invokeVisitorOnField(visitor, Fields::children, m_children);
413 cont = cont && self.invokeVisitorOnField(visitor, Fields::annotations, m_annotations);
414 cont = cont && visitor(
PathEls::Field(Fields::propertyInfos), [
this, &self]() {
415 return self.subMapItem(Map(
416 pathFromOwner().withField(Fields::propertyInfos),
417 [&self](
const DomItem &map,
const QString &k) {
418 auto pInfo = self.propertyInfoWithName(k);
419 return map.wrap(PathEls::Key(k), pInfo);
421 [&self](
const DomItem &) {
return self.propertyInfoNames(); },
422 QLatin1String(
"PropertyInfo")));
424 if (m_nameIdentifiers) {
425 cont = cont && visitor(
PathEls::Field(Fields::nameIdentifiers), [
this, &self]() {
426 return self.subScriptElementWrapperItem(m_nameIdentifiers);
434 static QList<QString> myFields(
435 { Fields::comments.toString(), Fields::idStr.toString(),
436 Fields::name.toString(), Fields::prototypes.toString(),
437 Fields::nextScope.toString(), Fields::propertyDefs.toString(),
438 Fields::bindings.toString(), Fields::methods.toString(),
439 Fields::children.toString(), Fields::annotations.toString(),
440 Fields::propertyInfos.toString() });
446 bool cont = iterateBaseDirectSubpaths(self, visitor);
447 cont = cont && self.invokeVisitorOnLazyField(visitor, Fields::defaultPropertyName,
448 [
this, &self]() {
return defaultPropertyName(self); });
454 if (name == Fields::name)
455 return self.subDataItem(
PathEls::Field(Fields::name),
this->name());
456 if (name == Fields::idStr) {
457 if (idStr().isEmpty())
459 return self.subDataItem(
PathEls::Field(Fields::idStr), idStr());
461 if (name == Fields::methods)
462 return self.wrap(
PathEls::Field(Fields::methods), m_methods);
463 if (name == Fields::bindings)
464 return self.wrap(
PathEls::Field(Fields::bindings), m_bindings);
465 if (name == Fields::comments)
466 return CommentableDomElement::field(self, name);
467 if (name == Fields::children)
468 return self.wrap(
PathEls::Field(Fields::children), m_children);
470 if (name == Fields::nextScope) {
476 if (name == Fields::prototypes) {
477 if (prototypePaths().isEmpty())
479 return self.subReferencesItem(
PathEls::Field(Fields::prototypes), m_prototypePaths);
481 if (name == Fields::annotations)
482 return self.wrap(
PathEls::Field(Fields::annotations), m_annotations);
483 if (name == Fields::propertyDefs)
484 return self.wrap(
PathEls::Field(Fields::propertyDefs), m_propertyDefs);
485 if (name == Fields::propertyInfos) {
489 [copiedSelf = self](
const DomItem &map,
const QString &k) {
490 return map.wrap(PathEls::Key(k), copiedSelf.propertyInfoWithName(k));
492 [copiedSelf = self](
const DomItem &) {
return copiedSelf.propertyInfoNames(); },
493 QLatin1String(
"PropertyInfo"))
);
495 if (name == Fields::nameIdentifiers && m_nameIdentifiers) {
498 if (name == Fields::defaultPropertyName) {
499 return self.subDataItem(
PathEls::Field(Fields::defaultPropertyName),
500 defaultPropertyName(self));
502 static QStringList knownLookups({ Fields::fileLocationsTree.toString() });
503 if (!knownLookups.contains(name)) {
504 qCWarning(domLog()) <<
"Asked non existing field " << name <<
" in QmlObject "
513 updatePathFromOwnerMultiMap(m_propertyDefs, newPath.withField(Fields::propertyDefs));
514 updatePathFromOwnerMultiMap(m_bindings, newPath.withField(Fields::bindings));
515 updatePathFromOwnerMultiMap(m_methods, newPath.withField(Fields::methods));
516 updatePathFromOwnerQList(m_children, newPath.withField(Fields::children));
517 updatePathFromOwnerQList(m_annotations, newPath.withField(Fields::annotations));
522 if (!m_defaultPropertyName.isEmpty())
523 return m_defaultPropertyName;
524 for (
const PropertyDefinition &pDef : m_propertyDefs)
525 if (pDef.isDefaultMember)
532 QString dProp = localDefaultPropertyName();
533 if (!dProp.isEmpty())
535 QString res = QStringLiteral(u"data");
536 self.visitPrototypeChain(
539 QString dProp = objPtr->localDefaultPropertyName();
540 if (!dProp.isEmpty()) {
553 bool cont = self.field(Fields::bindings).visitKeys([visitor](
const QString &,
const DomItem &bs) {
554 return bs.visitIndexes([visitor](
const DomItem &b) {
555 DomItem v = b.field(Fields::value);
556 if (std::shared_ptr<ScriptExpression> vPtr = v.ownerAs<ScriptExpression>()) {
559 return v.iterateSubOwners(visitor);
564 cont = cont && self.field(Fields::children).visitIndexes([visitor](
const DomItem &qmlObj) {
566 return qmlObjPtr->iterateSubOwners(qmlObj, visitor);
577 AST::Node *node = (expr ? expr->ast() :
nullptr);
579 switch (node->kind) {
580 case AST::Node::Kind_IdentifierExpression: {
581 AST::IdentifierExpression *id = AST::cast<AST::IdentifierExpression *>(node);
582 res.prepend(id->name.toString());
585 case AST::Node::Kind_FieldMemberExpression: {
586 AST::FieldMemberExpression *id = AST::cast<AST::FieldMemberExpression *>(node);
587 res.prepend(id->name.toString());
592 qCDebug(writeOutLog).noquote() <<
"Could not convert dot expression to list for:\n"
593 << expr->astRelocatableDump();
594 return QStringList();
603 QStringList accessSequenceList = dotExpressionToList(accessSequence);
610 QSet<QString> visitedAlias;
611 if (accessSequence.isEmpty()) {
613 }
else if (accessSequence.size() > 3) {
617 QString idName = accessSequence.first();
618 DomItem idTarget = self.component()
622 .field(Fields::referredObject)
626 res.baseObject = idTarget;
627 res.accessedPath = accessSequence.mid(1);
628 res.typeName = idTarget.name();
631 while (!res.accessedPath.isEmpty()) {
632 QString pNow = res.accessedPath.first();
633 DomItem defNow = res.baseObject.propertyDefs().key(pNow).index(0);
636 res.typeName = QString();
639 if (visitedAlias.contains(aliasPath)) {
643 visitedAlias.insert(aliasPath);
644 DomItem valNow = res.baseObject.bindings().key(pNow).index(0);
645 if (std::shared_ptr<ScriptExpression> exp =
646 valNow.field(Fields::value).ownerAs<ScriptExpression>()) {
647 QStringList expList = dotExpressionToList(exp);
648 if (expList.isEmpty()) {
651 }
else if (expList.size() > 3) {
655 idName = expList.first();
656 idTarget = self.component()
660 .field(Fields::referredObject)
662 res.baseObject = idTarget;
663 res.accessedPath = expList.mid(1) + res.accessedPath.mid(1);
669 res.typeName = idTarget.name();
675 res.localPropertyDef = defNow;
676 res.typeName = defNowPtr->typeName;
677 res.accessedPath = res.accessedPath.mid(1);
678 DomItem valNow = res.baseObject.bindings().key(pNow).index(0).field(Fields::value);
680 res.baseObject = valNow;
681 res.typeName = valNow.name();
701 tr(
"Repeated PropertyDefinition with name %1").arg(propertyDef.name)
));
708 if (p && p
.last().headIndex(0) > 1)
709 self.owningItemPtr()->addErrorLocal(
719 self.owningItemPtr()->addErrorLocal(
726 if (!idStr().isEmpty()) {
727 DomItem myId = self.component().field(Fields::ids).key(idStr()).index(0);
731 .writeRegion(fLoc, IdTokenRegion)
732 .writeRegion(fLoc, IdColonTokenRegion)
734 .writeRegion(fLoc, IdNameRegion, idStr());
743 const DomItem &component)
const
747 return l->info().fullRegion;
748 return SourceLocation(posOfNewElements, 0, 0, 0);
751 QList<std::pair<SourceLocation, DomItem>> attribs;
754 if (component && objLocPtr)
755 componentLoc = objLocPtr->parent()->parent();
759 const auto values = base.values();
760 for (
const auto &els : values) {
761 FileLocations::Tree elsLoc = FileLocations::find(baseLoc, els.pathFromOwner().last());
762 const auto elsValues = els.values();
763 for (
const auto &el : elsValues) {
764 FileLocations::Tree elLoc = FileLocations::find(elsLoc, el.pathFromOwner().last());
765 attribs.append(std::make_pair(startLoc(elLoc), el));
769 auto addMyMMap = [
this, &objLocPtr, &self, &addMMap](QStringView fieldName) {
770 DomItem base =
this->field(self, fieldName);
773 auto addSingleLevel = [&attribs, &startLoc](
const DomItem &base,
777 const auto baseValues = base.values();
778 for (
const auto &el : baseValues) {
779 FileLocations::Tree elLoc = FileLocations::find(baseLoc, el.pathFromOwner().last());
780 attribs.append(std::make_pair(startLoc(elLoc), el));
784 DomItem enums = component.field(Fields::enumerations);
787 addMyMMap(Fields::propertyDefs);
788 addMyMMap(Fields::bindings);
789 addMyMMap(Fields::methods);
790 DomItem children = field(self, Fields::children);
793 DomItem subCs = component.field(Fields::subComponents);
794 for (
const DomItem &c : subCs.values()) {
795 const auto subLocPtr = FileLocations::treeOf(c);
797 attribs.append(std::make_pair(startLoc(subLocPtr), c));
800 std::stable_sort(attribs.begin(), attribs.end(),
801 [](
const std::pair<SourceLocation, DomItem> &el1,
802 const std::pair<SourceLocation, DomItem> &el2) {
803 if (el1.first.offset < el2.first.offset)
805 if (el1.first.offset > el2.first.offset)
807 int i =
int(el1.second.internalKind()) -
int(el2.second.internalKind());
814 const QString &code)
const
817 while (iAttr != attribs.size()) {
818 auto &el = attribs[iAttr++];
821 quint32 start = el.first.offset;
822 if (start != posOfNewElements && size_t(code.size()) >= start) {
824 QChar c = code.at(--start);
826 if (++preNewlines == 2)
828 }
else if (!c.isSpace())
832 if (preNewlines == 0)
834 ow.ensureNewline(preNewlines);
836 && el.first.offset != ~quint32(0)) {
838 auto &bPair = attribs[iAttr];
840 && bPair.first.begin() < el.first.end()
841 && bPair.second.name() == el.second.name()) {
846 el.second.writeOut(ow);
849 ow.writeRegion(fLoc, ColonTokenRegion);
854 qWarning() <<
"Internal error casting binding to Binding in"
856 ow.writeRegion(fLoc, LeftBraceRegion).writeRegion(fLoc, RightBraceRegion);
861 el.second.writeOut(ow);
868 const QStringList &keys)
870 QStringList originalOrderedKeys;
871 for (
const auto &attrib : attribs) {
872 QString defName = attrib.second.name();
873 if (keys.contains(defName) && !originalOrderedKeys.contains(defName))
874 originalOrderedKeys.append(std::move(defName));
876 return originalOrderedKeys;
880 const QStringView &field,
const DomItem &refItem)
882 DomItem item = refItem.field(field);
883 QList<DomItem> values = item.values();
885 QList<DomItem> originalValuesOrder;
886 for (
const auto &attrib : attribs) {
887 DomItem itemValue = item.key(attrib.second.name());
888 if (values.contains(itemValue) && !originalValuesOrder.contains(itemValue))
889 originalValuesOrder.append(std::move(itemValue));
891 return originalValuesOrder;
896 for (
const auto &enumDescs : descs) {
897 const auto values = enumDescs.values();
898 for (
const auto &enumDesc : values) {
900 enumDesc.writeOut(ow);
907 QSet<QString> &mergedDefBinding,
908 const QStringList &keys)
const
910 DomItem propertyDefs = field(self, Fields::propertyDefs);
911 DomItem bindings = field(self, Fields::bindings);
913 for (
const QString &defName : keys) {
914 const auto pDefs = propertyDefs.key(defName).values();
915 for (
const auto &pDef : pDefs) {
916 const PropertyDefinition *pDefPtr = pDef.as<PropertyDefinition>();
919 bool uniqueDeclarationWithThisName = pDefs.size() == 1;
920 if (uniqueDeclarationWithThisName && !pDefPtr->isRequired)
921 bindings.key(pDef.name()).visitIndexes([&b, pDefPtr](
const DomItem &el) {
922 const Binding *elPtr = el.as<Binding>();
923 if (elPtr && elPtr->bindingType() == BindingType::Normal) {
924 switch (elPtr->valueKind()) {
925 case BindingValueKind::ScriptExpression:
928 case BindingValueKind::Array:
929 if (!pDefPtr->isDefaultMember && pDefPtr->isParametricType())
932 case BindingValueKind::Object:
933 if (!pDefPtr->isDefaultMember && !pDefPtr->isParametricType())
936 case BindingValueKind::Empty:
944 mergedDefBinding.insert(defName);
949 const auto fLoc = FileLocations::treeOf(b);
950 ow.writeRegion(fLoc, ColonTokenRegion);
952 if (
const Binding *bPtr = b.as<Binding>())
953 bPtr->writeOutValue(b, ow);
955 qWarning() <<
"Internal error casting binding to Binding in"
956 << b.canonicalPath();
957 ow.writeRegion(fLoc, LeftBraceRegion).writeRegion(fLoc, RightBraceRegion);
1012 const DomItem &component,
const Attributes &attribs)
const
1015 quint32 counter = ow.counter();
1018 writeOutSortedEnumerations(
1019 ow.lineWriter.options().groupAttributesTogether
1020 ? keepDomItemsOrder(attribs, Fields::enumerations, component)
1021 : component.field(Fields::enumerations).values(),
1024 if (counter != ow.counter() || !idStr().isEmpty())
1025 spacerId = ow.addNewlinesAutospacerCallback(2);
1027 QSet<QString> mergedDefBinding;
1028 QStringList propertyDefsKeys = field(self, Fields::propertyDefs).sortedKeys();
1029 writeOutSortedPropertyDefinition(self, ow, mergedDefBinding,
1030 ow.lineWriter.options().groupAttributesTogether
1031 ? keepKeysOrder(attribs, propertyDefsKeys)
1032 : propertyDefsKeys);
1034 ow.removeTextAddCallback(spacerId);
1035 if (counter != ow.counter())
1036 spacerId = ow.addNewlinesAutospacerCallback(2);
1038 const auto [signalList, methodList] =
1039 splitSignalsAndMethods(ow.lineWriter.options().groupAttributesTogether
1040 ? keepDomItemsOrder(attribs, Fields::methods, self)
1041 : field(self, Fields::methods).values());
1042 for (
const auto &sig : std::as_const(signalList)) {
1048 ow.removeTextAddCallback(spacerId);
1049 if (counter != ow.counter())
1050 spacerId = ow.addNewlinesAutospacerCallback(2);
1053 for (
const auto &method : std::as_const(methodList)) {
1054 if (!first && ow.lineWriter.options().functionsSpacing) {
1059 method.writeOut(ow);
1062 ow.removeTextAddCallback(spacerId);
1064 DomItem bindings = field(self, Fields::bindings);
1065 QStringList bindingsKeys = bindings.sortedKeys();
1066 const auto [normalBindings, signalHandlers, delayedBindings] = splitBindings(
1067 bindings, mergedDefBinding,
1068 ow.lineWriter.options().groupAttributesTogether ? keepKeysOrder(attribs, bindingsKeys)
1071 if (counter != ow.counter())
1072 spacerId = ow.addNewlinesAutospacerCallback(2);
1073 for (
const auto &b : std::as_const(normalBindings))
1075 ow.removeTextAddCallback(spacerId);
1077 if (counter != ow.counter())
1078 spacerId = ow.addNewlinesAutospacerCallback(2);
1079 for (
const auto &b : std::as_const(delayedBindings))
1081 ow.removeTextAddCallback(spacerId);
1083 if (counter != ow.counter())
1084 spacerId = ow.addNewlinesAutospacerCallback(2);
1085 for (
const auto &b : std::as_const(signalHandlers))
1087 ow.removeTextAddCallback(spacerId);
1089 if (counter != ow.counter())
1090 spacerId = ow.addNewlinesAutospacerCallback(2);
1093 const auto values = field(self, Fields::children).values();
1094 for (
const auto &c : values) {
1095 if (!first && ow.lineWriter.options().objectsSpacing) {
1096 ow.newline().newline();
1102 ow.removeTextAddCallback(spacerId);
1106 DomItem subComps = component.field(Fields::subComponents);
1107 if (counter != ow.counter())
1108 spacerId = ow.addNewlinesAutospacerCallback(2);
1109 const auto values = subComps.values();
1110 for (
const auto &subC : values) {
1114 ow.removeTextAddCallback(spacerId);
1116 if (counter != ow.counter() || !ow.lineWriter.options().singleLineEmptyObjects)
1123 &&
pathFromOwner()[0] == Path::fromField(Fields::components)
1126 ow.writeRegion(fLoc, IdentifierRegion, name());
1127 if (!onTarget.isEmpty()) {
1129 .writeRegion(fLoc, OnTokenRegion)
1131 .writeRegion(fLoc, OnTargetRegion, onTarget);
1134 ow.writeRegion(fLoc, LeftBraceRegion);
1139 const Attributes attributes = orderOfAttributes(self, component);
1144 if (!idStr().isEmpty() && ow.lineWriter.options().attributesSequence
1145 == LineWriterOptions::AttributesSequence::Normalize) {
1146 ow.ensureNewline(attributes.empty() ? 1 : 2);
1149 if (ow.lineWriter.options().attributesSequence
1150 == LineWriterOptions::AttributesSequence::Preserve) {
1152 if (std::shared_ptr<QmlFile> qmlFilePtr = self.ownerAs<QmlFile>())
1153 code = qmlFilePtr->code();
1154 writeOutAttributes(ow, attributes, code);
1156 writeOutSortedAttributes(self, ow, component, attributes);
1158 ow.writeRegion(fLoc, RightBraceRegion);
1179 scriptCode, ScriptExpression::ExpressionType::BindingExpression)),
1195 : m_bindingType(o.m_bindingType),
1202 m_value = std::make_unique<BindingValue>(*o.m_value);
1211 m_bindingType = o.m_bindingType;
1212 m_annotations = o.m_annotations;
1213 m_comments = o.m_comments;
1214 m_bindingIdentifiers = o.m_bindingIdentifiers;
1217 m_value = std::make_unique<BindingValue>(*o.m_value);
1219 *m_value = *o.m_value;
1229 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), m_name);
1230 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isSignalHandler),
1233 cont = cont && visitor(
PathEls::Field(Fields::value), []() {
return DomItem(); });
1235 cont = cont && visitor(
PathEls::Field(Fields::value), [
this, &self]() {
1236 return m_value->value(self);
1238 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::bindingType),
1239 int(m_bindingType));
1240 cont = cont && self.invokeVisitorOnField(visitor, Fields::comments, m_comments);
1241 cont = cont && self.invokeVisitorOnLazyField(visitor, Fields::preCode, [
this]() {
1242 return this->preCode();
1244 cont = cont && self.invokeVisitorOnLazyField(visitor, Fields::postCode, [
this]() {
1245 return this->postCode();
1247 if (m_bindingIdentifiers) {
1248 cont = cont && visitor(
PathEls::Field(Fields::bindingIdentifiers), [
this, &self]() {
1249 return self.subScriptElementWrapperItem(m_bindingIdentifiers);
1252 cont = cont && self.invokeVisitorOnField(visitor, Fields::annotations, m_annotations);
1260 return m_value->value(self);
1266 return BindingValueKind::Empty;
1267 return m_value->kind;
1272 if (valueKind() == BindingValueKind::Object)
1273 return &(m_value->object);
1279 if (valueKind() == BindingValueKind::Object)
1280 return &(m_value->object);
1286 if (valueKind() == BindingValueKind::Array)
1287 return &(m_value->array);
1293 if (valueKind() == BindingValueKind::Array)
1294 return &(m_value->array);
1300 if (valueKind() == BindingValueKind::ScriptExpression)
1301 return m_value->scriptExpression;
1307 if (valueKind() == BindingValueKind::ScriptExpression)
1308 return m_value->scriptExpression;
1314 m_value = std::move(value);
1319 return appendUpdatableElementInQList(selfPathFromOwner.withField(Fields::annotations),
1320 m_annotations, annotation, aPtr);
1325 Path base = newPath.withField(Fields::annotations);
1327 m_value->updatePathFromOwner(newPath.withField(Fields::value));
1328 updatePathFromOwnerQList(m_annotations, newPath.withField(Fields::annotations));
1336 lw.writeRegion(fLoc, IdentifierRegion, name());
1337 lw.writeRegion(fLoc, ColonTokenRegion).ensureSpace();
1346 qCWarning(writeOutLog()) <<
"On Binding requires an QmlObject Value, not "
1356 switch (valueKind()) {
1357 case BindingValueKind::Empty:
1358 qCWarning(writeOutLog()) <<
"Writing of empty binding " << name();
1359 lw.writeRegion(fLoc, LeftBraceRegion);
1360 lw.writeRegion(fLoc, RightBraceRegion);
1362 case BindingValueKind::Array:
1363 if (
const List *vPtr = v.as<
List>()) {
1369 case BindingValueKind::Object:
1370 case BindingValueKind::ScriptExpression:
1378 bool cont = Component::iterateDirectSubpaths(self, visitor);
1379 cont = cont && self.invokeVisitorOnField(visitor, Fields::exports, m_exports);
1380 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::metaRevisions),
1382 if (!fileName().isEmpty()) {
1383 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::fileName),
1386 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::interfaceNames),
1388 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::hasCustomParser),
1390 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::elementTypeName),
1392 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::extensionTypeName),
1393 m_extensionTypeName);
1394 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::accessSemantics),
1395 int(m_accessSemantics));
1403 res.exportSourcePath = source;
1404 res.typePath = typePath;
1405 int slashIdx = exp.indexOf(QLatin1Char(
'/'));
1406 int spaceIdx = exp.indexOf(QLatin1Char(
' '));
1408 spaceIdx = exp.size();
1410 res.version = Version::fromString(exp.mid(spaceIdx + 1));
1411 if (!res.version.isValid())
1413 .error(tr(
"Expected string literal to contain 'Package/Name major.minor' "
1414 "or 'Name major.minor' not '%1'.")
1418 res.uri = exp.left(slashIdx).toString();
1419 res.typeName = exp.mid(slashIdx + 1, spaceIdx - (slashIdx + 1)).toString();
1426 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), name);
1427 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::access),
int(
access));
1428 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::typeName), typeName);
1429 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isReadonly),
isReadonly);
1430 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isList),
isList);
1431 cont = cont && self.invokeVisitorOnField(visitor, Fields::comments, comments);
1432 cont = cont && self.invokeVisitorOnField(visitor, Fields::annotations, annotations);
1439 return appendUpdatableElementInQList(selfPathFromOwner.withField(Fields::annotations), annotations,
1445 Path base = newPath.withField(Fields::annotations);
1446 updatePathFromOwnerQList(annotations, newPath.withField(Fields::annotations));
1451 bool cont = CommentableDomElement::iterateDirectSubpaths(self, visitor);
1452 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), name());
1453 cont = cont && self.invokeVisitorOnField(visitor, Fields::values, m_values);
1454 cont = cont && self.invokeVisitorOnField(visitor, Fields::annotations, m_annotations);
1461 updatePathFromOwnerQList(m_annotations, newPath.withField(Fields::annotations));
1466 m_annotations = annotations;
1471 return appendUpdatableElementInQList(
pathFromOwner().withField(Fields::annotations), m_annotations,
1478 ow.writeRegion(fLoc, EnumKeywordRegion)
1480 .writeRegion(fLoc, IdentifierRegion, name())
1482 .writeRegion(fLoc, LeftBraceRegion);
1483 const auto values = self.field(Fields::values).values();
1484 for (
const auto &value : values)
1486 ow.ensureNewline().writeRegion(fLoc, RightBraceRegion);
1494 RefCacheEntry cached = (env ? RefCacheEntry::forPath(env, selfPath) : RefCacheEntry());
1495 if (cached.cached == RefCacheEntry::Cached::All)
1496 return cached.canonicalPaths;
1498 QSet<Path> knownPaths;
1499 QList<Path> toDo(m_importSourcePaths.rbegin(), m_importSourcePaths.rend());
1500 while (!toDo.isEmpty()) {
1501 Path pNow = toDo.takeLast();
1502 if (knownPaths.contains(pNow))
1504 knownPaths.insert(pNow);
1507 for (
const DomItem &autoExp : sourceBase.field(Fields::autoExports).values()) {
1508 if (
const ModuleAutoExport *autoExpPtr = autoExp.as<ModuleAutoExport>()) {
1510 if (autoExpPtr->inheritVersion) {
1511 Version v = autoExpPtr->import.version;
1512 DomItem sourceVersion = sourceBase.field(Fields::version);
1513 if (
const Version *sourceVersionPtr = sourceVersion.as<Version>()) {
1514 if (v.majorVersion < 0)
1515 v.majorVersion = sourceVersionPtr->majorVersion;
1516 if (v.minorVersion < 0)
1517 v.minorVersion = sourceVersionPtr->minorVersion;
1519 qWarning() <<
"autoExport with inherited version " << autoExp
1520 <<
" but missing version in source" << pNow;
1522 Import toImport(autoExpPtr->import.uri, v);
1523 newSource = toImport.importedPath();
1525 newSource = autoExpPtr->import.importedPath();
1527 if (newSource && !knownPaths.contains(newSource))
1528 toDo.append(newSource);
1530 qWarning() <<
"expected ModuleAutoExport not " << autoExp.internalKindStr()
1531 <<
"looking up autoExports of" << sourceBase;
1544 cont = cont && self.invokeVisitorOnReferences(visitor, Fields::importSources, m_importSourcePaths);
1545 cont = cont && visitor(
PathEls::Field(Fields::allSources), [
this, &self]() ->
DomItem {
1547 self.pathFromOwner().withField(Fields::allSources), allSources(self),
1548 [](
const DomItem &list,
const PathEls::PathComponent &p,
1549 const Path &el) {
return list.subDataItem(p, el.toString()); }));
1551 cont = cont && self.invokeVisitorOnField(visitor, Fields::qualifiedImports, m_subImports);
1552 cont = cont && visitor(
PathEls::Field(Fields::imported), [
this, &self]() ->
DomItem {
1555 [
this, &self](
const DomItem &map,
const QString &key) {
1556 return map.subListItem(List::fromQList<DomItem>(
1557 map.pathFromOwner().withKey(key),
1558 importedItemsWithName(self, key),
1559 [](
const DomItem &,
const PathEls::PathComponent &,
1560 const DomItem &el) {
return el; }));
1562 [
this, &self](
const DomItem &) {
return this->importedNames(self); },
1563 QLatin1String(
"List<Export>"))
);
1571 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::propertyDefs),
1573 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::bindings), bindings);
1581 new (&object) QmlObject(o);
1587 new (&scriptExpression) std::shared_ptr<ScriptExpression>(o);
1592 new (&array) QList<QmlObject>(l);
1603 case BindingValueKind::Empty:
1605 case BindingValueKind::Object:
1606 new (&object) QmlObject(o.object);
1608 case BindingValueKind::ScriptExpression:
1609 new (&scriptExpression) std::shared_ptr<ScriptExpression>(o.scriptExpression);
1611 case BindingValueKind::Array:
1612 new (&array) QList<QmlObject>(o.array);
1621 case BindingValueKind::Empty:
1623 case BindingValueKind::Object:
1624 new (&object) QmlObject(o.object);
1626 case BindingValueKind::ScriptExpression:
1627 new (&scriptExpression) std::shared_ptr<ScriptExpression>(o.scriptExpression);
1629 case BindingValueKind::Array:
1630 new (&array) QList<QmlObject>(o.array);
1638 case BindingValueKind::Empty:
1640 case BindingValueKind::Object:
1641 return binding.copy(&object);
1642 case BindingValueKind::ScriptExpression:
1643 return binding.subOwnerItem(
PathEls::Field(Fields::value), scriptExpression);
1644 case BindingValueKind::Array:
1645 return binding
.subListItem(List::fromQListRef<QmlObject>(
1646 binding.pathFromOwner().withField(u"value"), array,
1647 [](
const DomItem &self,
const PathEls::PathComponent &,
const QmlObject &obj) {
1648 return self.copy(&obj);
1657 case BindingValueKind::Empty:
1659 case BindingValueKind::Object:
1660 object.updatePathFromOwner(newPath);
1662 case BindingValueKind::ScriptExpression:
1664 case BindingValueKind::Array:
1665 updatePathFromOwnerQList(array, newPath);
1673 case BindingValueKind::Empty:
1675 case BindingValueKind::Object:
1676 object.~QmlObject();
1678 case BindingValueKind::ScriptExpression:
1679 scriptExpression.~shared_ptr();
1681 case BindingValueKind::Array:
1682 array.~QList<QmlObject>();
1685 kind = BindingValueKind::Empty;
1690 ExpressionType expressionType,
const SourceLocation &localOffset)
1699 if (m_expressionType == ExpressionType::BindingExpression)
1700 if (AST::ExpressionStatement *exp = AST::cast<AST::ExpressionStatement *>(m_ast))
1701 m_ast = exp->expression;
1702 Q_ASSERT(m_astComments);
1707 QMutexLocker l(mutex());
1708 m_expressionType = e.m_expressionType;
1709 m_engine = e.m_engine;
1711 if (m_codeStr.isEmpty()) {
1714 m_codeStr = e.m_codeStr;
1717 m_localOffset = e.m_localOffset;
1718 m_astComments = e.m_astComments;
1723 bool cont = OwningItem::iterateDirectSubpaths(self, visitor);
1724 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::code), code());
1725 cont = cont && self.invokeVisitorOnLazyField(
1726 visitor, Fields::localOffset,
1727 [
this]() {
return sourceLocationToQCborValue(localOffset()); },
1729 cont = cont && self.invokeVisitorOnLazyField(visitor, Fields::astRelocatableDump, [
this]() {
1730 return astRelocatableDump();
1732 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::expressionType),
1733 int(expressionType()));
1735 cont = cont && visitor(
PathEls::Field(Fields::scriptElement), [
this, &self]() {
1736 return self.subScriptElementWrapperItem(m_element);
1753 if (!VisitAll::uiKinds().contains(n->kind)) {
1754 qsizetype start = n->firstSourceLocation().begin();
1755 qsizetype end = n->lastSourceLocation().end();
1756 if (!firstNodeInRange && minStart <= start && end <= maxEnd && start < end)
1757 firstNodeInRange = n;
1759 return !firstNodeInRange;
1766 AST::Node::accept(n, &visitor);
1767 return visitor.firstNodeInRange;
1773 if (code.isEmpty()) {
1777 m_code = QStringView(m_codeStr);
1779 m_localOffset = SourceLocation();
1780 m_localOffset.length = m_code.size();
1782 m_engine = std::make_shared<QQmlJS::Engine>();
1783 m_astComments = std::make_shared<AstComments>(m_engine);
1786 if (AST::Program *programPtr = AST::cast<AST::Program *>(m_ast)) {
1787 m_ast = programPtr->statements;
1790 if (
auto *sList = AST::cast<AST::FormalParameterList *>(m_ast)) {
1791 m_ast = sList->element;
1793 if (m_expressionType != ExpressionType::FunctionBody) {
1794 if (AST::StatementList *sList = AST::cast<AST::StatementList *>(m_ast)) {
1796 m_ast = sList->statement;
1799 if (m_expressionType == ExpressionType::BindingExpression)
1800 if (AST::ExpressionStatement *exp = AST::cast<AST::ExpressionStatement *>(m_ast))
1801 m_ast = exp->expression;
1809 QQmlJS::Lexer lexer(m_engine.get());
1811 const bool qmlMode = m_expressionType != ExpressionType::ESMCode
1812 && m_expressionType != ExpressionType::JSCode;
1813 lexer.setCode(m_codeStr, 1, qmlMode);
1814 QQmlJS::Parser parser(m_engine.get());
1815 const bool parserSucceeded = m_expressionType == ExpressionType::ESMCode ? parser.parseModule()
1816 : parser.parseScript();
1817 if (!parserSucceeded) {
1820 const auto messages = parser.diagnosticMessages();
1821 for (
const DiagnosticMessage &msg : messages) {
1822 ErrorMessage err = domParsingErrors().errorMessage(msg);
1823 err.location.offset -= m_localOffset.offset;
1824 err.location.startLine -= m_localOffset.startLine;
1825 if (err.location.startLine == 1)
1826 err.location.startColumn -= m_localOffset.startColumn;
1827 addErrorLocal(std::move(err));
1829 return parser.rootNode();
1834 astNodeDumper(s, ast(), options, 1, 0, [
this](SourceLocation astL) {
1835 SourceLocation l =
this->locationToLocal(astL);
1836 return this->code().mid(l.offset, l.length);
1842 return dumperToString([
this](
const Sink &s) {
1843 this->astDumper(s, AstDumperOption::NoLocations | AstDumperOption::SloppyCompare);
1849 reformatAst(lw,
this);
1854 SourceLocation l =
this->locationToLocal(astL);
1855 return this->code().mid(l.offset, l.length);
1860 if (
const FileLocations::Tree tree = FileLocations::treeOf(self)) {
1861 return FileLocations::region(tree, MainRegion);
1863 return SourceLocation();
1868 return typeName.contains(QChar(u'<'));
1876 lw.writeRegion(fLoc, DefaultKeywordRegion).ensureSpace();
1878 lw.writeRegion(fLoc, VirtualKeywordRegion).ensureSpace();
1880 lw.writeRegion(fLoc, OverrideKeywordRegion).ensureSpace();
1882 lw.writeRegion(fLoc, FinalKeywordRegion).ensureSpace();
1884 lw.writeRegion(fLoc, RequiredKeywordRegion).ensureSpace();
1886 lw.writeRegion(fLoc, ReadonlyKeywordRegion).ensureSpace();
1887 if (!typeName.isEmpty()) {
1888 lw.writeRegion(fLoc, PropertyKeywordRegion).ensureSpace();
1889 lw.writeRegion(fLoc, TypeIdentifierRegion, typeName).ensureSpace();
1891 lw.writeRegion(fLoc, IdentifierRegion, name);
1896 bool cont = AttributeInfo::iterateDirectSubpaths(self, visitor);
1897 cont = cont && self.invokeVisitorOnField(visitor, Fields::parameters, parameters);
1898 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::methodType),
1900 if (!typeName.isEmpty())
1901 cont = cont && self.invokeVisitorOnReference(visitor, Fields::type,
typePath(self
));
1902 if (methodType == MethodType::Method) {
1903 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isConstructor),
1907 cont = cont && visitor(
PathEls::Field(Fields::returnType), [
this, &self]() {
1908 return self.subOwnerItem(PathEls::Field(Fields::returnType), returnType);
1911 cont = cont && visitor(
PathEls::Field(Fields::body), [
this, &self]() {
1912 return self.subOwnerItem(PathEls::Field(Fields::body), body);
1919 if (parameters.isEmpty() && methodType == MethodType::Signal)
1923 ow.writeRegion(fLoc, LeftParenthesisRegion);
1925 for (
const DomItem &arg : self.field(Fields::parameters).values()) {
1929 const auto fLocArg = FileLocations::treeOf(arg);
1930 ow.writeRegion(fLocArg, CommaTokenRegion).ensureSpace();
1934 ow.writeRegion(fLoc, RightParenthesisRegion);
1939 if (typeName.isEmpty())
1943 ow.writeRegion(fLoc, ColonTokenRegion);
1945 ow.writeRegion(fLoc, TypeIdentifierRegion, typeName);
1951 ow.ensureSpace().writeRegion(fLoc, LeftBraceRegion);
1952 if (
DomItem b = self.field(Fields::body)) {
1956 ow.ensureNewline().writeRegion(fLoc, RightBraceRegion);
1962 if (methodType == MethodType::Signal) {
1963 ow.writeRegion(fLoc, SignalKeywordRegion).ensureSpace();
1965 ow.writeRegion(fLoc, FunctionKeywordRegion);
1967 ow.writeRegion(fLoc, StarTokenRegion);
1970 ow.writeRegion(fLoc, IdentifierRegion, name);
1971 writeOutArguments(self, ow);
1972 if (methodType == MethodType::Signal) {
1976 writeOutReturnType(self, ow);
1977 writeOutBody(self, ow);
1983 QTextStream res(&resultStr);
1984 LineWriter lw([&res](QStringView s) { res << s; }, QLatin1String(
"*testStream*"));
1986 ow.indentNextlines =
true;
1987 ow.skipComments =
true;
1989 writeOutArguments(self, ow);
1990 writeOutReturnType(self, ow);
1994 return resultStr.simplified();
2000 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), name);
2001 if (!typeName.isEmpty()) {
2002 cont = cont && self.invokeVisitorOnReference(visitor, Fields::type,
2003 Paths::lookupTypePath(typeName));
2004 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::typeName), typeName);
2006 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isPointer),
isPointer);
2007 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isReadonly),
isReadonly);
2008 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::isList),
isList);
2009 cont = cont && self.invokeVisitorOnField(visitor, Fields::defaultValue, defaultValue);
2010 cont = cont && self.invokeVisitorOnField(visitor, Fields::value, value);
2012 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::preCode),
2014 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::postCode), u") {}"_s);
2016 if (!annotations.isEmpty())
2017 cont = cont && self.invokeVisitorOnField(visitor, Fields::annotations, annotations);
2018 cont = cont && self.invokeVisitorOnField(visitor, Fields::comments, comments);
2029 if (!name.isEmpty()) {
2032 ow.writeRegion(fLoc, EllipsisTokenRegion);
2033 ow.writeRegion(fLoc, IdentifierRegion, name);
2034 if (!typeName.isEmpty())
2035 ow.writeRegion(fLoc, ColonTokenRegion)
2037 .writeRegion(fLoc, TypeIdentifierRegion, typeName);
2039 ow.ensureSpace().writeRegion(fLoc, EqualTokenRegion).ensureSpace();
2040 self.subOwnerItem(
PathEls::Field(Fields::defaultValue), defaultValue).writeOut(ow);
2044 self.subOwnerItem(
PathEls::Field(Fields::value), value).writeOut(ow);
2053 if (!typeName.isEmpty())
2054 ow.writeRegion(fLoc, TypeIdentifierRegion, typeName).ensureSpace();
2055 ow.writeRegion(fLoc, IdentifierRegion, name);
2063 ow.writeRegion(fLoc, PragmaKeywordRegion)
2065 .writeRegion(fLoc, IdentifierRegion, name);
2067 bool isFirst =
true;
2068 for (
const auto &value : values) {
2071 ow.writeRegion(fLoc, ColonTokenRegion).ensureSpace();
2072 ow.writeRegion(fLoc, PragmaValuesRegion, value);
2076 ow.writeRegion(fLoc, CommaTokenRegion).ensureSpace();
2077 ow.writeRegion(fLoc, PragmaValuesRegion, value);
2085 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::name), name());
2086 cont = cont && self.invokeVisitorOnValue(visitor,
PathEls::Field(Fields::value),
value());
2087 cont = cont && self.invokeVisitorOnField(visitor, Fields::comments, m_comments);
2096 ow.writeRegion(fLoc, CommaTokenRegion);
2098 ow.writeRegion(fLoc, IdentifierRegion, name());
2100 QString v = QString::number(value(),
'f', 0);
2101 if (abs(value() - v.toDouble()) > 1.e-10)
2102 v = QString::number(value());
2104 .writeRegion(fLoc, EqualTokenRegion)
2106 .writeRegion(fLoc, EnumValueRegion, v);
2112 if (str.startsWith(u'"'))
2113 return fromDirectoryString(str.mid(1, str.size() - 2)
2114 .replace(u"\\\""_s, u"\""_s)
2115 .replace(u"\\\\"_s, u"\\"_s));
2117 return fromUriString(str);
2122 QRegularExpression moduleUriRe(QLatin1String(R"(\A\w+(?:\.\w+)*\Z)"));
2129 if (url.isValid() && url.scheme().size() > 1)
2131 if (!str.isEmpty()) {
2132 QFileInfo path(str);
2164 if (m_kind == Kind::ModuleUri)
2165 return std::get<QString>(m_value);
2176 const QUrl &url = std::get<QUrl>(m_value);
2177 if (url.scheme().compare(u"file", Qt::CaseInsensitive) == 0)
2181 case Kind::RelativePath:
2182 case Kind::AbsolutePath:
2183 return std::get<QString>(m_value);
2195 const QUrl &url = std::get<QUrl>(m_value);
2196 if (url.scheme().compare(u"file", Qt::CaseInsensitive) == 0)
2201 if (!basePath.isEmpty())
2202 return QDir(basePath).filePath(std::get<QString>(m_value));
2205 case Kind::AbsolutePath:
2206 return std::get<QString>(m_value);
2213 if (m_kind == Kind::DirectoryUrl)
2214 return std::get<QUrl>(m_value);
2224 case Kind::DirectoryUrl:
2225 return std::get<QUrl>(m_value).toString();
2226 case Kind::RelativePath:
2227 case Kind::AbsolutePath:
2228 return std::get<QString>(m_value);
2238 case Kind::ModuleUri:
2239 return std::get<QString>(m_value);
2240 case Kind::DirectoryUrl:
2241 case Kind::RelativePath:
2242 case Kind::AbsolutePath:
2243 return u"\""_s + directoryString().replace(u'\\', u"\\\\"_s).replace(u'"', u"\\\""_s)
2264#include "moc_qqmldomelements_p.cpp"
void updatePathFromOwner(const Path &newPath)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &annotation, QmlObject **aPtr=nullptr)
BindingValue(const QList< QmlObject > &l)
void updatePathFromOwner(const Path &newPath)
BindingValue(const std::shared_ptr< ScriptExpression > &o)
BindingValue(const BindingValue &o)
DomItem value(const DomItem &binding) const
BindingValue & operator=(const BindingValue &o)
BindingValue(const QmlObject &o)
void setValue(std::unique_ptr< BindingValue > &&value)
std::shared_ptr< ScriptExpression > scriptExpressionValue() const
Binding & operator=(const Binding &)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &a, QmlObject **aPtr=nullptr)
void updatePathFromOwner(const Path &newPath)
QmlObject const * objectValue() const
DomItem valueItem(const DomItem &self) const
QList< QmlObject > * arrayValue()
Binding(const Binding &o)
QList< QmlObject > const * arrayValue() const
void writeOut(const DomItem &self, OutWriter &lw) const
Binding(const QString &m_name, const QString &scriptCode, BindingType bindingType=BindingType::Normal)
Binding(const QString &m_name, std::unique_ptr< BindingValue > &&value, BindingType bindingType=BindingType::Normal)
bool isSignalHandler() const
void writeOutValue(const DomItem &self, OutWriter &lw) const
Binding(const QString &m_name=QString())
Binding(const QString &m_name, const QmlObject &value, BindingType bindingType=BindingType::Normal)
QmlObject * objectValue()
std::shared_ptr< ScriptExpression > scriptExpressionValue()
BindingValueKind valueKind() const
Binding(const QString &m_name, const std::shared_ptr< ScriptExpression > &value, BindingType bindingType=BindingType::Normal)
void updatePathFromOwner(const Path &newPath) override
Component(const Path &pathFromOwner=Path())
Path addObject(const QmlObject &object, QmlObject **oPtr=nullptr)
Path attachedTypePath(const DomItem &) const
DomItem field(const DomItem &self, QStringView name) const override
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
Component(const QString &name)
virtual void updatePathFromOwner(const Path &newPath)
Path pathFromOwner() const override
A value type that references any element of the Dom.
void writeOutPost(OutWriter &lw) const
DomItem path(const Path &p, const ErrorHandler &h=&defaultErrorHandler) const
DomItem subListItem(const List &list) const
void writeOutPre(OutWriter &lw) const
DomItem environment() const
Path canonicalPath() const
DomItem containingObject() const
DomItem subMapItem(const Map &map) const
DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const
InternalKind internalKind() const
DomItem owner() const
The owner of an element, for an qmlObject this is the containing qml file.
void writeOut(OutWriter &lw) const
Path pathFromOwner() const
DomItem subScriptElementWrapperItem(const ScriptElementVariant &obj) const
static ErrorGroup domErrorGroup
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
void setAnnotations(const QList< QmlObject > &annotations)
void writeOut(const DomItem &self, OutWriter &lw) const override
void updatePathFromOwner(const Path &newP) override
Path addAnnotation(const QmlObject &child, QmlObject **cPtr=nullptr)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOut(const DomItem &self, OutWriter &lw) const
Represents a set of tags grouping a set of related error messages.
ErrorMessage warning(const Dumper &message) const
ErrorMessage error(const Dumper &message) const
AST::Node * firstNodeInRange
bool preVisit(AST::Node *n) override
FirstNodeVisitor(qsizetype minStart, qsizetype maxEnd)
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &ann, QmlObject **aPtr=nullptr)
Id(const QString &idName=QString(), const Path &referredObject=Path())
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
void updatePathFromOwner(const Path &pathFromOwner)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
QList< Path > allSources(const DomItem &self) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
void writeOut(const DomItem &self, OutWriter &ow) const
void eof(bool ensureNewline=true)
void writeOut(const DomItem &self, OutWriter &ow, bool compact) const
std::function< index_type(const DomItem &)> Length
std::function< QSet< QString >(const DomItem &)> Keys
Path typePath(const DomItem &) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOut(const DomItem &self, OutWriter &ow) const
QString signature(const DomItem &self) const
void writeOut(const DomItem &self, OutWriter &ow) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOutSignal(const DomItem &self, OutWriter &ow) const
TypeAnnotationStyle typeAnnotationStyle
MutableDomItem path(const Path &p)
A DomItem that owns other DomItems and is managed through a shared pointer.
void addErrorLocal(ErrorMessage &&msg)
OwningItem(int derivedFrom=0)
static Path fromRoot(PathRoot r)
static ErrorGroups myErrors()
Path operator[](int i) const
void writeOut(const DomItem &self, OutWriter &ow) const
bool isParametricType() const
void writeOut(const DomItem &self, OutWriter &lw) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
QList< DomItem > subComponents(const DomItem &self) const
void updatePathFromOwner(const Path &newPath) override
void writeOut(const DomItem &self, OutWriter &) const override
QList< QString > subComponentsNames(const DomItem &self) const
MutableDomItem addBinding(MutableDomItem &self, const Binding &binding, AddOption option)
void writeOutSortedEnumerations(const QList< DomItem > &descs, OutWriter &ow) const
void writeOut(const DomItem &self, OutWriter &ow, const QString &onTarget) const
QList< std::pair< SourceLocation, DomItem > > orderOfAttributes(const DomItem &self, const DomItem &component) const
bool iterateSubOwners(const DomItem &self, function_ref< bool(const DomItem &owner)> visitor) const
void updatePathFromOwner(const Path &newPath) override
Path addBinding(const Binding &binding, AddOption option, Binding **bPtr=nullptr)
LocallyResolvedAlias resolveAlias(const DomItem &self, std::shared_ptr< ScriptExpression > accessSequence) const
void writeOutId(const DomItem &self, OutWriter &ow) const
LocallyResolvedAlias resolveAlias(const DomItem &self, const QStringList &accessSequence) const
void writeOutSortedPropertyDefinition(const DomItem &self, OutWriter &ow, QSet< QString > &mergedDefBinding, const QStringList &keys) const
Path addPropertyDef(const PropertyDefinition &propertyDef, AddOption option, PropertyDefinition **pDef=nullptr)
void writeOutSortedAttributes(const DomItem &self, OutWriter &ow, const DomItem &component, const Attributes &attribs) const
MutableDomItem addPropertyDef(MutableDomItem &self, const PropertyDefinition &propertyDef, AddOption option)
DomItem field(const DomItem &self, QStringView name) const override
QString localDefaultPropertyName() const
QString defaultPropertyName(const DomItem &self) const
QmlObject(const Path &pathFromOwner=Path())
void writeOutAttributes(OutWriter &ow, const Attributes &attribs, const QString &code) const
MutableDomItem addMethod(MutableDomItem &self, const MethodInfo &functionDef, AddOption option)
Path nextScopePath() const
void writeOut(const DomItem &self, OutWriter &lw) const override
QList< QString > fields() const
QList< std::pair< SourceLocation, DomItem > > Attributes
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
Path addMethod(const MethodInfo &functionDef, AddOption option, MethodInfo **mPtr=nullptr)
bool iterateBaseDirectSubpaths(const DomItem &self, DirectVisitor) const
QString absoluteLocalPath(const QString &basePath=QString()) const
QUrl directoryUrl() const
QString directoryString() const
QString localPath() const
QString moduleUri() const
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
static bool addForPath(const DomItem &el, const Path &canonicalPath, const RefCacheEntry &entry, AddOption addOption=AddOption::KeepExisting)
Use this to contain any script element.
QStringView loc2Str(const SourceLocation &) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
ScriptExpression(const ScriptExpression &e)
void writeOut(const DomItem &self, OutWriter &lw) const override
SourceLocation globalLocation(const DomItem &self) const
ScriptExpression(QStringView code, const std::shared_ptr< QQmlJS::Engine > &engine, AST::Node *ast, const std::shared_ptr< AstComments > &comments, ExpressionType expressionType, const SourceLocation &localOffset=SourceLocation())
QString astRelocatableDump() const
void setScriptElement(const ScriptElementVariant &p)
void astDumper(const Sink &s, AstDumperOptions options) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
Version(qint32 majorVersion=Undefined, qint32 minorVersion=Undefined)
QString stringValue() const
A vistor that visits all the AST:Node.
Provides entities to maintain mappings between elements and their location in a file.
Tree treeOf(const DomItem &)
Tree find(const Tree &self, const Path &p)
std::shared_ptr< Node > Tree
Path moduleIndexPath(const QString &uri, int majorVersion, const ErrorHandler &errorHandler=nullptr)
Path moduleScopePath(const QString &uri, const QString &version, const ErrorHandler &errorHandler=nullptr)
Path moduleScopePath(const QString &uri, Version version, const ErrorHandler &errorHandler=nullptr)
static ErrorGroups domParsingErrors()
static QStringList dotExpressionToList(const std::shared_ptr< ScriptExpression > &expr)
static QStringList keepKeysOrder(const QList< std::pair< SourceLocation, DomItem > > &attribs, const QStringList &keys)
static QList< DomItem > keepDomItemsOrder(const QList< std::pair< SourceLocation, DomItem > > &attribs, const QStringView &field, const DomItem &refItem)
std::function< void(const ErrorMessage &)> ErrorHandler
AST::Node * firstNodeInRange(AST::Node *n, qsizetype minStart=0, qsizetype maxEnd=std::numeric_limits< qint32 >::max())
Combined button and popup list for selecting options.
#define NewErrorGroup(name)