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