Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmldomoutwriter_p.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QMLDOMOUTWRITER_P_H
5#define QMLDOMOUTWRITER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qqmldom_global.h"
19#include "qqmldom_fwd_p.h"
23
24#include <QtCore/QLoggingCategory>
25
26QT_BEGIN_NAMESPACE
27
28namespace QQmlJS {
29namespace Dom {
30
31class QMLDOM_EXPORT OutWriter
32{
33public:
34 int indent = 0;
35 bool indentNextlines = false;
36 // TODO QTBUG-139623
37 bool skipComments = false;
38 LineWriter &lineWriter;
39 QString writtenStr;
40 using RegionToCommentMap = QMap<FileLocationRegion, CommentedElement>;
41 QStack<RegionToCommentMap> pendingComments;
42 QStringView code;
43 bool isFormatterEnabled = true;
44
45 using OffsetToDisabledRegionMap = QMap<quint32, SourceLocation>;
46 OffsetToDisabledRegionMap formatDisabledRegions;
47
48 explicit OutWriter(LineWriter &lw) : lineWriter(lw)
49 {
50 lineWriter.addInnerSink([this](QStringView s) { writtenStr.append(s); });
51 lineWriter.addTextAddCallback([this](LineWriter &, LineWriter::TextAddType tt) {
52 if (indentNextlines && tt == LineWriter::TextAddType::Normal
53 && QStringView(lineWriter.currentLine()).trimmed().isEmpty())
54 lineWriter.setLineIndent(indent);
55 return true;
56 });
57 }
58
59 OutWriter(std::shared_ptr<ExternalOwningItem> ownerFile, LineWriter &lw)
60 : OutWriter(lw)
61 {
62 if (!ownerFile)
63 return;
64
65 code = ownerFile->code();
66
67 const auto engine = [&ownerFile]() -> std::shared_ptr<QQmlJS::Engine> {
68 if (auto qmlfilePtr = std::dynamic_pointer_cast<QmlFile>(ownerFile))
69 return qmlfilePtr->engine();
70 else if (auto jsfilePtr = std::dynamic_pointer_cast<JsFile>(ownerFile))
71 return jsfilePtr->engine();
72 return nullptr;
73 }();
74
75 if (engine)
76 scanFormatDirectives(code, engine->comments());
77 }
78
79 int increaseIndent(int level = 1)
80 {
81 int oldIndent = indent;
82 indent += lineWriter.options().formatOptions.indentSize * level;
83 return oldIndent;
84 }
85 int decreaseIndent(int level = 1, int expectedIndent = -1)
86 {
87 indent -= lineWriter.options().formatOptions.indentSize * level;
88 Q_ASSERT(expectedIndent < 0 || expectedIndent == indent);
89 return indent;
90 }
91
92 void itemStart(const DomItem &it);
93 void itemEnd();
94 void writePreComment(FileLocationRegion region);
95 void writePostComment(FileLocationRegion regino);
96
97 quint32 counter() const { return lineWriter.counter(); }
98 OutWriter &writeRegion(const FileLocations::Tree &fLoc, FileLocationRegion region, QStringView toWrite);
99 OutWriter &writeRegion(const FileLocations::Tree &fLoc, FileLocationRegion region);
100 OutWriter &ensureNewline(int nNewlines = 1)
101 {
102 if (formatterEnabled())
103 lineWriter.ensureNewline(nNewlines);
104 return *this;
105 }
106
107 OutWriter &ensureSpace()
108 {
109 if (formatterEnabled())
110 lineWriter.ensureSpace();
111 return *this;
112 }
113
114 OutWriter &ensureSpace(QStringView space)
115 {
116 if (formatterEnabled())
117 lineWriter.ensureSpace(space);
118 return *this;
119 }
120
121 OutWriter &newline()
122 {
123 if (formatterEnabled())
124 lineWriter.newline();
125 return *this;
126 }
127
128 OutWriter &write(QStringView v, LineWriter::TextAddType t = LineWriter::TextAddType::Normal)
129 {
130 if (formatterEnabled())
131 lineWriter.write(v, t);
132 return *this;
133 }
134 void flush()
135 {
136 if (formatterEnabled())
137 lineWriter.flush();
138 }
139
140 void eof(bool ensureNewline = true)
141 {
142 if (formatterEnabled())
143 lineWriter.eof(ensureNewline);
144 }
145
146 int addNewlinesAutospacerCallback(int nLines)
147 {
148 return lineWriter.addNewlinesAutospacerCallback(nLines);
149 }
150 int addTextAddCallback(std::function<bool(LineWriter &, LineWriter::TextAddType)> callback)
151 {
152 return lineWriter.addTextAddCallback(callback);
153 }
154 bool removeTextAddCallback(int i) { return lineWriter.removeTextAddCallback(i); }
155
156 void maybeWriteComment(const Comment &comment);
157 bool formatterEnabled() const;
158 bool shouldFormat(const FileLocations::Tree &fLoc, FileLocationRegion region);
159 void maybeWriteDisabledRegion(const SourceLocation &loc);
160 void scanFormatDirectives(QStringView code, const QList<SourceLocation> &comments);
161 void writeDisabledRegion(const SourceLocation &loc);
162 QStringView attachedDisableCode(quint32 offset) const;
163};
164
165} // end namespace Dom
166} // end namespace QQmlJS
167
168QT_END_NAMESPACE
169#endif // QMLDOMOUTWRITER_P_H
std::pair< AST::Node *, CommentAnchor > CommentKey
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
void addNodeRanges(AST::Node *rootNode)
bool preVisit(Node *n) override
bool visit(Block *block) override
void addSourceLocations(Node *n, const SourceLocation &sourceLocation)
void addItemRanges(const DomItem &item, const FileLocations::Tree &itemLocations, const Path &currentP)
void addSourceLocations(Node *n, qsizetype start, qsizetype end, CommentAnchor commentAnchor)
QMap< qsizetype, ElementRef > ends
static const QSet< int > kindsToSkip()
static bool shouldSkipRegion(const DomItem &item, FileLocationRegion region)
returns true if comments should skip attaching to this region
QMap< qsizetype, ElementRef > starts
CommentCollector(MutableDomItem item)
void collectComments(const std::shared_ptr< Engine > &engine, AST::Node *rootNode, const std::shared_ptr< AstComments > &astComments)
Collects and associates comments with javascript AST::Node pointers or with MutableDomItem.
Extracts various pieces and information out of a rawComment string.
CommentLinker(QStringView code, ElementRef &commentedElement, const AstRangesVisitor &ranges, qsizetype &lastPostCommentPostEnd, const SourceLocation &commentLocation)
Represents a comment.
void write(OutWriter &lw) const
CommentInfo info() const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
Expose attributes to the Dom.
Keeps the comment associated with an element.
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writePre(OutWriter &lw) const
void writePost(OutWriter &lw) const
A value type that references any element of the Dom.
DomItem path(const Path &p, const ErrorHandler &h=&defaultErrorHandler) const
DomItem subMapItem(const Map &map) const
InternalKind internalKind() const
Path pathFromOwner() const
ElementRef(const Path &path, FileLocationRegion region, qsizetype size)
ElementRef(AST::Node *node, qsizetype size, CommentAnchor commentAnchor)
std::variant< NodeRef, RegionRef > element
Path withPath(const Path &toAdd, bool avoidToAddAsBase=false) const
Returns a copy of this with toAdd appended to it.
Keeps the comments associated with a DomItem.
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
FileLocationRegion regionName
A vistor that visits all the AST:Node.
Provides entities to maintain mappings between elements and their location in a file.
static void writeComments(OutWriter &lw, const QList< Comment > &comments)
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")
#define QMLDOM_EXPORT