aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmldom
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmldom')
-rw-r--r--src/qmldom/qqmldomattachedinfo.cpp2
-rw-r--r--src/qmldom/qqmldomcomments.cpp2
-rw-r--r--src/qmldom/qqmldomelements.cpp46
-rw-r--r--src/qmldom/qqmldomelements_p.h2
-rw-r--r--src/qmldom/qqmldomerrormessage.cpp2
-rw-r--r--src/qmldom/qqmldomerrormessage_p.h63
-rw-r--r--src/qmldom/qqmldomfieldfilter.cpp2
-rw-r--r--src/qmldom/qqmldomfilewriter.cpp2
-rw-r--r--src/qmldom/qqmldomitem.cpp95
-rw-r--r--src/qmldom/qqmldomitem_p.h13
-rw-r--r--src/qmldom/qqmldomlinewriter.cpp2
-rw-r--r--src/qmldom/qqmldommoduleindex.cpp2
-rw-r--r--src/qmldom/qqmldompath.cpp17
-rw-r--r--src/qmldom/qqmldompath_p.h32
-rw-r--r--src/qmldom/qqmldomreformatter.cpp62
-rw-r--r--src/qmldom/qqmldomtop.cpp169
-rw-r--r--src/qmldom/qqmldomtop_p.h13
17 files changed, 364 insertions, 162 deletions
diff --git a/src/qmldom/qqmldomattachedinfo.cpp b/src/qmldom/qqmldomattachedinfo.cpp
index 707aae4283..eb48640d90 100644
--- a/src/qmldom/qqmldomattachedinfo.cpp
+++ b/src/qmldom/qqmldomattachedinfo.cpp
@@ -369,3 +369,5 @@ bool UpdatedScriptExpression::visitTree(Tree base, function_ref<bool(Path, Tree)
} // namespace Dom
} // namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomattachedinfo_p.cpp"
diff --git a/src/qmldom/qqmldomcomments.cpp b/src/qmldom/qqmldomcomments.cpp
index af58b6d821..7edcc0c9d9 100644
--- a/src/qmldom/qqmldomcomments.cpp
+++ b/src/qmldom/qqmldomcomments.cpp
@@ -555,7 +555,7 @@ void AstComments::collectComments(std::shared_ptr<Engine> engine, AST::Node *n,
}
if (iPre == 0)
preNewline = 1;
- quint32 iPost = cLoc.end();
+ qsizetype iPost = cLoc.end();
while (iPost < code.size()) {
QChar c = code.at(iPost);
if (!c.isSpace()) {
diff --git a/src/qmldom/qqmldomelements.cpp b/src/qmldom/qqmldomelements.cpp
index 914c72e34f..9a9a186833 100644
--- a/src/qmldom/qqmldomelements.cpp
+++ b/src/qmldom/qqmldomelements.cpp
@@ -57,6 +57,7 @@
#include <QtCore/QBasicMutex>
#include <optional>
+#include <limits>
QT_BEGIN_NAMESPACE
@@ -653,9 +654,14 @@ MutableDomItem QmlObject::addMethod(MutableDomItem &self, MethodInfo functionDef
void QmlObject::writeOut(DomItem &self, OutWriter &ow, QString onTarget) const
{
+ const quint32 posOfNewElements = std::numeric_limits<quint32>::max();
bool isRootObject = pathFromOwner().length() == 5
&& pathFromOwner()[0] == Path::Field(Fields::components)
&& pathFromOwner()[3] == Path::Field(Fields::objects);
+ QString code;
+ DomItem owner = self.owner();
+ if (std::shared_ptr<QmlFile> qmlFilePtr = self.ownerAs<QmlFile>())
+ code = qmlFilePtr->code();
ow.writeRegion(u"name", name());
if (!onTarget.isEmpty())
ow.space().writeRegion(u"on", u"on").space().writeRegion(u"onTarget", onTarget).space();
@@ -678,10 +684,10 @@ void QmlObject::writeOut(DomItem &self, OutWriter &ow, QString onTarget) const
DomItem component;
if (isRootObject)
component = self.containingObject();
- auto startLoc = [](FileLocations::Tree l) {
+ auto startLoc = [&](FileLocations::Tree l) {
if (l)
return l->info().fullRegion;
- return SourceLocation(~quint32(0), 0, 0, 0);
+ return SourceLocation(posOfNewElements, 0, 0, 0);
};
if (ow.lineWriter.options().attributesSequence
== LineWriterOptions::AttributesSequence::Preserve) {
@@ -749,10 +755,22 @@ void QmlObject::writeOut(DomItem &self, OutWriter &ow, QString onTarget) const
qsizetype iAttr = 0;
while (iAttr != attribs.size()) {
auto &el = attribs[iAttr++];
- if (iAttr > 1 && el.second.internalKind() != attribs[iAttr - 2].second.internalKind())
- ow.ensureNewline(2);
- else
- ow.ensureNewline();
+ // check for an empty line before the current element, and preserve it
+ int preNewlines = 0;
+ quint32 start = el.first.offset;
+ if (start != posOfNewElements && size_t(code.size()) >= start) {
+ while (start != 0) {
+ QChar c = code.at(--start);
+ if (c == u'\n') {
+ if (++preNewlines == 2)
+ break;
+ } else if (!c.isSpace())
+ break;
+ }
+ }
+ if (preNewlines == 0)
+ ++preNewlines;
+ ow.ensureNewline(preNewlines);
if (el.second.internalKind() == DomType::PropertyDefinition && iAttr != attribs.size()
&& el.first.offset != ~quint32(0)) {
DomItem b;
@@ -1197,9 +1215,10 @@ void EnumDecl::writeOut(DomItem &self, OutWriter &ow) const
QList<Path> ImportScope::allSources(DomItem &self) const
{
- DomItem env = self.environment();
+ DomItem top = self.top();
+ DomItem env = top.environment();
Path selfPath = self.canonicalPath().field(Fields::allSources);
- RefCacheEntry cached = RefCacheEntry::forPath(env, selfPath);
+ RefCacheEntry cached = (env ? RefCacheEntry::forPath(env, selfPath) : RefCacheEntry());
if (cached.cached == RefCacheEntry::Cached::All)
return cached.canonicalPaths;
QList<Path> res;
@@ -1211,7 +1230,7 @@ QList<Path> ImportScope::allSources(DomItem &self) const
continue;
knownPaths.insert(pNow);
res.append(pNow);
- DomItem sourceBase = env.path(pNow);
+ DomItem sourceBase = top.path(pNow);
for (DomItem autoExp : sourceBase.field(Fields::autoExports).values()) {
if (const ModuleAutoExport *autoExpPtr = autoExp.as<ModuleAutoExport>()) {
Path newSource;
@@ -1241,7 +1260,8 @@ QList<Path> ImportScope::allSources(DomItem &self) const
}
}
}
- RefCacheEntry::addForPath(env, selfPath, RefCacheEntry { RefCacheEntry::Cached::All, res });
+ if (env)
+ RefCacheEntry::addForPath(env, selfPath, RefCacheEntry { RefCacheEntry::Cached::All, res });
return res;
}
@@ -1447,10 +1467,10 @@ class FirstNodeVisitor : public VisitAll
{
public:
quint32 minStart = 0;
- quint32 maxEnd = ~quint32(0);
+ quint32 maxEnd = std::numeric_limits<quint32>::max();
AST::Node *firstNodeInRange = nullptr;
- FirstNodeVisitor(quint32 minStart = 0, quint32 maxEnd = ~quint32(0))
+ FirstNodeVisitor(quint32 minStart = 0, quint32 maxEnd = std::numeric_limits<quint32>::max())
: minStart(minStart), maxEnd(maxEnd)
{
}
@@ -1769,3 +1789,5 @@ void EnumItem::writeOut(DomItem &self, OutWriter &ow) const
} // end namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomelements_p.cpp"
diff --git a/src/qmldom/qqmldomelements_p.h b/src/qmldom/qqmldomelements_p.h
index 69c2cc1a7d..023883dfd6 100644
--- a/src/qmldom/qqmldomelements_p.h
+++ b/src/qmldom/qqmldomelements_p.h
@@ -726,7 +726,6 @@ public:
: CommentableDomElement(pathFromOwner), m_name(name), m_values(values)
{
}
- EnumDecl &operator=(const EnumDecl &) = default;
bool iterateDirectSubpaths(DomItem &self, DirectVisitor visitor) override;
@@ -766,7 +765,6 @@ public:
DomType kind() const override { return kindValue; }
QmlObject(Path pathFromOwner = Path());
- QmlObject &operator=(const QmlObject &) = default;
bool iterateDirectSubpaths(DomItem &self, DirectVisitor) override;
bool iterateBaseDirectSubpaths(DomItem &self, DirectVisitor);
QList<QString> fields() const;
diff --git a/src/qmldom/qqmldomerrormessage.cpp b/src/qmldom/qqmldomerrormessage.cpp
index e621ac775f..450ae558b8 100644
--- a/src/qmldom/qqmldomerrormessage.cpp
+++ b/src/qmldom/qqmldomerrormessage.cpp
@@ -560,3 +560,5 @@ ErrorLevel errorLevelFromQtMsgType(QtMsgType msgType)
} // end namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomerrormessage_p.cpp"
diff --git a/src/qmldom/qqmldomerrormessage_p.h b/src/qmldom/qqmldomerrormessage_p.h
index fc3e0a2e11..3e7233125e 100644
--- a/src/qmldom/qqmldomerrormessage_p.h
+++ b/src/qmldom/qqmldomerrormessage_p.h
@@ -160,6 +160,46 @@ public:
void dump(Sink s) const;
QString toString() const;
QCborMap toCbor() const;
+ friend int compare(const ErrorMessage &msg1, const ErrorMessage &msg2)
+ {
+ int c;
+ c = msg1.location.offset - msg2.location.offset;
+ if (c != 0)
+ return c;
+ c = msg1.location.startLine - msg2.location.startLine;
+ if (c != 0)
+ return c;
+ c = msg1.errorId.compare(msg2.errorId);
+ if (c != 0)
+ return c;
+ if (!msg1.errorId.isEmpty())
+ return 0;
+ c = msg1.message.compare(msg2.message);
+ if (c != 0)
+ return c;
+ c = msg1.file.compare(msg2.file);
+ if (c != 0)
+ return c;
+ c = Path::cmp(msg1.path, msg2.path);
+ if (c != 0)
+ return c;
+ c = int(msg1.level) - int(msg2.level);
+ if (c != 0)
+ return c;
+ c = int(msg1.errorGroups.groups.size() - msg2.errorGroups.groups.size());
+ if (c != 0)
+ return c;
+ for (qsizetype i = 0; i < msg1.errorGroups.groups.size(); ++i) {
+ c = msg1.errorGroups.groups[i].groupId().compare(msg2.errorGroups.groups[i].groupId());
+ if (c != 0)
+ return c;
+ }
+ c = msg1.location.length - msg2.location.length;
+ if (c != 0)
+ return c;
+ c = msg1.location.startColumn - msg2.location.startColumn;
+ return c;
+ }
QLatin1String errorId;
QString message;
@@ -171,13 +211,26 @@ public:
};
inline bool operator !=(const ErrorMessage &e1, const ErrorMessage &e2) {
- return e1.errorId != e2.errorId || e1.message != e2.message || e1.errorGroups != e2.errorGroups
- || e1.level != e2.level || e1.path != e2.path || e1.file != e2.file
- || e1.location.startLine != e2.location.startLine || e1.location.offset != e2.location.offset
- || e1.location.startColumn != e2.location.startColumn || e1.location.length != e2.location.length;
+ return compare(e1, e2) != 0;
}
inline bool operator ==(const ErrorMessage &e1, const ErrorMessage &e2) {
- return !(e1 != e2);
+ return compare(e1, e2) == 0;
+}
+inline bool operator<(const ErrorMessage &e1, const ErrorMessage &e2)
+{
+ return compare(e1, e2) < 0;
+}
+inline bool operator<=(const ErrorMessage &e1, const ErrorMessage &e2)
+{
+ return compare(e1, e2) <= 0;
+}
+inline bool operator>(const ErrorMessage &e1, const ErrorMessage &e2)
+{
+ return compare(e1, e2) > 0;
+}
+inline bool operator>=(const ErrorMessage &e1, const ErrorMessage &e2)
+{
+ return compare(e1, e2) >= 0;
}
QMLDOM_EXPORT void silentError(const ErrorMessage &);
diff --git a/src/qmldom/qqmldomfieldfilter.cpp b/src/qmldom/qqmldomfieldfilter.cpp
index 3fa39b5b49..1ea27e0ee5 100644
--- a/src/qmldom/qqmldomfieldfilter.cpp
+++ b/src/qmldom/qqmldomfieldfilter.cpp
@@ -237,3 +237,5 @@ void FieldFilter::setFiltred()
} // end namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomfieldfilter_p.cpp"
diff --git a/src/qmldom/qqmldomfilewriter.cpp b/src/qmldom/qqmldomfilewriter.cpp
index b24e5518ba..b7b0e21d97 100644
--- a/src/qmldom/qqmldomfilewriter.cpp
+++ b/src/qmldom/qqmldomfilewriter.cpp
@@ -166,3 +166,5 @@ FileWriter::Status FileWriter::write(QString tFile, function_ref<bool(QTextStrea
} // namespace Dom
} // namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomfilewriter_p.cpp"
diff --git a/src/qmldom/qqmldomitem.cpp b/src/qmldom/qqmldomitem.cpp
index 079fa5678e..3a3ab7bb26 100644
--- a/src/qmldom/qqmldomitem.cpp
+++ b/src/qmldom/qqmldomitem.cpp
@@ -1927,14 +1927,23 @@ MutableDomItem DomItem::makeCopy(DomItem::CopyOption option)
return MutableDomItem(newItem.path(pathFromOwner()));
}
DomItem env = environment();
- std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>();
- Q_ASSERT(envPtr);
- std::shared_ptr<DomEnvironment> newEnvPtr(
- new DomEnvironment(envPtr, envPtr->loadPaths(), envPtr->options()));
- DomBase *eBase = envPtr.get();
- if (std::holds_alternative<DomEnvironment *>(m_element) && eBase
- && std::get<DomEnvironment *>(m_element) == eBase)
- return MutableDomItem(DomItem(newEnvPtr));
+ std::shared_ptr<DomEnvironment> newEnvPtr;
+ if (std::shared_ptr<DomEnvironment> envPtr = env.ownerAs<DomEnvironment>()) {
+ newEnvPtr = std::shared_ptr<DomEnvironment>(
+ new DomEnvironment(envPtr, envPtr->loadPaths(), envPtr->options()));
+ DomBase *eBase = envPtr.get();
+ if (std::holds_alternative<DomEnvironment *>(m_element) && eBase
+ && std::get<DomEnvironment *>(m_element) == eBase)
+ return MutableDomItem(DomItem(newEnvPtr));
+ } else if (std::shared_ptr<DomUniverse> univPtr = top().ownerAs<DomUniverse>()) {
+ newEnvPtr = std::shared_ptr<DomEnvironment>(new DomEnvironment(
+ QStringList(),
+ DomEnvironment::Option::SingleThreaded | DomEnvironment::Option::NoDependencies,
+ univPtr));
+ } else {
+ Q_ASSERT(false);
+ return {};
+ }
DomItem newItem = std::visit(
[this, newEnvPtr, &o](auto &&el) {
auto copyPtr = el->makeCopy(o);
@@ -2279,21 +2288,23 @@ DomItem::DomItem(std::shared_ptr<DomUniverse> universePtr):
}
void DomItem::loadFile(QString canonicalFilePath, QString logicalPath, QString code,
- QDateTime codeDate, DomTop::Callback callback, LoadOptions loadOptions)
+ QDateTime codeDate, DomTop::Callback callback, LoadOptions loadOptions,
+ std::optional<DomType> fileType)
{
DomItem topEl = top();
if (topEl.internalKind() == DomType::DomEnvironment
|| topEl.internalKind() == DomType::DomUniverse) {
if (auto univ = topEl.ownerAs<DomUniverse>())
univ->loadFile(*this, canonicalFilePath, logicalPath, code, codeDate, callback,
- loadOptions);
+ loadOptions, fileType);
else if (auto env = topEl.ownerAs<DomEnvironment>()) {
if (env->options() & DomEnvironment::Option::NoDependencies)
env->loadFile(topEl, canonicalFilePath, logicalPath, code, codeDate, callback,
- DomTop::Callback(), DomTop::Callback(), loadOptions);
+ DomTop::Callback(), DomTop::Callback(), loadOptions, fileType);
else
env->loadFile(topEl, canonicalFilePath, logicalPath, code, codeDate,
- DomTop::Callback(), DomTop::Callback(), callback, loadOptions);
+ DomTop::Callback(), DomTop::Callback(), callback, loadOptions,
+ fileType);
} else
Q_ASSERT(false && "expected either DomUniverse or DomEnvironment cast to succeed");
} else {
@@ -2303,7 +2314,7 @@ void DomItem::loadFile(QString canonicalFilePath, QString logicalPath, QString c
}
void DomItem::loadFile(QString filePath, QString logicalPath, DomTop::Callback callback,
- LoadOptions loadOptions)
+ LoadOptions loadOptions, std::optional<DomType> fileType)
{
DomItem topEl = top();
if (topEl.internalKind() == DomType::DomEnvironment
@@ -2313,10 +2324,10 @@ void DomItem::loadFile(QString filePath, QString logicalPath, DomTop::Callback c
else if (auto env = topEl.ownerAs<DomEnvironment>()) {
if (env->options() & DomEnvironment::Option::NoDependencies)
env->loadFile(topEl, filePath, logicalPath, callback, DomTop::Callback(),
- DomTop::Callback(), loadOptions);
+ DomTop::Callback(), loadOptions, fileType);
else
env->loadFile(topEl, filePath, logicalPath, DomTop::Callback(), DomTop::Callback(),
- callback, loadOptions);
+ callback, loadOptions, fileType);
} else
Q_ASSERT(false && "expected either DomUniverse or DomEnvironment cast to succeed");
} else {
@@ -2727,26 +2738,28 @@ DomItem Reference::get(DomItem &self, ErrorHandler h, QList<Path> *visitedRefs)
Path cachedPath;
if (shouldCache()) {
env = self.environment();
- selfPath = self.canonicalPath();
- RefCacheEntry cached = RefCacheEntry::forPath(self, selfPath);
- switch (cached.cached) {
- case RefCacheEntry::Cached::None:
- break;
- case RefCacheEntry::Cached::First:
- case RefCacheEntry::Cached::All:
- if (!cached.canonicalPaths.isEmpty())
- cachedPath = cached.canonicalPaths.first();
- else
- return res;
- break;
- }
- if (cachedPath) {
- res = env.path(cachedPath);
- if (!res)
- qCWarning(refLog) << "referenceCache outdated, reference at " << selfPath
- << " leads to invalid path " << cachedPath;
- else
- return res;
+ if (env) {
+ selfPath = self.canonicalPath();
+ RefCacheEntry cached = RefCacheEntry::forPath(self, selfPath);
+ switch (cached.cached) {
+ case RefCacheEntry::Cached::None:
+ break;
+ case RefCacheEntry::Cached::First:
+ case RefCacheEntry::Cached::All:
+ if (!cached.canonicalPaths.isEmpty())
+ cachedPath = cached.canonicalPaths.first();
+ else
+ return res;
+ break;
+ }
+ if (cachedPath) {
+ res = env.path(cachedPath);
+ if (!res)
+ qCWarning(refLog) << "referenceCache outdated, reference at " << selfPath
+ << " leads to invalid path " << cachedPath;
+ else
+ return res;
+ }
}
}
QList<Path> visitedRefsLocal;
@@ -2972,12 +2985,10 @@ void OwningItem::addError(DomItem &, ErrorMessage msg)
void OwningItem::addErrorLocal(ErrorMessage msg)
{
QMutexLocker l(mutex());
- auto it = m_errors.constFind(msg.path);
- while (it != m_errors.constEnd() && it->path == msg.path) {
- if (*it++ == msg)
- return;
- }
- m_errors.insert(msg.path, msg);
+ quint32 &c = m_errorsCounts[msg];
+ c += 1;
+ if (c == 1)
+ m_errors.insert(msg.path, msg);
}
void OwningItem::clearErrors(ErrorGroups groups)
@@ -3369,3 +3380,5 @@ void ListPBase::writeOut(DomItem &self, OutWriter &ow, bool compact) const
} // end namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomitem_p.cpp"
diff --git a/src/qmldom/qqmldomitem_p.h b/src/qmldom/qqmldomitem_p.h
index 469001709c..9388309bf7 100644
--- a/src/qmldom/qqmldomitem_p.h
+++ b/src/qmldom/qqmldomitem_p.h
@@ -588,7 +588,9 @@ public:
} else if constexpr (domTypeIsObjWrap(T::kindValue)) {
return m_value.value<T *>();
} else {
- Q_ASSERT_X(false, "SimpleObjectWrapT", "wrapping of unexpected type");
+ // need dependent static assert to not unconditially trigger
+ static_assert(!std::is_same_v<T, T>, "wrapping of unexpected type");
+ return nullptr; // necessary to avoid warnings on INTEGRITY
}
}
@@ -1036,11 +1038,11 @@ public:
DomItem(std::shared_ptr<DomUniverse>);
void loadFile(QString filePath, QString logicalPath,
- std::function<void(Path, DomItem &, DomItem &)> callback,
- LoadOptions loadOptions);
+ std::function<void(Path, DomItem &, DomItem &)> callback, LoadOptions loadOptions,
+ std::optional<DomType> fileType = std::optional<DomType>());
void loadFile(QString canonicalFilePath, QString logicalPath, QString code, QDateTime codeDate,
- std::function<void(Path, DomItem &, DomItem &)> callback,
- LoadOptions loadOptions);
+ std::function<void(Path, DomItem &, DomItem &)> callback, LoadOptions loadOptions,
+ std::optional<DomType> fileType = std::optional<DomType>());
void loadModuleDependency(QString uri, Version v,
std::function<void(Path, DomItem &, DomItem &)> callback = nullptr,
ErrorHandler = nullptr);
@@ -1342,6 +1344,7 @@ private:
QDateTime m_lastDataUpdateAt;
QDateTime m_frozenAt;
QMultiMap<Path, ErrorMessage> m_errors;
+ QMap<ErrorMessage, quint32> m_errorsCounts;
};
template<typename T>
diff --git a/src/qmldom/qqmldomlinewriter.cpp b/src/qmldom/qqmldomlinewriter.cpp
index a2371c4ccd..6c04602a55 100644
--- a/src/qmldom/qqmldomlinewriter.cpp
+++ b/src/qmldom/qqmldomlinewriter.cpp
@@ -480,3 +480,5 @@ void LineWriter::commitLine(QString eol, TextAddType tType, int untilChar)
} // namespace Dom
} // namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomlinewriter_p.cpp"
diff --git a/src/qmldom/qqmldommoduleindex.cpp b/src/qmldom/qqmldommoduleindex.cpp
index 700537d287..47a2d9192f 100644
--- a/src/qmldom/qqmldommoduleindex.cpp
+++ b/src/qmldom/qqmldommoduleindex.cpp
@@ -145,7 +145,7 @@ ModuleIndex::~ModuleIndex()
auto it = scopes.begin();
auto end = scopes.end();
while (it != end) {
- free(*it);
+ delete *it;
++it;
}
}
diff --git a/src/qmldom/qqmldompath.cpp b/src/qmldom/qqmldompath.cpp
index c2ceeaf3cc..d901813f3a 100644
--- a/src/qmldom/qqmldompath.cpp
+++ b/src/qmldom/qqmldompath.cpp
@@ -205,24 +205,25 @@ int PathComponent::cmp(const PathComponent &p1, const PathComponent &p2)
} // namespace PathEls
-PathEls::PathComponent Path::component(int i) const
+const PathEls::PathComponent &Path::component(int i) const
{
+ static Component emptyComponent;
if (i < 0)
i += m_length;
if (i >= m_length || i < 0) {
Q_ASSERT(false && "index out of bounds");
- return Component();
+ return emptyComponent;
}
i = i - m_length - m_endOffset;
auto data = m_data.get();
while (data) {
i += data->components.length();
if (i >= 0)
- return data->components.at(i);
+ return qAsConst(data)->components[i];
data = data->parent.get();
}
Q_ASSERT(false && "Invalid data reached while resolving a seemengly valid index in Path (inconsisten Path object)");
- return Component();
+ return emptyComponent;
}
Path Path::operator[](int i) const
@@ -247,7 +248,7 @@ PathIterator Path::end() const
PathRoot Path::headRoot() const
{
- auto comp = component(0);
+ auto &comp = component(0);
if (PathEls::Root const * r = comp.base()->asRoot())
return r->contextKind;
return PathRoot::Other;
@@ -285,7 +286,7 @@ index_type Path::headIndex(index_type defaultValue) const
function<bool (DomItem)> Path::headFilter() const
{
- auto comp = component(0);
+ auto &comp = component(0);
if (PathEls::Filter const * f = comp.base()->asFilter()) {
return f->filterFunction;
}
@@ -939,7 +940,7 @@ void Path::dump(Sink sink) const
{
bool first = true;
for (int i = 0; i < m_length; ++i) {
- auto c = component(i);
+ auto &c = component(i);
if (!c.hasSquareBrackets()) {
if (!first || (c.kind() != Kind::Root && c.kind() != Kind::Current))
sink(u".");
@@ -997,3 +998,5 @@ Path Path::fromString(QString s, ErrorHandler errorHandler)
} // end namespace Dom
} // end namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldompath_p.cpp"
diff --git a/src/qmldom/qqmldompath_p.h b/src/qmldom/qqmldompath_p.h
index 7fe68428d7..f0fddcabea 100644
--- a/src/qmldom/qqmldompath_p.h
+++ b/src/qmldom/qqmldompath_p.h
@@ -124,7 +124,8 @@ public:
virtual const Filter *asFilter() const { return nullptr; }
};
-class Empty: public Base {
+class Empty final : public Base
+{
public:
Empty() = default;
Kind kind() const override { return Kind::Empty; }
@@ -133,7 +134,8 @@ public:
const Empty * asEmpty() const override { return this; }
};
-class Field: public Base {
+class Field final : public Base
+{
public:
Field() = default;
Field(QStringView n): fieldName(n) {}
@@ -147,7 +149,8 @@ public:
QStringView fieldName;
};
-class Index: public Base {
+class Index final : public Base
+{
public:
Index() = default;
Index(index_type i): indexValue(i) {}
@@ -161,7 +164,8 @@ public:
index_type indexValue = -1;
};
-class Key: public Base {
+class Key final : public Base
+{
public:
Key() = default;
Key(QString n) : keyValue(n) { }
@@ -180,7 +184,8 @@ public:
QString keyValue;
};
-class Root: public Base {
+class Root final : public Base
+{
public:
Root() = default;
Root(PathRoot r): contextKind(r), contextName() {}
@@ -229,7 +234,8 @@ public:
QStringView contextName;
};
-class Current: public Base {
+class Current final : public Base
+{
public:
Current() = default;
Current(PathCurrent c): contextKind(c) {}
@@ -283,7 +289,8 @@ public:
QStringView contextName;
};
-class Any: public Base {
+class Any final : public Base
+{
public:
Any() = default;
Kind kind() const override { return Kind::Any; }
@@ -293,7 +300,8 @@ public:
const Any *asAny() const override { return this; }
};
-class QMLDOM_EXPORT Filter: public Base {
+class QMLDOM_EXPORT Filter final : public Base
+{
public:
Filter() = default;
Filter(std::function<bool(DomItem)> f, QStringView filterDescription = u"<native code filter>");
@@ -718,10 +726,12 @@ public:
using iterator_category = std::forward_iterator_tag;
static int cmp(const Path &p1, const Path &p2);
- Component component(int i) const;
+
private:
+ const Component &component(int i) const;
explicit Path(quint16 endOffset, quint16 length, std::shared_ptr<PathEls::PathData> data);
friend class QQmlJS::Dom::PathEls::TestPaths;
+ friend class FieldFilter;
friend size_t qHash(const Path &, size_t);
Path noEndOffset() const;
@@ -762,8 +772,8 @@ public:
Path operator *() const { return currentEl.head(); }
PathIterator operator ++() { currentEl = currentEl.dropFront(); return *this; }
PathIterator operator ++(int) { PathIterator res{currentEl}; currentEl = currentEl.dropFront(); return res; }
- bool operator ==(const PathIterator &o) { return currentEl == o.currentEl; }
- bool operator !=(const PathIterator &o) { return currentEl != o.currentEl; }
+ bool operator ==(const PathIterator &o) const { return currentEl == o.currentEl; }
+ bool operator !=(const PathIterator &o) const { return currentEl != o.currentEl; }
};
class Source {
diff --git a/src/qmldom/qqmldomreformatter.cpp b/src/qmldom/qqmldomreformatter.cpp
index d627af12ef..ee48a71c29 100644
--- a/src/qmldom/qqmldomreformatter.cpp
+++ b/src/qmldom/qqmldomreformatter.cpp
@@ -972,7 +972,11 @@ protected:
// to check
bool visit(TypeExpression *) override { return true; }
- bool visit(SuperLiteral *) override { return true; }
+ bool visit(SuperLiteral *) override
+ {
+ out("super");
+ return true;
+ }
bool visit(PatternProperty *) override { return true; }
bool visit(ComputedPropertyName *) override
{
@@ -989,7 +993,61 @@ protected:
}
bool visit(YieldExpression *) override { return true; }
bool visit(ClassExpression *) override { return true; }
- bool visit(ClassDeclaration *) override { return true; }
+
+ // Return false because we want to omit default function callsĀ in accept0 implementation.
+ bool visit(ClassDeclaration *ast) override
+ {
+ preVisit(ast);
+ out(ast->classToken);
+ out(" ");
+ out(ast->name);
+ if (ast->heritage) {
+ out(" extends ");
+ accept(ast->heritage);
+ }
+ out(" {");
+ int baseIndent = lw.increaseIndent();
+ for (ClassElementList *it = ast->elements; it; it = it->next) {
+ PatternProperty *property = it->property;
+ lw.newline();
+ preVisit(property);
+ if (it->isStatic)
+ out("static ");
+ if (property->type == PatternProperty::Getter)
+ out("get ");
+ else if (property->type == PatternProperty::Setter)
+ out("set ");
+ FunctionExpression *f = AST::cast<FunctionExpression *>(property->initializer);
+ const bool scoped = f->lbraceToken.length != 0;
+ out(f->functionToken);
+ out(f->lparenToken);
+ accept(f->formals);
+ out(f->rparenToken);
+ out(f->lbraceToken);
+ if (scoped)
+ ++expressionDepth;
+ if (f->body) {
+ if (f->body->next || scoped) {
+ lnAcceptIndented(f->body);
+ lw.newline();
+ } else {
+ baseIndent = lw.increaseIndent(1);
+ accept(f->body);
+ lw.decreaseIndent(1, baseIndent);
+ }
+ }
+ if (scoped)
+ --expressionDepth;
+ out(f->rbraceToken);
+ lw.newline();
+ postVisit(property);
+ }
+ lw.decreaseIndent(1, baseIndent);
+ out("}");
+ postVisit(ast);
+ return false;
+ }
+
bool visit(ClassElementList *) override { return true; }
bool visit(Program *) override { return true; }
bool visit(NameSpaceImport *) override { return true; }
diff --git a/src/qmldom/qqmldomtop.cpp b/src/qmldom/qqmldomtop.cpp
index c41402d761..7d2500488b 100644
--- a/src/qmldom/qqmldomtop.cpp
+++ b/src/qmldom/qqmldomtop.cpp
@@ -48,7 +48,6 @@
#include <QtQml/private/qqmljsastvisitor_p.h>
#include <QtQml/private/qqmljsast_p.h>
-#include <QtCore/QAtomicInt>
#include <QtCore/QBasicMutex>
#include <QtCore/QCborArray>
#include <QtCore/QDebug>
@@ -157,11 +156,14 @@ DomUniverse::DomUniverse(QString universeName, Options options):
std::shared_ptr<DomUniverse> DomUniverse::guaranteeUniverse(std::shared_ptr<DomUniverse> univ)
{
- static QAtomicInt counter(0);
+ const auto next = [] {
+ static std::atomic<int> counter(0);
+ return counter.fetch_add(1, std::memory_order_relaxed) + 1;
+ };
if (univ)
return univ;
return std::shared_ptr<DomUniverse>(
- new DomUniverse(QLatin1String("universe") + QString::number(++counter)));
+ new DomUniverse(QLatin1String("universe") + QString::number(next())));
}
DomItem DomUniverse::create(QString universeName, Options options)
@@ -248,56 +250,58 @@ std::shared_ptr<OwningItem> DomUniverse::doCopy(DomItem &) const
}
void DomUniverse::loadFile(DomItem &self, QString filePath, QString logicalPath, Callback callback,
- LoadOptions loadOptions)
+ LoadOptions loadOptions, std::optional<DomType> fileType)
{
- loadFile(self, filePath, logicalPath, QString(), QDateTime::fromMSecsSinceEpoch(0), callback, loadOptions);
+ loadFile(self, filePath, logicalPath, QString(), QDateTime::fromMSecsSinceEpoch(0), callback,
+ loadOptions, fileType);
}
-void DomUniverse::loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath,
- QString code, QDateTime codeDate, Callback callback,
- LoadOptions loadOptions)
-{
- if (canonicalFilePath.endsWith(u".qml", Qt::CaseInsensitive) ||
- canonicalFilePath.endsWith(u".qmlannotation", Qt::CaseInsensitive) ||
- canonicalFilePath.endsWith(u".ui", Qt::CaseInsensitive)) {
- m_queue.enqueue(ParsingTask{
- QDateTime::currentDateTime(),
- loadOptions,
- DomType::QmlFile,
- canonicalFilePath,
- logicalPath,
- code,
- codeDate,
- self.ownerAs<DomUniverse>(),
- callback});
+static DomType fileTypeForPath(DomItem &self, QString canonicalFilePath)
+{
+ if (canonicalFilePath.endsWith(u".qml", Qt::CaseInsensitive)
+ || canonicalFilePath.endsWith(u".qmlannotation", Qt::CaseInsensitive)) {
+ return DomType::QmlFile;
} else if (canonicalFilePath.endsWith(u".qmltypes")) {
- m_queue.enqueue(ParsingTask{
- QDateTime::currentDateTime(),
- loadOptions,
- DomType::QmltypesFile,
- canonicalFilePath,
- logicalPath,
- code,
- codeDate,
- self.ownerAs<DomUniverse>(),
- callback});
- } else if (QStringView(u"qmldir").compare(QFileInfo(canonicalFilePath).fileName(), Qt::CaseInsensitive) == 0) {
- m_queue.enqueue(ParsingTask{
- QDateTime::currentDateTime(),
- loadOptions,
- DomType::QmldirFile,
- canonicalFilePath,
- logicalPath,
- code,
- codeDate,
- self.ownerAs<DomUniverse>(),
- callback});
+ return DomType::QmltypesFile;
+ } else if (QStringView(u"qmldir").compare(QFileInfo(canonicalFilePath).fileName(),
+ Qt::CaseInsensitive)
+ == 0) {
+ return DomType::QmltypesFile;
} else if (QFileInfo(canonicalFilePath).isDir()) {
- m_queue.enqueue(ParsingTask { QDateTime::currentDateTime(), loadOptions,
- DomType::QmlDirectory, canonicalFilePath, logicalPath, code,
- codeDate, self.ownerAs<DomUniverse>(), callback });
+ return DomType::QmlDirectory;
} else {
- self.addError(myErrors().error(tr("Ignoring request to load file of unknown type %1, calling callback immediately").arg(canonicalFilePath)).handle());
+ self.addError(DomUniverse::myErrors()
+ .error(QCoreApplication::translate("Dom::filteTypeForPath",
+ "Could not detect type of file %1")
+ .arg(canonicalFilePath))
+ .handle());
+ }
+ return DomType::Empty;
+}
+
+void DomUniverse::loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath,
+ QString code, QDateTime codeDate, Callback callback,
+ LoadOptions loadOptions, std::optional<DomType> fileType)
+{
+ DomType fType = (bool(fileType) ? (*fileType) : fileTypeForPath(self, canonicalFilePath));
+ switch (fType) {
+ case DomType::QmlFile:
+ case DomType::QmltypesFile:
+ case DomType::QmldirFile:
+ case DomType::QmlDirectory: {
+ // Protect the queue from concurrent access.
+ QMutexLocker l(mutex());
+ m_queue.enqueue(ParsingTask { QDateTime::currentDateTime(), loadOptions, fType,
+ canonicalFilePath, logicalPath, code, codeDate,
+ self.ownerAs<DomUniverse>(), callback });
+ break;
+ }
+ default:
+ self.addError(myErrors()
+ .error(tr("Ignoring request to load file %1 of unexpected type %2, "
+ "calling callback immediately")
+ .arg(canonicalFilePath, domTypeToString(fType)))
+ .handle());
Q_ASSERT(false && "loading non supported file type");
callback(Path(), DomItem::empty, DomItem::empty);
return;
@@ -350,7 +354,14 @@ updateEntry(DomItem &univ, std::shared_ptr<T> newItem,
void DomUniverse::execQueue()
{
- ParsingTask t = m_queue.dequeue();
+ ParsingTask t;
+ {
+ // Protect the queue from concurrent access.
+ QMutexLocker l(mutex());
+ if (m_queue.isEmpty())
+ return;
+ t = m_queue.dequeue();
+ }
shared_ptr<DomUniverse> topPtr = t.requestingUniverse.lock();
if (!topPtr) {
myErrors().error(tr("Ignoring callback for loading of %1: universe is not valid anymore").arg(t.canonicalPath)).handle();
@@ -626,7 +637,8 @@ void LoadInfo::advanceLoad(DomItem &self)
[this, self, dep](Path, DomItem &, DomItem &) mutable {
finishedLoadingDep(self, dep);
},
- nullptr, nullptr, LoadOption::DefaultLoad, self.errorHandler());
+ nullptr, nullptr, LoadOption::DefaultLoad, dep.fileType,
+ self.errorHandler());
else
Q_ASSERT(false && "missing environment");
} else {
@@ -746,12 +758,13 @@ void LoadInfo::doAddDependencies(DomItem &self)
DomItem import = currentImports.index(i);
if (const Import *importPtr = import.as<Import>()) {
if (!importPtr->filePath().isEmpty()) {
- addDependency(
- self,
- Dependency { QString(), importPtr->version, importPtr->filePath() });
+ addDependency(self,
+ Dependency { QString(), importPtr->version, importPtr->filePath(),
+ DomType::Empty });
} else {
addDependency(self,
- Dependency { importPtr->uri, importPtr->version, QString() });
+ Dependency { importPtr->uri, importPtr->version, QString(),
+ DomType::ModuleIndex });
}
}
}
@@ -763,7 +776,8 @@ void LoadInfo::doAddDependencies(DomItem &self)
Path canonicalPath = ref->referredObjectPath[2];
if (canonicalPath && !canonicalPath.headName().isEmpty())
addDependency(self,
- Dependency { QString(), Version(), canonicalPath.headName() });
+ Dependency { QString(), Version(), canonicalPath.headName(),
+ DomType::QmltypesFile });
}
}
DomItem currentQmlFiles = el.field(Fields::currentItem).field(Fields::qmlFiles);
@@ -772,9 +786,9 @@ void LoadInfo::doAddDependencies(DomItem &self)
if (const Reference *ref = el.as<Reference>()) {
Path canonicalPath = ref->referredObjectPath[2];
if (canonicalPath && !canonicalPath.headName().isEmpty())
- addDependency(
- self,
- Dependency { QString(), Version(), canonicalPath.headName() });
+ addDependency(self,
+ Dependency { QString(), Version(), canonicalPath.headName(),
+ DomType::QmlFile });
}
return true;
});
@@ -783,7 +797,9 @@ void LoadInfo::doAddDependencies(DomItem &self)
for (Path qmldirPath : elPtr->qmldirsToLoad(el)) {
Path canonicalPath = qmldirPath[2];
if (canonicalPath && !canonicalPath.headName().isEmpty())
- addDependency(self, Dependency { QString(), Version(), canonicalPath.headName() });
+ addDependency(self,
+ Dependency { QString(), Version(), canonicalPath.headName(),
+ DomType::QmldirFile });
}
} else if (!el) {
self.addError(DomEnvironment::myErrors().error(
@@ -1147,10 +1163,11 @@ std::shared_ptr<DomEnvironment> DomEnvironment::makeCopy(DomItem &self) const
void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPath,
DomTop::Callback loadCallback, DomTop::Callback directDepsCallback,
- DomTop::Callback endCallback, LoadOptions loadOptions, ErrorHandler h)
+ DomTop::Callback endCallback, LoadOptions loadOptions,
+ std::optional<DomType> fileType, ErrorHandler h)
{
loadFile(self, filePath, logicalPath, QString(), QDateTime::fromMSecsSinceEpoch(0),
- loadCallback, directDepsCallback, endCallback, loadOptions, h);
+ loadCallback, directDepsCallback, endCallback, loadOptions, fileType, h);
}
std::shared_ptr<OwningItem> DomEnvironment::doCopy(DomItem &) const
@@ -1167,11 +1184,10 @@ std::shared_ptr<OwningItem> DomEnvironment::doCopy(DomItem &) const
void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPath, QString code,
QDateTime codeDate, Callback loadCallback,
Callback directDepsCallback, Callback endCallback,
- LoadOptions loadOptions, ErrorHandler h)
+ LoadOptions loadOptions, std::optional<DomType> fileType,
+ ErrorHandler h)
{
QFileInfo fileInfo(filePath);
- bool isDir = fileInfo.isDir();
- QString ext = fileInfo.suffix();
QString canonicalFilePath = fileInfo.canonicalFilePath();
if (canonicalFilePath.isEmpty()) {
if (code.isNull()) {
@@ -1190,7 +1206,9 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa
}
}
shared_ptr<ExternalItemInfoBase> oldValue, newValue;
- if (isDir) {
+ DomType fType = (bool(fileType) ? (*fileType) : fileTypeForPath(self, canonicalFilePath));
+ switch (fType) {
+ case DomType::QmlDirectory: {
{
QMutexLocker l(mutex());
auto it = m_qmlDirectoryWithPath.find(canonicalFilePath);
@@ -1217,10 +1235,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa
self.universe().loadFile(
canonicalFilePath, logicalPath, code, codeDate,
callbackForQmlDirectory(self, loadCallback, directDepsCallback, endCallback),
- loadOptions);
+ loadOptions, fType);
return;
}
- } else if (ext == u"qml" || ext == u"ui" || ext == u"qmlannotation") {
+ } break;
+ case DomType::QmlFile: {
{
QMutexLocker l(mutex());
auto it = m_qmlFileWithPath.find(canonicalFilePath);
@@ -1246,10 +1265,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa
self.universe().loadFile(
canonicalFilePath, logicalPath, code, codeDate,
callbackForQmlFile(self, loadCallback, directDepsCallback, endCallback),
- loadOptions);
+ loadOptions, fType);
return;
}
- } else if (ext == u"qmltypes") {
+ } break;
+ case DomType::QmltypesFile: {
{
QMutexLocker l(mutex());
auto it = m_qmltypesFileWithPath.find(canonicalFilePath);
@@ -1276,10 +1296,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa
self.universe().loadFile(
canonicalFilePath, logicalPath, code, codeDate,
callbackForQmltypesFile(self, loadCallback, directDepsCallback, endCallback),
- loadOptions);
+ loadOptions, fType);
return;
}
- } else if (fileInfo.fileName() == u"qmldir") {
+ } break;
+ case DomType::QmldirFile: {
{
QMutexLocker l(mutex());
auto it = m_qmldirFileWithPath.find(canonicalFilePath);
@@ -1305,10 +1326,11 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa
self.universe().loadFile(
canonicalFilePath, logicalPath, code, codeDate,
callbackForQmldirFile(self, loadCallback, directDepsCallback, endCallback),
- loadOptions);
+ loadOptions, fType);
return;
}
- } else {
+ } break;
+ default: {
myErrors().error(tr("Unexpected file to load: '%1'").arg(filePath)).handle(h);
if (loadCallback)
loadCallback(self.canonicalPath(), DomItem::empty, DomItem::empty);
@@ -1317,6 +1339,7 @@ void DomEnvironment::loadFile(DomItem &self, QString filePath, QString logicalPa
if (endCallback)
endCallback(self.canonicalPath(), DomItem::empty, DomItem::empty);
return;
+ } break;
}
Path p = self.copy(newValue).canonicalPath();
std::shared_ptr<LoadInfo> lInfo = loadInfo(p);
@@ -2310,3 +2333,5 @@ bool RefCacheEntry::addForPath(DomItem &el, Path canonicalPath, const RefCacheEn
} // end namespace QQmlJS
QT_END_NAMESPACE
+
+#include "moc_qqmldomtop_p.cpp"
diff --git a/src/qmldom/qqmldomtop_p.h b/src/qmldom/qqmldomtop_p.h
index 4c905991af..eeb0038d09 100644
--- a/src/qmldom/qqmldomtop_p.h
+++ b/src/qmldom/qqmldomtop_p.h
@@ -61,6 +61,7 @@
#include <QtCore/QCborMap>
#include <memory>
+#include <optional>
QT_BEGIN_NAMESPACE
@@ -253,9 +254,11 @@ public:
}
void loadFile(DomItem &self, QString filePath, QString logicalPath, Callback callback,
- LoadOptions loadOptions);
+ LoadOptions loadOptions,
+ std::optional<DomType> fileType = std::optional<DomType>());
void loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath, QString code,
- QDateTime codeDate, Callback callback, LoadOptions loadOptions);
+ QDateTime codeDate, Callback callback, LoadOptions loadOptions,
+ std::optional<DomType> fileType = std::optional<DomType>());
void execQueue();
std::shared_ptr<ExternalItemPair<GlobalScope>> globalScopeWithName(QString name) const
@@ -517,6 +520,7 @@ public:
QString uri; // either dotted uri or file:, http: https: uri
Version version;
QString filePath; // for file deps
+ DomType fileType;
};
class QMLDOM_EXPORT LoadInfo final : public OwningItem
@@ -683,10 +687,13 @@ public:
void loadFile(DomItem &self, QString filePath, QString logicalPath, Callback loadCallback,
Callback directDepsCallback, Callback endCallback, LoadOptions loadOptions,
+ std::optional<DomType> fileType = std::optional<DomType>(),
ErrorHandler h = nullptr);
void loadFile(DomItem &self, QString canonicalFilePath, QString logicalPath, QString code,
QDateTime codeDate, Callback loadCallback, Callback directDepsCallback,
- Callback endCallback, LoadOptions loadOptions, ErrorHandler h = nullptr);
+ Callback endCallback, LoadOptions loadOptions,
+ std::optional<DomType> fileType = std::optional<DomType>(),
+ ErrorHandler h = nullptr);
void loadModuleDependency(DomItem &self, QString uri, Version v,
Callback loadCallback = nullptr, Callback endCallback = nullptr,
ErrorHandler = nullptr);