Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
language.cpp
Go to the documentation of this file.
1// Copyright (C) 2018 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 "language.h"
5
6#include <QtCore/qtextstream.h>
7
8namespace language {
9
10using namespace Qt::StringLiterals;
11
14
16
18{
19 _language = l;
20 switch (_language) {
21 case Language::Cpp:
22 derefPointer = u"->"_s;
23 listStart = '{';
24 listEnd = '}';
25 nullPtr = u"nullptr"_s;
26 operatorNew = u"new "_s;
27 qtQualifier = u"Qt::"_s;
28 qualifier = u"::"_s;
29 self = u""_s; // for testing: change to "this->";
30 eol = u";\n"_s;
31 emptyString = u"QString()"_s;
33 break;
35 derefPointer = u"."_s;
36 listStart = '[';
37 listEnd = ']';
38 nullPtr = u"None"_s;
39 operatorNew = u""_s;
40 qtQualifier = u"Qt."_s;
41 qualifier = u"."_s;
42 self = u"self."_s;
43 eol = u"\n"_s;
44 emptyString = u"\"\""_s;
46 break;
47 }
48}
49
60
62QString cppTrue = u"true"_s;
63QString cppFalse = u"false"_s;
64
66{
67 str << "QT_CONFIG(" << c.parameter() << ')';
68 return str;
69}
70
72{
73 str << "#if " << qtConfig(c.parameter()) << '\n';
74 return str;
75}
76
78{
79 str << "#endif // " << qtConfig(c.parameter()) << '\n';
80 return str;
81}
82
84{
85 int value;
86 const char *valueString;
87};
88
89template <int N>
90const char *lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex = 0)
91{
92 for (int i = 0; i < N; ++i) {
93 if (value == array[i].value)
94 return array[i].valueString;
95 }
96 const char *defaultValue = array[defaultIndex].valueString;
97 qWarning("uic: Warning: Invalid enumeration value %d, defaulting to %s",
98 value, defaultValue);
99 return defaultValue;
100}
101
103{
104 if (language() == Language::Python)
105 className.replace(cppQualifier, "_"_L1);
106 return className;
107}
108
109const char *toolbarArea(int v)
110{
111 static const EnumLookup toolBarAreas[] =
112 {
113 {0, "NoToolBarArea"},
114 {0x1, "LeftToolBarArea"},
115 {0x2, "RightToolBarArea"},
116 {0x4, "TopToolBarArea"},
117 {0x8, "BottomToolBarArea"},
118 {0xf, "AllToolBarAreas"}
119 };
120 return lookupEnum(toolBarAreas, v);
121}
122
123const char *sizePolicy(int v)
124{
125 static const EnumLookup sizePolicies[] =
126 {
127 {0, "Fixed"},
128 {0x1, "Minimum"},
129 {0x4, "Maximum"},
130 {0x5, "Preferred"},
131 {0x3, "MinimumExpanding"},
132 {0x7, "Expanding"},
133 {0xD, "Ignored"}
134 };
135 return lookupEnum(sizePolicies, v, 3);
136}
137
138const char *dockWidgetArea(int v)
139{
140 static const EnumLookup dockWidgetAreas[] =
141 {
142 {0, "NoDockWidgetArea"},
143 {0x1, "LeftDockWidgetArea"},
144 {0x2, "RightDockWidgetArea"},
145 {0x4, "TopDockWidgetArea"},
146 {0x8, "BottomDockWidgetArea"},
147 {0xf, "AllDockWidgetAreas"}
148 };
149 return lookupEnum(dockWidgetAreas, v);
150}
151
152const char *paletteColorRole(int v)
153{
154 static const EnumLookup colorRoles[] =
155 {
156 {0, "WindowText"},
157 {1, "Button"},
158 {2, "Light"},
159 {3, "Midlight"},
160 {4, "Dark"},
161 {5, "Mid"},
162 {6, "Text"},
163 {7, "BrightText"},
164 {8, "ButtonText"},
165 {9, "Base"},
166 {10, "Window"},
167 {11, "Shadow"},
168 {12, "Highlight"},
169 {13, "HighlightedText"},
170 {14, "Link"},
171 {15, "LinkVisited"},
172 {16, "AlternateBase"},
173 {17, "NoRole"},
174 {18, "ToolTipBase"},
175 {19, "ToolTipText"},
176 {20, "PlaceholderText"},
177 };
178 return lookupEnum(colorRoles, v);
179}
180
181// Helpers for formatting a character sequences
182
183// Format a special character like '\x0a'
185 char prefix = 0)
186{
187 int length = 1 + width;
188 str << '\\';
189 if (prefix) {
190 str << prefix;
191 ++length;
192 }
193 const auto oldPadChar = str.padChar();
194 const auto oldFieldWidth = str.fieldWidth();
195 const auto oldFieldAlignment = str.fieldAlignment();
196 const auto oldIntegerBase = str.integerBase();
197 str.setPadChar(u'0');
198 str.setFieldWidth(width);
199 str.setFieldAlignment(QTextStream::AlignRight);
200 str.setIntegerBase(base);
201 str << value;
202 str.setIntegerBase(oldIntegerBase);
203 str.setFieldAlignment(oldFieldAlignment);
204 str.setFieldWidth(oldFieldWidth);
205 str.setPadChar(oldPadChar);
206 return length;
207}
208
210{
211 int length = 0;
212 switch (value) {
213 case '\\':
214 str << "\\\\";
215 length += 2;
216 break;
217 case '\"':
218 str << "\\\"";
219 length += 2;
220 break;
221 case '\n':
222 str << "\\n\"\n\"";
223 length += 5;
224 break;
225 default:
226 break;
227 }
228 return length;
229}
230
231// Format a sequence of characters for C++ with special characters numerically
232// escaped (non-raw string literals), wrappped at maxSegmentSize. FormattingTraits
233// are used to transform characters into (unsigned) codes, which can be used
234// for either normal escapes or Unicode code points as used in Unicode literals.
235
236enum : int { maxSegmentSize = 1024 };
237
238template <Encoding e>
240{
241};
242
243template <>
245{
246 static ushort code(char c) { return uchar(c); }
247};
248
249template <>
251{
252 static ushort code(QChar c) { return c.unicode(); }
253};
254
255template <Encoding e, class Iterator>
256static void formatStringSequence(QTextStream &str, Iterator it, Iterator end,
257 const QString &indent,
258 int escapeIntegerBase, int escapeWidth,
259 char escapePrefix = 0)
260{
261 str << '"';
262 int length = 0;
263 while (it != end) {
264 const auto code = FormattingTraits<e>::code(*it);
265 if (code >= 0x80) {
266 length += formatEscapedNumber(str, code, escapeIntegerBase, escapeWidth, escapePrefix);
267 } else if (const int l = formatSpecialCharacter(str, code)) {
268 length += l;
269 } else if (code != '\r') {
270 str << *it;
271 ++length;
272 }
273 ++it;
274 if (it != end && length > maxSegmentSize) {
275 str << "\"\n" << indent << indent << '"';
276 length = 0;
277 }
278 }
279 str << '"';
280}
281
282void _formatString(QTextStream &str, const QString &value, const QString &indent,
283 bool qString)
284{
285 switch (encoding) {
286 // Special characters as 3 digit octal escapes (u8"\303\234mlaut")
287 case Encoding::Utf8: {
288 if (qString && _language == Language::Cpp)
289 str << "QString::fromUtf8(";
290 const QByteArray utf8 = value.toUtf8();
291 formatStringSequence<Encoding::Utf8>(str, utf8.cbegin(), utf8.cend(), indent,
292 8, 3);
293 if (qString && _language == Language::Cpp)
294 str << ')';
295 }
296 break;
297 // Special characters as 4 digit hex Unicode points (u8"\u00dcmlaut")
299 str << 'u'; // Python Unicode literal (would be UTF-16 in C++)
300 formatStringSequence<Encoding::Unicode>(str, value.cbegin(), value.cend(), indent,
301 16, 4, 'u');
302 break;
303 }
304}
305
307{
308 for (int i = 0; i < r.m_count; ++i)
309 str << r.m_char;
310 return str;
311}
312
314 const QString &parameterName,
315 const QString &indent,
316 const char *returnType) :
317 m_name(name), m_parameterType(parameterType), m_parameterName(parameterName),
318 m_indent(indent), m_return(returnType)
319{
320}
321
323{
324 switch (language()) {
325 case Language::Cpp:
326 str << (f.m_return ? f.m_return : "void") << ' ' << f.m_name << '('
327 << f.m_parameterType;
328 if (f.m_parameterType.cend()->isLetter())
329 str << ' ';
330 str << f.m_parameterName << ')' << '\n' << f.m_indent << "{\n";
331 break;
332 case Language::Python:
333 str << "def " << f.m_name << "(self, " << f.m_parameterName << "):\n";
334 break;
335 }
336 return str;
337}
338
340{
341}
342
344{
345 switch (language()) {
346 case Language::Cpp:
347 str << "} // " << f.m_name << "\n\n";
348 break;
349 case Language::Python:
350 str << "# " << f.m_name << "\n\n";
351 break;
352 }
353 return str;
354}
355
357 bool withInitParameters)
358{
359 switch (language()) {
360 case Language::Cpp:
361 str << className << ' ' << varName;
362 if (withInitParameters)
363 str << '(';
364 break;
365 case Language::Python:
366 str << varName << " = " << className << '(';
367 if (!withInitParameters)
368 str << ')';
369 break;
370 }
371}
372
375 UseOverloadWhenNoArguments, // Use overload only when the argument list is empty,
376 // in this case there is no chance of connecting
377 // mismatching T against const T &
380
381// Format a member function for a signal slot connection
383 OverloadUse useQOverload = DontUseOverload)
384{
385 const qsizetype parenPos = s.signature.indexOf(u'(');
386 Q_ASSERT(parenPos >= 0);
387 const auto functionName = QStringView{s.signature}.left(parenPos);
388
389 const auto parameters = QStringView{s.signature}.mid(parenPos + 1,
390 s.signature.size() - parenPos - 2);
391 const bool withOverload = useQOverload == UseOverload ||
392 (useQOverload == UseOverloadWhenNoArguments && parameters.isEmpty());
393
394 if (withOverload)
395 str << "qOverload<" << parameters << ">(";
396
397 str << '&' << s.className << "::" << functionName;
398
399 if (withOverload)
400 str << ')';
401}
402
404 const SignalSlot &sender,
405 const SignalSlot &receiver)
406{
407 str << "QObject::connect(" << sender.name << ", ";
408 formatMemberFnPtr(str, sender);
409 str << ", " << receiver.name << ", ";
411 str << ')';
412}
413
415 const SignalSlot &sender,
416 const SignalSlot &receiver)
417{
418 str << "QObject::connect(" << sender.name << ", SIGNAL("<< sender.signature
419 << "), " << receiver.name << ", SLOT(" << receiver.signature << "))";
420}
421
422void formatConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver,
424{
425 switch (language()) {
426 case Language::Cpp:
427 switch (connectionSyntax) {
429 formatMemberFnPtrConnection(str, sender, receiver);
430 break;
432 formatStringBasedConnection(str, sender, receiver);
433 break;
434 }
435 break;
436 case Language::Python: {
437 const auto paren = sender.signature.indexOf(u'(');
438 auto senderSignature = QStringView{sender.signature};
439 str << sender.name << '.' << senderSignature.left(paren);
440 // Signals like "QAbstractButton::clicked(checked=false)" require
441 // the parameter if it is used.
442 if (sender.options.testFlag(SignalSlotOption::Ambiguous)) {
443 const QStringView parameters =
444 senderSignature.mid(paren + 1, senderSignature.size() - paren - 2);
445 if (!parameters.isEmpty() && !parameters.contains(u','))
446 str << "[\"" << parameters << "\"]";
447 }
448 str << ".connect(" << receiver.name << '.'
449 << QStringView{receiver.signature}.left(receiver.signature.indexOf(u'('))
450 << ')';
451 }
452 break;
453 }
454}
455
457{
458 switch (language()) {
459 case Language::Cpp:
460 return v ? cppTrue : cppFalse;
461 case Language::Python:
462 return v ? QStringLiteral("True") : QStringLiteral("False");
463 }
464 Q_UNREACHABLE();
465}
466
467static inline QString dot() { return QStringLiteral("."); }
468
470{
471 if (language() == Language::Cpp || !value.contains(cppQualifier))
472 return value;
473 QString fixed = value;
474 fixed.replace(cppQualifier, dot());
475 return fixed;
476}
477
478} // namespace language
\inmodule QtCore
Definition qbytearray.h:57
const_iterator cbegin() const noexcept
Definition qbytearray.h:430
const_iterator cend() const noexcept
Definition qbytearray.h:434
\inmodule QtCore
Definition qchar.h:48
\inmodule QtCore
Definition qstringview.h:76
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
constexpr QStringView left(qsizetype n) const noexcept
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
Definition qstring.h:127
const_iterator cbegin() const
Definition qstring.h:1201
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
static QString static QString qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.cpp:4420
\inmodule QtCore
endFunctionDefinition(const char *name)
Definition language.cpp:339
startFunctionDefinition1(const char *name, const QString &parameterType, const QString &parameterName, const QString &indent, const char *returnType=nullptr)
Definition language.cpp:313
QString str
[2]
QSet< QString >::iterator it
ConnectionSyntax
Definition language.h:15
Language
Definition language.h:13
QString self
Definition language.cpp:57
static Encoding encoding
Definition language.cpp:12
static Language _language
Definition language.cpp:13
Language language()
Definition language.cpp:15
QString qtQualifier
Definition language.cpp:55
static void formatStringBasedConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver)
Definition language.cpp:414
QString enumValue(const QString &value)
Definition language.cpp:469
static int formatSpecialCharacter(QTextStream &str, ushort value)
Definition language.cpp:209
char listStart
Definition language.cpp:51
QString emptyString
Definition language.cpp:59
QString nullPtr
Definition language.cpp:53
const char * toolbarArea(int v)
Definition language.cpp:109
const char * dockWidgetArea(int v)
Definition language.cpp:138
static QString dot()
Definition language.cpp:467
void _formatStackVariable(QTextStream &str, const char *className, QStringView varName, bool withInitParameters)
Definition language.cpp:356
void _formatString(QTextStream &str, const QString &value, const QString &indent, bool qString)
Definition language.cpp:282
QString eol
Definition language.cpp:58
static void formatStringSequence(QTextStream &str, Iterator it, Iterator end, const QString &indent, int escapeIntegerBase, int escapeWidth, char escapePrefix=0)
Definition language.cpp:256
char listEnd
Definition language.cpp:52
QString qualifier
Definition language.cpp:56
QString cppFalse
Definition language.cpp:63
void setLanguage(Language l)
Definition language.cpp:17
const char * lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex=0)
Definition language.cpp:90
static void formatMemberFnPtrConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver)
Definition language.cpp:403
static int formatEscapedNumber(QTextStream &str, ushort value, int base, int width, char prefix=0)
Definition language.cpp:184
ConnectionSyntax connectionSyntax()
@ DontUseOverload
Definition language.cpp:378
@ UseOverloadWhenNoArguments
Definition language.cpp:375
const char * sizePolicy(int v)
Definition language.cpp:123
QString fixClassName(QString className)
Definition language.cpp:102
const char * paletteColorRole(int v)
Definition language.cpp:152
QString cppTrue
Definition language.cpp:62
@ maxSegmentSize
Definition language.cpp:236
QTextStream & operator<<(QTextStream &str, const qtConfig &c)
Definition language.cpp:65
void formatConnection(QTextStream &str, const SignalSlot &sender, const SignalSlot &receiver, ConnectionSyntax connectionSyntax)
Definition language.cpp:422
QString cppQualifier
Definition language.cpp:61
static void formatMemberFnPtr(QTextStream &str, const SignalSlot &s, OverloadUse useQOverload=DontUseOverload)
Definition language.cpp:382
QString operatorNew
Definition language.cpp:54
QString derefPointer
Definition language.cpp:50
QString boolValue(bool v)
Definition language.cpp:456
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static qsizetype defaultIndex()
Definition qlocale.cpp:816
#define qWarning
Definition qlogging.h:162
GLsizei const GLfloat * v
[13]
GLboolean r
[2]
GLuint GLuint end
GLenum GLuint GLenum GLsizei length
GLfloat GLfloat f
GLint GLsizei width
GLuint name
const GLubyte * c
GLenum array
GLdouble s
[6]
Definition qopenglext.h:235
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
unsigned char uchar
Definition qtypes.h:27
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned short ushort
Definition qtypes.h:28
const char className[16]
[1]
Definition qwizard.cpp:100
const char * valueString
Definition language.cpp:86
SignalSlotOptions options
Definition language.h:188