[tools] Generate boiler plate of requests on client side

In the header for each request a method is created, with following
features:
* ignores requests working as destructor
* adjusts return type for requests containing newId
* adds QObject *parent = nullptr for requests containing newId
* adds the arguements
* turns arguments from wayland into Qt types

In the cpp the same logic is applied. Methods are not properly
implemented and won't compile in the case of returning.
This commit is contained in:
Martin Gräßlin 2015-09-07 10:10:37 +02:00
parent 7a52d15eca
commit 7a69d3cc40
2 changed files with 147 additions and 1 deletions

View file

@ -40,6 +40,17 @@ namespace Tools
static QMap<QString, QString> s_clientClassNameMapping;
static QString toQtInterfaceName(const QString &wlInterface)
{
auto it = s_clientClassNameMapping.constFind(wlInterface);
if (it != s_clientClassNameMapping.constEnd()) {
return it.value();
} else {
qWarning() << "Cannot find mapping for " << wlInterface;
}
return wlInterface;
}
Argument::Argument()
{
}
@ -84,6 +95,31 @@ Argument::Type Argument::parseType(const QStringRef &type)
return Type::Unknown;
}
QString Argument::typeAsQt() const
{
switch (m_type) {
case Type::Destructor:
return QString();
case Type::FileDescriptor:
return QStringLiteral("int");
case Type::Fixed:
return QStringLiteral("qreal");
case Type::Int:
return QStringLiteral("qint32");
case Type::NewId:
case Type::Object:
return toQtInterfaceName(m_inteface);
case Type::String:
return QStringLiteral("const QString &");
case Type::Uint:
return QStringLiteral("quint32");
case Type::Unknown:
return QString();
default:
Q_UNREACHABLE();
}
}
Request::Request()
{
}
@ -95,6 +131,26 @@ Request::Request(const QString &name)
Request::~Request() = default;
bool Request::isDestructor() const
{
for (const auto a: m_arguments) {
if (a.type() == Argument::Type::Destructor) {
return true;
}
}
return false;
}
bool Request::isFactory() const
{
for (const auto a: m_arguments) {
if (a.type() == Argument::Type::NewId) {
return true;
}
}
return false;
}
Event::Event()
{
}
@ -303,6 +359,7 @@ void Generator::startGenerateCppFile()
for (auto it = m_interfaces.constBegin(); it != m_interfaces.constEnd(); ++it) {
generatePrivateClass(*it);
generateClientCpp(*it);
generateClientCppRequests(*it);
}
generateEndNamespace();
@ -478,6 +535,7 @@ void Generator::generateClientGlobalClass(const Interface &interface)
generateClientGlobalClassSetup(interface);
generateClientClassReleaseDestroy(interface);
generateClientClassStart(interface);
generateClientClassRequests(interface);
generateClientClassCasts(interface);
generateClientClassSignals(interface);
generateClientGlobalClassEnd(interface);
@ -489,6 +547,7 @@ void Generator::generateClientResourceClass(const Interface &interface)
generateClientClassDtor(interface);
generateClientResourceClassSetup(interface);
generateClientClassReleaseDestroy(interface);
generateClientClassRequests(interface);
generateClientClassCasts(interface);
generateClientResourceClassEnd(interface);
}
@ -716,6 +775,87 @@ void Generator::generateClientClassStart(const Interface &interface)
*m_stream.localData() << templateString.arg(interface.kwaylandClientName());
}
void Generator::generateClientClassRequests(const Interface &interface)
{
const auto requests = interface.requests();
const QString templateString = QStringLiteral(" void %1(%2);\n\n");
const QString factoryTemplateString = QStringLiteral(" %1 *%2(%3);\n\n");
for (const auto &r: requests) {
if (r.isDestructor()) {
continue;
}
QString arguments;
bool first = true;
QString factored;
for (const auto &a: r.arguments()) {
if (a.type() == Argument::Type::NewId) {
factored = a.interface();
continue;
}
if (!first) {
arguments.append(QStringLiteral(", "));
} else {
first = false;
}
if (a.type() == Argument::Type::Object) {
arguments.append(QStringLiteral("%1 *%2").arg(a.typeAsQt()).arg(a.name()));
} else {
arguments.append(QStringLiteral("%1 %2").arg(a.typeAsQt()).arg(a.name()));
}
}
if (factored.isEmpty()) {
*m_stream.localData() << templateString.arg(r.name()).arg(arguments);
} else {
if (!first) {
arguments.append(QStringLiteral(", "));
}
arguments.append(QStringLiteral("QObject *parent = nullptr"));
*m_stream.localData() << factoryTemplateString.arg(toQtInterfaceName(factored)).arg(r.name()).arg(arguments);
}
}
}
void Generator::generateClientCppRequests(const Interface &interface)
{
const auto requests = interface.requests();
const QString templateString = QStringLiteral("void %1::%2(%3)\n");
const QString factoryTemplateString = QStringLiteral("%2 *%1::%3(%4)\n");
for (const auto &r: requests) {
if (r.isDestructor()) {
continue;
}
QString arguments;
bool first = true;
QString factored;
for (const auto &a: r.arguments()) {
if (a.type() == Argument::Type::NewId) {
factored = a.interface();
continue;
}
if (!first) {
arguments.append(QStringLiteral(", "));
} else {
first = false;
}
if (a.type() == Argument::Type::Object) {
arguments.append(QStringLiteral("%1 *%2").arg(a.typeAsQt()).arg(a.name()));
} else {
arguments.append(QStringLiteral("%1 %2").arg(a.typeAsQt()).arg(a.name()));
}
}
if (factored.isEmpty()) {
*m_stream.localData() << templateString.arg(interface.kwaylandClientName()).arg(r.name()).arg(arguments);
} else {
if (!first) {
arguments.append(QStringLiteral(", "));
}
arguments.append(QStringLiteral("QObject *parent"));
*m_stream.localData() << factoryTemplateString.arg(interface.kwaylandClientName()).arg(toQtInterfaceName(factored)).arg(r.name()).arg(arguments);
}
*m_stream.localData() << QStringLiteral("{\n}\n\n");
}
}
void Generator::generateClientClassCasts(const Interface &interface)
{
const QString templateString = QStringLiteral(
@ -793,7 +933,7 @@ void Generator::generateNamespaceForwardDeclarations()
if (it != s_clientClassNameMapping.constEnd()) {
*m_stream.localData() << QStringLiteral("class %1;\n").arg(it.value());
} else {
qWarning() << "Cannot forward declare KWayland class for interface " << it.key();
qWarning() << "Cannot forward declare KWayland class for interface " << o;
}
}
*m_stream.localData() << QStringLiteral("\n");

View file

@ -65,6 +65,7 @@ public:
QString interface() const {
return m_inteface;
}
QString typeAsQt() const;
private:
Type parseType(const QStringRef &type);
@ -93,6 +94,9 @@ public:
return m_arguments;
}
bool isDestructor() const;
bool isFactory() const;
private:
QString m_name;
QVector<Argument> m_arguments;
@ -227,6 +231,8 @@ private:
void generateClientClassDptr(const Interface &interface);
void generateClientGlobalClassEnd(const Interface &interface);
void generateClientResourceClassEnd(const Interface &interface);
void generateClientClassRequests(const Interface &interface);
void generateClientCppRequests(const Interface &interface);
void generateWaylandForwardDeclarations();
void generateNamespaceForwardDeclarations();
void startParseXml();