12#include <QtQml/private/qqmljsastvisitor_p.h>
13#include <QtQml/private/qqmljsast_p.h>
14#include <QtQml/private/qqmljslexer_p.h>
107 if (expectedEnd.
size() > 1) {
120 }
else if (!
c.isSpace()) {
153 warnings.append(
tr(
"Non whitespace char %1 after comment end at %2")
196 cont = cont && self.dvValueField(visitor, Fields::rawComment,
rawComment());
197 cont = cont && self.dvValueField(visitor, Fields::newlinesBefore,
newlinesBefore());
241 cont = cont && self.dvWrapField(visitor, Fields::preComments,
preComments);
242 cont = cont && self.dvWrapField(visitor, Fields::postComments,
postComments);
252 c.write(lw, (locs ? &((*locs)[
i++]) :
nullptr));
261 c.write(lw, (locs ? &((*locs)[
i++]) :
nullptr));
299 operator bool()
const
333#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
383 if (!itemLocations) {
385 qCWarning(commentsLog) <<
"reached item" <<
item.canonicalPath() <<
"without locations";
390 auto regs = itemLocations->info().regions;
394 if (!
starts.contains(startI))
396 if (!
ends.contains(endI))
397 ends.insert(endI, { currentP,
it.key(), endI - startI });
401 auto subMaps = itemLocations->subItems();
403 addItemRanges(
item.path(
it.key()),
404 std::static_pointer_cast<AttachedInfoT<FileLocations>>(
it.value()),
405 currentP.path(
it.key()));
413 AST::Node::Kind_ArgumentList,
414 AST::Node::Kind_ElementList,
415 AST::Node::Kind_FormalParameterList,
416 AST::Node::Kind_ImportsList,
417 AST::Node::Kind_ExportsList,
418 AST::Node::Kind_PropertyDefinitionList,
419 AST::Node::Kind_StatementList,
420 AST::Node::Kind_VariableDeclarationList,
421 AST::Node::Kind_ClassElementList,
422 AST::Node::Kind_PatternElementList,
423 AST::Node::Kind_PatternPropertyList,
424 AST::Node::Kind_TypeArgument,
426 .unite(VisitAll::uiKinds());
437 bool cont = self.dvItemField(visitor, Fields::commentedElements, [
this, &self]() {
438 return self.subMapItem(
Map(
439 self.pathFromOwner().field(Fields::commentedElements),
444 quintptr v = key.split(QLatin1Char(
'_')).last().toULong(&ok, 16);
446 AST::Node *n = reinterpret_cast<AST::Node *>(v);
447 if (ok && m_commentedElements.contains(n))
448 return map.wrap(PathEls::Key(key), m_commentedElements[n]);
453 for (AST::Node *n : m_commentedElements.keys()) {
456 name = QString::number(n->kind);
458 res.insert(name + QStringLiteral(u
"_") + QString::number(quintptr(n), 16));
471 return collectComments(scriptPtr->engine(), scriptPtr->ast(), scriptPtr->astComments(),
472 item, FileLocations::treeOf(itemItem));
473 }
else if (std::shared_ptr<QmlFile> qmlFilePtr =
item.ownerAs<
QmlFile>()) {
474 return collectComments(qmlFilePtr->engine(), qmlFilePtr->ast(), qmlFilePtr->astComments(),
475 item, qmlFilePtr->fileLocationsTree());
478 <<
"collectComments works with QmlFile and ScriptExpression, not with"
479 <<
item.internalKindStr();
499 quint32 lastPostCommentPostEnd = 0;
512 commentStartStr = code.
mid(iPre - 2, 2);
539 while (iPost < code.
size()) {
571 auto iStart = ranges.
starts.lowerBound(cLoc.begin());
572 auto iEnd = ranges.
ends.lowerBound(cLoc.begin());
575 auto checkElementBefore = [&]() {
580 auto preStart = iStart;
581 if (preEnd != ranges.
ends.begin()) {
583 if (iStart == ranges.
starts.begin() || (--preStart).
key() < preEnd.key()) {
593 if (
i <= preEnd.key() ||
i < lastPostCommentPostEnd
594 || iEnd == ranges.
ends.end()) {
595 commentEl = preEnd.value();
597 lastPostCommentPostEnd = iPost + 1;
603 auto checkElementAfter = [&]() {
606 if (iStart != ranges.
starts.end()) {
608 if (iEnd == ranges.
ends.end() || iEnd.key() > iStart.key()) {
612 commentEl = iStart.value();
616 if (iStart == ranges.
starts.begin()) {
619 commentEl = iStart.value();
622 auto checkInsideEl = [&]() {
625 auto preIStart = iStart;
626 if (iStart == ranges.
starts.begin()) {
627 commentEl = iStart.value();
644 checkElementBefore();
648 checkElementBefore();
654 <<
"adding before root node";
655 if (
rootItem && (rootItemLocations || !
n)) {
658 rootItemLocations->info()
659 .regions.value(
QString(), rootItemLocations->info().fullRegion)
664 commentEl.
size =
n->lastSourceLocation().end() -
n->firstSourceLocation().begin();
668 Comment comment(code.
mid(iPre, iPost - iPre), preNewline);
669 if (commentEl.
element.index() == 0 && std::get<0>(commentEl.
element)) {
675 }
else if (commentEl.
element.index() == 1) {
677 .path(std::get<1>(commentEl.
element).path)
678 .field(Fields::comments);
681 rCommentsPtr->addPreComment(comment, std::get<1>(commentEl.
element).regionName);
683 rCommentsPtr->addPostComment(comment,
684 std::get<1>(commentEl.
element).regionName);
690 <<
"Failed: no item or node to attach comment" << comment.
rawComment();
701 AST::Node::accept(
n,
this);
708 auto &cEls = comments->commentedElements();
709 if (cEls.contains(
n))
710 nodeComments += cEls[
n].commentGroups(
711 combine(
n->firstSourceLocation(),
n->lastSourceLocation()));
728 return v.nodeComments;
734 if (!regionComments.isEmpty())
735 cont = cont && self.dvWrapField(visitor, Fields::regionComments, regionComments);
constexpr char16_t unicode() const noexcept
Returns the numeric Unicode value of the QChar.
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
constexpr bool isSpace() const noexcept
Returns true if the character is a separator character (Separator_* categories or certain code points...
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
void resize(qsizetype size)
void accept(BaseVisitor *visitor)
@ Kind_UiObjectMemberList
@ Kind_UiObjectDefinition
@ Kind_UiVersionSpecifier
@ Kind_UiObjectInitializer
void addNodeRanges(AST::Node *rootNode)
bool preVisit(Node *n) override
QMap< quint32, ElementRef > ends
void addItemRanges(DomItem item, FileLocations::Tree itemLocations, Path currentP)
AstRangesVisitor()=default
static const QSet< int > kindsToSkip()
void throwRecursionDepthError() override
QMap< quint32, ElementRef > starts
FileLocations::Tree rootItemLocations
ElementRef(AST::Node *node, quint32 size)
ElementRef(Path path, QString region, quint32 size)
std::variant< AST::Node *, RegionRef > element
std::shared_ptr< AttachedInfoT< FileLocations > > Tree
void endSourceLocation(PendingSourceLocationId)
PendingSourceLocationId startSourceLocation(SourceLocation *)
OutWriter & ensureNewline(int nNewlines=1)
OutWriter & ensureSpace()
OutWriter & write(QStringView v, LineWriter::TextAddType t=LineWriter::TextAddType::Normal)
A vistor that visits all the AST:Node.
static QSet< int > uiKinds()
returns a set with all Ui* Nodes (i.e.
const_iterator cbegin() const noexcept
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
constexpr qsizetype size() const noexcept
Returns the size of this string view, in UTF-16 code units (that is, surrogate pairs count as two for...
constexpr QChar at(qsizetype n) const noexcept
Returns the character at position n in this string view.
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype size() const
Returns the number of characters in this string.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
QMLDOM_EXPORT QCborValue locationToData(SourceLocation loc, QStringView strValue=u"")
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei const GLchar *const * path
const QQuickItem * rootItem(const I &item)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QList< QPair< QString, QString > > Map
\inmodule QtCore \reentrant