summaryrefslogtreecommitdiffstats
path: root/src/tools/uic/shared/language.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/uic/shared/language.cpp')
-rw-r--r--src/tools/uic/shared/language.cpp260
1 files changed, 145 insertions, 115 deletions
diff --git a/src/tools/uic/shared/language.cpp b/src/tools/uic/shared/language.cpp
index 48f5830760..d59688e346 100644
--- a/src/tools/uic/shared/language.cpp
+++ b/src/tools/uic/shared/language.cpp
@@ -1,37 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "language.h"
#include <QtCore/qtextstream.h>
+#include <QtCore/QList>
namespace language {
+using namespace Qt::StringLiterals;
+
static Encoding encoding = Encoding::Utf8;
static Language _language = Language::Cpp;
@@ -42,31 +20,37 @@ void setLanguage(Language l)
_language = l;
switch (_language) {
case Language::Cpp:
- derefPointer = QLatin1String("->");
- nullPtr = QLatin1String("nullptr");
- operatorNew = QLatin1String("new ");
- qtQualifier = QLatin1String("Qt::");
- qualifier = QLatin1String("::");
- self = QLatin1String(""); // for testing: change to "this->";
- eol = QLatin1String(";\n");
- emptyString = QLatin1String("QString()");
+ derefPointer = u"->"_s;
+ listStart = '{';
+ listEnd = '}';
+ nullPtr = u"nullptr"_s;
+ operatorNew = u"new "_s;
+ qtQualifier = u"Qt::"_s;
+ qualifier = u"::"_s;
+ self = u""_s; // for testing: change to "this->";
+ eol = u";\n"_s;
+ emptyString = u"QString()"_s;
encoding = Encoding::Utf8;
break;
case Language::Python:
- derefPointer = QLatin1String(".");
- nullPtr = QLatin1String("None");
- operatorNew = QLatin1String("");
- qtQualifier = QLatin1String("Qt.");
- qualifier = QLatin1String(".");
- self = QLatin1String("self.");
- eol = QLatin1String("\n");
- emptyString = QLatin1String("\"\"");
+ derefPointer = u"."_s;
+ listStart = '[';
+ listEnd = ']';
+ nullPtr = u"None"_s;
+ operatorNew = u""_s;
+ qtQualifier = u"Qt."_s;
+ qualifier = u"."_s;
+ self = u"self."_s;
+ eol = u"\n"_s;
+ emptyString = u"\"\""_s;
encoding = Encoding::Unicode;
break;
}
}
QString derefPointer;
+char listStart;
+char listEnd;
QString nullPtr;
QString operatorNew;
QString qtQualifier;
@@ -75,9 +59,9 @@ QString self;
QString eol;
QString emptyString;
-QString cppQualifier = QLatin1String("::");
-QString cppTrue = QLatin1String("true");
-QString cppFalse = QLatin1String("false");
+QString cppQualifier = u"::"_s;
+QString cppTrue = u"true"_s;
+QString cppFalse = u"false"_s;
QTextStream &operator<<(QTextStream &str, const qtConfig &c)
{
@@ -100,97 +84,97 @@ QTextStream &operator<<(QTextStream &str, const closeQtConfig &c)
struct EnumLookup
{
int value;
- const char *valueString;
+ QLatin1StringView valueString;
};
template <int N>
-const char *lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex = 0)
+QLatin1StringView lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex = 0)
{
for (int i = 0; i < N; ++i) {
if (value == array[i].value)
return array[i].valueString;
}
- const char *defaultValue = array[defaultIndex].valueString;
+ auto defaultValue = array[defaultIndex].valueString;
qWarning("uic: Warning: Invalid enumeration value %d, defaulting to %s",
- value, defaultValue);
+ value, defaultValue.data());
return defaultValue;
}
QString fixClassName(QString className)
{
if (language() == Language::Python)
- className.replace(cppQualifier, QLatin1String("_"));
+ className.replace(cppQualifier, "_"_L1);
return className;
}
-const char *toolbarArea(int v)
+QLatin1StringView toolbarArea(int v)
{
static const EnumLookup toolBarAreas[] =
{
- {0, "NoToolBarArea"},
- {0x1, "LeftToolBarArea"},
- {0x2, "RightToolBarArea"},
- {0x4, "TopToolBarArea"},
- {0x8, "BottomToolBarArea"},
- {0xf, "AllToolBarAreas"}
+ {0, "NoToolBarArea"_L1},
+ {0x1, "LeftToolBarArea"_L1},
+ {0x2, "RightToolBarArea"_L1},
+ {0x4, "TopToolBarArea"_L1},
+ {0x8, "BottomToolBarArea"_L1},
+ {0xf, "AllToolBarAreas"_L1}
};
return lookupEnum(toolBarAreas, v);
}
-const char *sizePolicy(int v)
+QLatin1StringView sizePolicy(int v)
{
static const EnumLookup sizePolicies[] =
{
- {0, "Fixed"},
- {0x1, "Minimum"},
- {0x4, "Maximum"},
- {0x5, "Preferred"},
- {0x3, "MinimumExpanding"},
- {0x7, "Expanding"},
- {0xD, "Ignored"}
+ {0, "Fixed"_L1},
+ {0x1, "Minimum"_L1},
+ {0x4, "Maximum"_L1},
+ {0x5, "Preferred"_L1},
+ {0x3, "MinimumExpanding"_L1},
+ {0x7, "Expanding"_L1},
+ {0xD, "Ignored"_L1}
};
return lookupEnum(sizePolicies, v, 3);
}
-const char *dockWidgetArea(int v)
+QLatin1StringView dockWidgetArea(int v)
{
static const EnumLookup dockWidgetAreas[] =
{
- {0, "NoDockWidgetArea"},
- {0x1, "LeftDockWidgetArea"},
- {0x2, "RightDockWidgetArea"},
- {0x4, "TopDockWidgetArea"},
- {0x8, "BottomDockWidgetArea"},
- {0xf, "AllDockWidgetAreas"}
+ {0, "NoDockWidgetArea"_L1},
+ {0x1, "LeftDockWidgetArea"_L1},
+ {0x2, "RightDockWidgetArea"_L1},
+ {0x4, "TopDockWidgetArea"_L1},
+ {0x8, "BottomDockWidgetArea"_L1},
+ {0xf, "AllDockWidgetAreas"_L1}
};
return lookupEnum(dockWidgetAreas, v);
}
-const char *paletteColorRole(int v)
+QLatin1StringView paletteColorRole(int v)
{
static const EnumLookup colorRoles[] =
{
- {0, "WindowText"},
- {1, "Button"},
- {2, "Light"},
- {3, "Midlight"},
- {4, "Dark"},
- {5, "Mid"},
- {6, "Text"},
- {7, "BrightText"},
- {8, "ButtonText"},
- {9, "Base"},
- {10, "Window"},
- {11, "Shadow"},
- {12, "Highlight"},
- {13, "HighlightedText"},
- {14, "Link"},
- {15, "LinkVisited"},
- {16, "AlternateBase"},
- {17, "NoRole"},
- {18, "ToolTipBase"},
- {19, "ToolTipText"},
- {20, "PlaceholderText"},
+ {0, "WindowText"_L1},
+ {1, "Button"_L1},
+ {2, "Light"_L1},
+ {3, "Midlight"_L1},
+ {4, "Dark"_L1},
+ {5, "Mid"_L1},
+ {6, "Text"_L1},
+ {7, "BrightText"_L1},
+ {8, "ButtonText"_L1},
+ {9, "Base"_L1},
+ {10, "Window"_L1},
+ {11, "Shadow"_L1},
+ {12, "Highlight"_L1},
+ {13, "HighlightedText"_L1},
+ {14, "Link"_L1},
+ {15, "LinkVisited"_L1},
+ {16, "AlternateBase"_L1},
+ {17, "NoRole"_L1},
+ {18, "ToolTipBase"_L1},
+ {19, "ToolTipText"_L1},
+ {20, "PlaceholderText"_L1},
};
return lookupEnum(colorRoles, v);
}
@@ -211,7 +195,7 @@ static int formatEscapedNumber(QTextStream &str, ushort value, int base, int wid
const auto oldFieldWidth = str.fieldWidth();
const auto oldFieldAlignment = str.fieldAlignment();
const auto oldIntegerBase = str.integerBase();
- str.setPadChar(QLatin1Char('0'));
+ str.setPadChar(u'0');
str.setFieldWidth(width);
str.setFieldAlignment(QTextStream::AlignRight);
str.setIntegerBase(base);
@@ -387,29 +371,65 @@ void _formatStackVariable(QTextStream &str, const char *className, QStringView v
}
}
-enum OverloadUse {
- UseOverload,
- UseOverloadWhenNoArguments, // Use overload only when the argument list is empty,
- // in this case there is no chance of connecting
- // mismatching T against const T &
- DontUseOverload
+enum class OverloadUse {
+ Always,
+ WhenAmbiguousOrEmpty, // Use overload if
+ // - signal/slot is ambiguous
+ // - argument list is empty (chance of connecting mismatching T against const T &)
+ Never,
};
// Format a member function for a signal slot connection
-static void formatMemberFnPtr(QTextStream &str, const SignalSlot &s,
- OverloadUse useQOverload = DontUseOverload)
+static bool isConstRef(const QStringView &arg)
{
- const int parenPos = s.signature.indexOf(QLatin1Char('('));
+ return arg.startsWith(u'Q') && arg != "QPoint"_L1 && arg != "QSize"_L1;
+}
+
+static QString formatOverload(const QStringView &parameters)
+{
+ QString result = "qOverload<"_L1;
+ const auto args = QStringView{parameters}.split(u',');
+ for (qsizetype i = 0, size = args.size(); i < size; ++i) {
+ const auto &arg = args.at(i);
+ if (i > 0)
+ result += u',';
+ const bool constRef = isConstRef(arg);
+ if (constRef)
+ result += "const "_L1;
+ result += arg;
+ if (constRef)
+ result += u'&';
+ }
+ result += u'>';
+ return result;
+}
+
+static void formatMemberFnPtr(QTextStream &str, const SignalSlot &s, OverloadUse useQOverload)
+{
+ const qsizetype parenPos = s.signature.indexOf(u'(');
Q_ASSERT(parenPos >= 0);
const auto functionName = QStringView{s.signature}.left(parenPos);
const auto parameters = QStringView{s.signature}.mid(parenPos + 1,
s.signature.size() - parenPos - 2);
- const bool withOverload = useQOverload == UseOverload ||
- (useQOverload == UseOverloadWhenNoArguments && parameters.isEmpty());
+
+ const bool isAmbiguous = s.options.testFlag(SignalSlotOption::Ambiguous);
+ bool withOverload = false; // just to silence the compiler
+
+ switch (useQOverload) {
+ case OverloadUse::Always:
+ withOverload = true;
+ break;
+ case OverloadUse::Never:
+ withOverload = false;
+ break;
+ case OverloadUse::WhenAmbiguousOrEmpty:
+ withOverload = parameters.empty() || isAmbiguous;
+ break;
+ }
if (withOverload)
- str << "qOverload<" << parameters << ">(";
+ str << formatOverload(parameters) << '(';
str << '&' << s.className << "::" << functionName;
@@ -422,9 +442,9 @@ static void formatMemberFnPtrConnection(QTextStream &str,
const SignalSlot &receiver)
{
str << "QObject::connect(" << sender.name << ", ";
- formatMemberFnPtr(str, sender);
+ formatMemberFnPtr(str, sender, OverloadUse::Never);
str << ", " << receiver.name << ", ";
- formatMemberFnPtr(str, receiver, UseOverloadWhenNoArguments);
+ formatMemberFnPtr(str, receiver, OverloadUse::WhenAmbiguousOrEmpty);
str << ')';
}
@@ -450,12 +470,22 @@ void formatConnection(QTextStream &str, const SignalSlot &sender, const SignalSl
break;
}
break;
- case Language::Python:
- str << sender.name << '.'
- << QStringView{sender.signature}.left(sender.signature.indexOf(QLatin1Char('(')))
- << ".connect(" << receiver.name << '.'
- << QStringView{receiver.signature}.left(receiver.signature.indexOf(QLatin1Char('(')))
+ case Language::Python: {
+ const auto paren = sender.signature.indexOf(u'(');
+ auto senderSignature = QStringView{sender.signature};
+ str << sender.name << '.' << senderSignature.left(paren);
+ // Signals like "QAbstractButton::clicked(checked=false)" require
+ // the parameter if it is used.
+ if (sender.options.testFlag(SignalSlotOption::Ambiguous)) {
+ const QStringView parameters =
+ senderSignature.mid(paren + 1, senderSignature.size() - paren - 2);
+ if (!parameters.isEmpty() && !parameters.contains(u','))
+ str << "[\"" << parameters << "\"]";
+ }
+ str << ".connect(" << receiver.name << '.'
+ << QStringView{receiver.signature}.left(receiver.signature.indexOf(u'('))
<< ')';
+ }
break;
}
}