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"
20#include "qqmldomattachedinfo_p.h"
21#include "qqmldomlinewriter_p.h"
22
23#include <QtCore/QLoggingCategory>
24
25QT_BEGIN_NAMESPACE
26
27namespace QQmlJS {
28namespace Dom {
29
30class QMLDOM_EXPORT OutWriterState
31{
32public:
33 OutWriterState(Path itPath, DomItem &it, FileLocations::Tree fLoc);
34
35 void closeState(OutWriter &);
36
37 Path itemCanonicalPath;
38 DomItem item;
39 PendingSourceLocationId fullRegionId;
40 FileLocations::Tree currentMap;
41 QMap<QString, PendingSourceLocationId> pendingRegions;
42 QMap<QString, CommentedElement> pendingComments;
43};
44
45class QMLDOM_EXPORT OutWriter
46{
47public:
48 int indent = 0;
49 int indenterId = -1;
50 bool indentNextlines = false;
51 bool skipComments = false;
52 LineWriter &lineWriter;
53 Path currentPath;
54 FileLocations::Tree topLocation;
55 QString writtenStr;
56 UpdatedScriptExpression::Tree reformattedScriptExpressions;
57 QList<OutWriterState> states;
58
59 explicit OutWriter(LineWriter &lw)
60 : lineWriter(lw),
61 topLocation(FileLocations::createTree(basePath: Path())),
62 reformattedScriptExpressions(UpdatedScriptExpression::createTree(basePath: Path()))
63 {
64 lineWriter.addInnerSink(s: [this](QStringView s) { writtenStr.append(v: s); });
65 indenterId =
66 lineWriter.addTextAddCallback(callback: [this](LineWriter &, LineWriter::TextAddType tt) {
67 if (indentNextlines && tt == LineWriter::TextAddType::Normal
68 && QStringView(lineWriter.currentLine()).trimmed().isEmpty())
69 lineWriter.setLineIndent(indent);
70 return true;
71 });
72 }
73
74 OutWriterState &state(int i = 0);
75
76 int increaseIndent(int level = 1)
77 {
78 int oldIndent = indent;
79 indent += lineWriter.options().formatOptions.indentSize * level;
80 return oldIndent;
81 }
82 int decreaseIndent(int level = 1, int expectedIndent = -1)
83 {
84 indent -= lineWriter.options().formatOptions.indentSize * level;
85 Q_ASSERT(expectedIndent < 0 || expectedIndent == indent);
86 return indent;
87 }
88
89 void itemStart(DomItem &it);
90 void itemEnd(DomItem &it);
91 void regionStart(QString rName);
92 void regionStart(QStringView rName) { regionStart(rName: rName.toString()); }
93 void regionEnd(QString rName);
94 void regionEnd(QStringView rName) { regionEnd(rName: rName.toString()); }
95
96 quint32 counter() const { return lineWriter.counter(); }
97 OutWriter &writeRegion(QString rName, QStringView toWrite);
98 OutWriter &writeRegion(QStringView rName, QStringView toWrite)
99 {
100 return writeRegion(rName: rName.toString(), toWrite);
101 }
102 OutWriter &writeRegion(QString t) { return writeRegion(rName: t, toWrite: t); }
103 OutWriter &writeRegion(QStringView t) { return writeRegion(rName: t.toString(), toWrite: t); }
104 OutWriter &ensureNewline(int nNewlines = 1)
105 {
106 lineWriter.ensureNewline(nNewlines);
107 return *this;
108 }
109 OutWriter &ensureSpace()
110 {
111 lineWriter.ensureSpace();
112 return *this;
113 }
114 OutWriter &ensureSpace(QStringView space)
115 {
116 lineWriter.ensureSpace(space);
117 return *this;
118 }
119 OutWriter &newline()
120 {
121 lineWriter.newline();
122 return *this;
123 }
124 OutWriter &space()
125 {
126 lineWriter.space();
127 return *this;
128 }
129 OutWriter &write(QStringView v, LineWriter::TextAddType t = LineWriter::TextAddType::Normal)
130 {
131 lineWriter.write(v, tType: t);
132 return *this;
133 }
134 OutWriter &write(QStringView v, SourceLocation *toUpdate)
135 {
136 lineWriter.write(v, toUpdate);
137 return *this;
138 }
139 void flush() { lineWriter.flush(); }
140 void eof(bool ensureNewline = true) { lineWriter.eof(ensureNewline); }
141 int addNewlinesAutospacerCallback(int nLines)
142 {
143 return lineWriter.addNewlinesAutospacerCallback(nLines);
144 }
145 int addTextAddCallback(std::function<bool(LineWriter &, LineWriter::TextAddType)> callback)
146 {
147 return lineWriter.addTextAddCallback(callback);
148 }
149 bool removeTextAddCallback(int i) { return lineWriter.removeTextAddCallback(i); }
150 void addReformattedScriptExpression(Path p, std::shared_ptr<ScriptExpression> exp)
151 {
152 if (auto updExp = UpdatedScriptExpression::ensure(base: reformattedScriptExpressions, basePath: p,
153 pType: AttachedInfo::PathType::Canonical)) {
154 updExp->info().expr = exp;
155 }
156 }
157 DomItem updatedFile(DomItem &qmlFile);
158};
159
160} // end namespace Dom
161} // end namespace QQmlJS
162
163QT_END_NAMESPACE
164#endif // QMLDOMOUTWRITER_P_H
165

source code of qtdeclarative/src/qmldom/qqmldomoutwriter_p.h