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