1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "qqmljsstreamwriter_p.h"
5
6#include <QtCore/QBuffer>
7#include <QtCore/QStringList>
8
9QT_BEGIN_NAMESPACE
10
11QQmlJSStreamWriter::QQmlJSStreamWriter(QByteArray *array)
12 : m_indentDepth(0)
13 , m_pendingLineLength(0)
14 , m_maybeOneline(false)
15 , m_stream(new QBuffer(array))
16{
17 m_stream->open(mode: QIODevice::WriteOnly);
18}
19
20void QQmlJSStreamWriter::writeStartDocument()
21{
22}
23
24void QQmlJSStreamWriter::writeEndDocument()
25{
26}
27
28void QQmlJSStreamWriter::writeLibraryImport(const QString &uri, int majorVersion, int minorVersion, const QString &as)
29{
30 m_stream->write(data: QString::fromLatin1(ba: "import %1 %2.%3").arg(args: uri, args: QString::number(majorVersion), args: QString::number(minorVersion)).toUtf8());
31 if (!as.isEmpty())
32 m_stream->write(data: QString::fromLatin1(ba: " as %1").arg(a: as).toUtf8());
33 m_stream->write(data: "\n");
34}
35
36void QQmlJSStreamWriter::writeStartObject(const QString &component)
37{
38 flushPotentialLinesWithNewlines();
39 writeIndent();
40 m_stream->write(data: QString::fromLatin1(ba: "%1 {").arg(a: component).toUtf8());
41 ++m_indentDepth;
42 m_maybeOneline = true;
43}
44
45void QQmlJSStreamWriter::writeEndObject()
46{
47 if (m_maybeOneline) {
48 --m_indentDepth;
49 for (int i = 0; i < m_pendingLines.size(); ++i) {
50 m_stream->write(data: " ");
51 m_stream->write(data: m_pendingLines.at(i).trimmed());
52 if (i != m_pendingLines.size() - 1)
53 m_stream->write(data: ";");
54 }
55
56 if (!m_pendingLines.isEmpty())
57 m_stream->write(data: " }\n");
58 else
59 m_stream->write(data: "}\n");
60
61 m_pendingLines.clear();
62 m_pendingLineLength = 0;
63 m_maybeOneline = false;
64 } else {
65 flushPotentialLinesWithNewlines();
66 --m_indentDepth;
67 writeIndent();
68 m_stream->write(data: "}\n");
69 }
70}
71
72void QQmlJSStreamWriter::writeScriptBinding(const QString &name, const QString &rhs)
73{
74 writePotentialLine(line: QString::fromLatin1(ba: "%1: %2").arg(args: name, args: rhs).toUtf8());
75}
76
77void QQmlJSStreamWriter::writeBooleanBinding(const QString &name, bool value)
78{
79 writeScriptBinding(name, rhs: value ? QLatin1String("true") : QLatin1String("false"));
80}
81
82void QQmlJSStreamWriter::writeArrayBinding(const QString &name, const QStringList &elements)
83{
84 flushPotentialLinesWithNewlines();
85 writeIndent();
86
87 // try to use a single line
88 QString singleLine;
89 singleLine += QString::fromLatin1(ba: "%1: [").arg(a: name);
90 for (int i = 0; i < elements.size(); ++i) {
91 singleLine += elements.at(i);
92 if (i != elements.size() - 1)
93 singleLine += QLatin1String(", ");
94 }
95 singleLine += QLatin1String("]\n");
96 if (singleLine.size() + m_indentDepth * 4 < 80) {
97 m_stream->write(data: singleLine.toUtf8());
98 return;
99 }
100
101 // write multi-line
102 m_stream->write(data: QString::fromLatin1(ba: "%1: [\n").arg(a: name).toUtf8());
103 ++m_indentDepth;
104 for (int i = 0; i < elements.size(); ++i) {
105 writeIndent();
106 m_stream->write(data: elements.at(i).toUtf8());
107 if (i != elements.size() - 1) {
108 m_stream->write(data: ",\n");
109 } else {
110 m_stream->write(data: "\n");
111 }
112 }
113 --m_indentDepth;
114 writeIndent();
115 m_stream->write(data: "]\n");
116}
117
118void QQmlJSStreamWriter::write(const QString &data)
119{
120 flushPotentialLinesWithNewlines();
121 m_stream->write(data: data.toUtf8());
122}
123
124void QQmlJSStreamWriter::writeScriptObjectLiteralBinding(const QString &name, const QList<QPair<QString, QString> > &keyValue)
125{
126 flushPotentialLinesWithNewlines();
127 writeIndent();
128 m_stream->write(data: QString::fromLatin1(ba: "%1: {\n").arg(a: name).toUtf8());
129 ++m_indentDepth;
130 for (int i = 0; i < keyValue.size(); ++i) {
131 const QString key = keyValue.at(i).first;
132 const QString value = keyValue.at(i).second;
133 writeIndent();
134 m_stream->write(data: QString::fromLatin1(ba: "%1: %2").arg(args: key, args: value).toUtf8());
135 if (i != keyValue.size() - 1) {
136 m_stream->write(data: ",\n");
137 } else {
138 m_stream->write(data: "\n");
139 }
140 }
141 --m_indentDepth;
142 writeIndent();
143 m_stream->write(data: "}\n");
144}
145
146void QQmlJSStreamWriter::writeIndent()
147{
148 m_stream->write(data: QByteArray(m_indentDepth * 4, ' '));
149}
150
151void QQmlJSStreamWriter::writePotentialLine(const QByteArray &line)
152{
153 m_pendingLines.append(t: line);
154 m_pendingLineLength += line.size();
155 if (m_pendingLineLength >= 80) {
156 flushPotentialLinesWithNewlines();
157 }
158}
159
160void QQmlJSStreamWriter::flushPotentialLinesWithNewlines()
161{
162 if (m_maybeOneline)
163 m_stream->write(data: "\n");
164 for (const QByteArray &line : std::as_const(t&: m_pendingLines)) {
165 writeIndent();
166 m_stream->write(data: line);
167 m_stream->write(data: "\n");
168 }
169 m_pendingLines.clear();
170 m_pendingLineLength = 0;
171 m_maybeOneline = false;
172}
173
174QT_END_NAMESPACE
175

source code of qtdeclarative/src/qmltyperegistrar/qqmljsstreamwriter.cpp