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