summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-05-03 09:47:12 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-05-25 22:01:53 +0200
commit4b82c1c7278baf154a6a53fc8ce21f3b62d3479c (patch)
tree9bf20525ddc7320a7b5101f35234df6a7a2e4a8b /src/tools
parent6ecde6265a08163d47a834cb5591fdb22461d129 (diff)
uic: Extract a base class for WriteIncludes
Extract base class WriteIncludesBase from WriteIncludes which basically adds the dependent classes. Move the classlibmap there as well. Task-number: PYSIDE-1404 Change-Id: I899c7818cb96dd3b1af5f328cd20d64fbaf7755b Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/uic/CMakeLists.txt1
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.cpp163
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.h45
-rw-r--r--src/tools/uic/shared/writeincludesbase.cpp160
-rw-r--r--src/tools/uic/shared/writeincludesbase.h99
5 files changed, 288 insertions, 180 deletions
diff --git a/src/tools/uic/CMakeLists.txt b/src/tools/uic/CMakeLists.txt
index 73ea838b34..e0747cbc50 100644
--- a/src/tools/uic/CMakeLists.txt
+++ b/src/tools/uic/CMakeLists.txt
@@ -21,6 +21,7 @@ qt_internal_add_tool(${target_name}
python/pythonwritedeclaration.cpp python/pythonwritedeclaration.h
python/pythonwriteimports.cpp python/pythonwriteimports.h
shared/language.cpp shared/language.h
+ shared/writeincludesbase.cpp shared/writeincludesbase.h
treewalker.cpp treewalker.h
ui4.cpp ui4.h
uic.cpp uic.h
diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp
index 9784825c72..809c78f700 100644
--- a/src/tools/uic/cpp/cppwriteincludes.cpp
+++ b/src/tools/uic/cpp/cppwriteincludes.cpp
@@ -43,20 +43,6 @@ QT_BEGIN_NAMESPACE
enum { debugWriteIncludes = 0 };
enum { warnHeaderGeneration = 0 };
-struct ClassInfoEntry
-{
- const char *klass;
- const char *module;
- const char *header;
-};
-
-static const ClassInfoEntry qclass_lib_map[] = {
-#define QT_CLASS_LIB(klass, module, header) { #klass, #module, #header },
-#include "qclass_lib_map.h"
-
-#undef QT_CLASS_LIB
-};
-
// Format a module header as 'QtCore/QObject'
static inline QString moduleHeader(const QString &module, const QString &header)
{
@@ -68,18 +54,17 @@ static inline QString moduleHeader(const QString &module, const QString &header)
namespace CPP {
-WriteIncludes::WriteIncludes(Uic *uic)
- : m_uic(uic), m_output(uic->output())
+WriteIncludes::WriteIncludes(Uic *uic) : WriteIncludesBase(uic),
+ m_output(uic->output())
{
// When possible (no namespace) use the "QtModule/QClass" convention
// and create a re-mapping of the old header "qclass.h" to it. Do not do this
// for the "Phonon::Someclass" classes, however.
const QString namespaceDelimiter = QLatin1String("::");
- const ClassInfoEntry *classLibEnd = qclass_lib_map + sizeof(qclass_lib_map)/sizeof(ClassInfoEntry);
- for (const ClassInfoEntry *it = qclass_lib_map; it < classLibEnd; ++it) {
- const QString klass = QLatin1String(it->klass);
- const QString module = QLatin1String(it->module);
- QLatin1String header = QLatin1String(it->header);
+ for (const auto &e : classInfoEntries()) {
+ const QString klass = QLatin1String(e.klass);
+ const QString module = QLatin1String(e.module);
+ QLatin1String header = QLatin1String(e.header);
if (klass.contains(namespaceDelimiter)) {
m_classToHeader.insert(klass, moduleHeader(module, header));
} else {
@@ -92,27 +77,13 @@ WriteIncludes::WriteIncludes(Uic *uic)
void WriteIncludes::acceptUI(DomUI *node)
{
- m_laidOut = false;
m_localIncludes.clear();
m_globalIncludes.clear();
- m_knownClasses.clear();
m_includeBaseNames.clear();
- if (node->elementIncludes())
- acceptIncludes(node->elementIncludes());
-
- if (node->elementCustomWidgets())
- TreeWalker::acceptCustomWidgets(node->elementCustomWidgets());
-
- add(QLatin1String("QApplication"));
- add(QLatin1String("QVariant"));
-
- if (node->elementButtonGroups())
- add(QLatin1String("QButtonGroup"));
+ WriteIncludesBase::acceptUI(node);
- TreeWalker::acceptUI(node);
-
- const auto includeFile = m_uic->option().includeFile;
+ const auto includeFile = uic()->option().includeFile;
if (!includeFile.isEmpty())
m_globalIncludes.insert(includeFile);
@@ -122,39 +93,6 @@ void WriteIncludes::acceptUI(DomUI *node)
m_output << '\n';
}
-void WriteIncludes::acceptWidget(DomWidget *node)
-{
- if (debugWriteIncludes)
- fprintf(stderr, "%s '%s'\n", Q_FUNC_INFO, qPrintable(node->attributeClass()));
-
- add(node->attributeClass());
- TreeWalker::acceptWidget(node);
-}
-
-void WriteIncludes::acceptLayout(DomLayout *node)
-{
- add(node->attributeClass());
- m_laidOut = true;
- TreeWalker::acceptLayout(node);
-}
-
-void WriteIncludes::acceptSpacer(DomSpacer *node)
-{
- add(QLatin1String("QSpacerItem"));
- TreeWalker::acceptSpacer(node);
-}
-
-void WriteIncludes::acceptProperty(DomProperty *node)
-{
- if (node->kind() == DomProperty::Date)
- add(QLatin1String("QDate"));
- if (node->kind() == DomProperty::Locale)
- add(QLatin1String("QLocale"));
- if (node->kind() == DomProperty::IconSet)
- add(QLatin1String("QIcon"));
- TreeWalker::acceptProperty(node);
-}
-
void WriteIncludes::insertIncludeForClass(const QString &className, QString header, bool global)
{
if (debugWriteIncludes)
@@ -185,13 +123,13 @@ void WriteIncludes::insertIncludeForClass(const QString &className, QString head
}
// Last resort: Create default header
- if (!m_uic->option().implicitIncludes)
+ if (!uic()->option().implicitIncludes)
break;
header = lowerClassName;
header += QLatin1String(".h");
if (warnHeaderGeneration) {
qWarning("%s: Warning: generated header '%s' for class '%s'.",
- qPrintable(m_uic->option().messagePrefix()),
+ qPrintable(uic()->option().messagePrefix()),
qPrintable(header), qPrintable(className));
}
@@ -203,87 +141,30 @@ void WriteIncludes::insertIncludeForClass(const QString &className, QString head
insertInclude(header, global);
}
-void WriteIncludes::add(const QString &className, bool determineHeader, const QString &header, bool global)
+void WriteIncludes::doAdd(const QString &className, const DomCustomWidget *dcw)
{
- if (debugWriteIncludes)
- fprintf(stderr, "%s %s '%s' %d\n", Q_FUNC_INFO, qPrintable(className), qPrintable(header), global);
-
- if (className.isEmpty() || m_knownClasses.contains(className))
- return;
-
- m_knownClasses.insert(className);
-
- const CustomWidgetsInfo *cwi = m_uic->customWidgetsInfo();
- static const QStringList treeViewsWithHeaders = {
- QLatin1String("QTreeView"), QLatin1String("QTreeWidget"),
- QLatin1String("QTableView"), QLatin1String("QTableWidget")
- };
- if (cwi->extendsOneOf(className, treeViewsWithHeaders))
- add(QLatin1String("QHeaderView"));
-
- if (!m_laidOut && cwi->extends(className, QLatin1String("QToolBox")))
- add(QLatin1String("QLayout")); // spacing property of QToolBox)
-
- if (className == QLatin1String("Line")) { // ### hmm, deprecate me!
- add(QLatin1String("QFrame"));
- return;
- }
-
- if (cwi->extends(className, QLatin1String("QDialogButtonBox")))
- add(QLatin1String("QAbstractButton")); // for signal "clicked(QAbstractButton*)"
-
- if (determineHeader)
- insertIncludeForClass(className, header, global);
+ if (dcw != nullptr)
+ addCppCustomWidget(className, dcw);
+ else
+ insertIncludeForClass(className, {}, false);
}
-void WriteIncludes::acceptCustomWidget(DomCustomWidget *node)
+void WriteIncludes::addCppCustomWidget(const QString &className, const DomCustomWidget *dcw)
{
- const QString className = node->elementClass();
- if (className.isEmpty())
- return;
-
- if (!node->elementHeader() || node->elementHeader()->text().isEmpty()) {
- add(className, false); // no header specified
- } else {
+ const DomHeader *domHeader = dcw->elementHeader();
+ if (domHeader != nullptr && !domHeader->text().isEmpty()) {
// custom header unless it is a built-in qt class
QString header;
bool global = false;
if (!m_classToHeader.contains(className)) {
- global = node->elementHeader()->attributeLocation().toLower() == QLatin1String("global");
- header = node->elementHeader()->text();
+ global = domHeader->attributeLocation().toLower() == QLatin1String("global");
+ header = domHeader->text();
}
- add(className, true, header, global);
+ insertIncludeForClass(className, header, global);
+ return;
}
}
-void WriteIncludes::acceptActionGroup(DomActionGroup *node)
-{
- add(QLatin1String("QActionGroup"));
- TreeWalker::acceptActionGroup(node);
-}
-
-void WriteIncludes::acceptAction(DomAction *node)
-{
- add(QLatin1String("QAction"));
- TreeWalker::acceptAction(node);
-}
-
-void WriteIncludes::acceptActionRef(DomActionRef *node)
-{
- add(QLatin1String("QAction"));
- TreeWalker::acceptActionRef(node);
-}
-
-void WriteIncludes::acceptCustomWidgets(DomCustomWidgets *node)
-{
- Q_UNUSED(node);
-}
-
-void WriteIncludes::acceptIncludes(DomIncludes *node)
-{
- TreeWalker::acceptIncludes(node);
-}
-
void WriteIncludes::acceptInclude(DomInclude *node)
{
bool global = true;
diff --git a/src/tools/uic/cpp/cppwriteincludes.h b/src/tools/uic/cpp/cppwriteincludes.h
index 9b9ac283fe..4ff2a514fb 100644
--- a/src/tools/uic/cpp/cppwriteincludes.h
+++ b/src/tools/uic/cpp/cppwriteincludes.h
@@ -29,79 +29,46 @@
#ifndef CPPWRITEINCLUDES_H
#define CPPWRITEINCLUDES_H
-#include "treewalker.h"
+#include <writeincludesbase.h>
-#include <qmap.h>
-#include <qset.h>
-#include <qstring.h>
+#include <QtCore/qmap.h>
#include <set>
QT_BEGIN_NAMESPACE
class QTextStream;
-class CustomWidgetsInfo;
-class Driver;
-class Uic;
namespace CPP {
-struct WriteIncludes : public TreeWalker
+class WriteIncludes : public WriteIncludesBase
{
+public:
WriteIncludes(Uic *uic);
void acceptUI(DomUI *node) override;
- void acceptWidget(DomWidget *node) override;
- void acceptLayout(DomLayout *node) override;
- void acceptSpacer(DomSpacer *node) override;
- void acceptProperty(DomProperty *node) override;
-
-//
-// actions
-//
- void acceptActionGroup(DomActionGroup *node) override;
- void acceptAction(DomAction *node) override;
- void acceptActionRef(DomActionRef *node) override;
-
-//
-// custom widgets
-//
- void acceptCustomWidgets(DomCustomWidgets *node) override;
- void acceptCustomWidget(DomCustomWidget *node) override;
-
-//
-// include hints
-//
- void acceptIncludes(DomIncludes *node) override;
void acceptInclude(DomInclude *node) override;
protected:
QTextStream &output() const { return m_output; }
-
-private:
- void add(const QString &className, bool determineHeader = true, const QString &header = QString(), bool global = false);
+ void doAdd(const QString &className, const DomCustomWidget *dcw = nullptr) override;
private:
using OrderedSet = std::set<QString>;
+ void addCppCustomWidget(const QString &className, const DomCustomWidget *dcw);
void insertIncludeForClass(const QString &className, QString header = QString(), bool global = false);
void insertInclude(const QString &header, bool global);
void writeHeaders(const OrderedSet &headers, bool global);
QString headerForClassName(const QString &className) const;
- const Uic *m_uic;
QTextStream &m_output;
OrderedSet m_localIncludes;
OrderedSet m_globalIncludes;
QSet<QString> m_includeBaseNames;
-
- QSet<QString> m_knownClasses;
-
using StringMap = QMap<QString, QString>;
StringMap m_classToHeader;
StringMap m_oldHeaderToNewHeader;
-
- bool m_laidOut = false;
};
} // namespace CPP
diff --git a/src/tools/uic/shared/writeincludesbase.cpp b/src/tools/uic/shared/writeincludesbase.cpp
new file mode 100644
index 0000000000..128200ed68
--- /dev/null
+++ b/src/tools/uic/shared/writeincludesbase.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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$
+**
+****************************************************************************/
+
+#include "writeincludesbase.h"
+#include "ui4.h"
+#include <uic.h>
+#include <databaseinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+static const ClassInfoEntry qclass_lib_map[] = {
+#define QT_CLASS_LIB(klass, module, header) { #klass, #module, #header },
+#include "qclass_lib_map.h"
+#undef QT_CLASS_LIB
+};
+
+ClassInfoEntries classInfoEntries()
+{
+ const ClassInfoEntry *classLibEnd = qclass_lib_map + sizeof(qclass_lib_map)/sizeof(ClassInfoEntry);
+ return {qclass_lib_map, classLibEnd};
+}
+
+// Base class for implementing a class that determines includes and equivalents
+// in other languages by implementing doAdd(). It makes sure all dependent
+// classes are known.
+WriteIncludesBase::WriteIncludesBase(Uic *uic) : m_uic(uic)
+{
+}
+
+void WriteIncludesBase::acceptUI(DomUI *node)
+{
+ m_knownClasses.clear();
+ m_laidOut = false;
+
+ if (node->elementIncludes())
+ acceptIncludes(node->elementIncludes());
+
+ // Populate known custom widgets first
+ if (node->elementCustomWidgets())
+ TreeWalker::acceptCustomWidgets(node->elementCustomWidgets());
+
+ add(QStringLiteral("QApplication"));
+ add(QStringLiteral("QVariant"));
+
+ if (node->elementButtonGroups())
+ add(QStringLiteral("QButtonGroup"));
+
+ TreeWalker::acceptUI(node);
+}
+
+void WriteIncludesBase::acceptWidget(DomWidget *node)
+{
+ add(node->attributeClass());
+ TreeWalker::acceptWidget(node);
+}
+
+void WriteIncludesBase::acceptLayout(DomLayout *node)
+{
+ add(node->attributeClass());
+ m_laidOut = true;
+ TreeWalker::acceptLayout(node);
+}
+
+void WriteIncludesBase::acceptSpacer(DomSpacer *node)
+{
+ add(QStringLiteral("QSpacerItem"));
+ TreeWalker::acceptSpacer(node);
+}
+
+void WriteIncludesBase::acceptProperty(DomProperty *node)
+{
+ if (node->kind() == DomProperty::Date)
+ add(QStringLiteral("QDate"));
+ if (node->kind() == DomProperty::Locale)
+ add(QStringLiteral("QLocale"));
+ if (node->kind() == DomProperty::IconSet)
+ add(QStringLiteral("QIcon"));
+ TreeWalker::acceptProperty(node);
+}
+
+void WriteIncludesBase::add(const QString &className, const DomCustomWidget *dcw)
+{
+ if (className.isEmpty() || m_knownClasses.contains(className))
+ return;
+
+ m_knownClasses.insert(className);
+
+ const CustomWidgetsInfo *cwi = m_uic->customWidgetsInfo();
+ static const QStringList treeViewsWithHeaders = {
+ QStringLiteral("QTreeView"), QStringLiteral("QTreeWidget"),
+ QStringLiteral("QTableView"), QStringLiteral("QTableWidget")
+ };
+ if (cwi->extendsOneOf(className, treeViewsWithHeaders))
+ add(QStringLiteral("QHeaderView"));
+
+ if (!m_laidOut && cwi->extends(className, QLatin1String("QToolBox")))
+ add(QStringLiteral("QLayout")); // spacing property of QToolBox)
+
+ if (className == QStringLiteral("Line")) { // ### hmm, deprecate me!
+ add(QStringLiteral("QFrame"));
+ return;
+ }
+
+ if (cwi->extends(className, QLatin1String("QDialogButtonBox")))
+ add(QStringLiteral("QAbstractButton")); // for signal "clicked(QAbstractButton*)"
+
+ doAdd(className, dcw);
+}
+
+void WriteIncludesBase::acceptCustomWidget(DomCustomWidget *node)
+{
+ const QString className = node->elementClass();
+ if (!className.isEmpty())
+ add(className, node);
+}
+
+void WriteIncludesBase::acceptActionGroup(DomActionGroup *node)
+{
+ add(QStringLiteral("QActionGroup"));
+ TreeWalker::acceptActionGroup(node);
+}
+
+void WriteIncludesBase::acceptAction(DomAction *node)
+{
+ add(QStringLiteral("QAction"));
+ TreeWalker::acceptAction(node);
+}
+
+void WriteIncludesBase::acceptActionRef(DomActionRef *node)
+{
+ add(QStringLiteral("QAction"));
+ TreeWalker::acceptActionRef(node);
+}
+
+QT_END_NAMESPACE
diff --git a/src/tools/uic/shared/writeincludesbase.h b/src/tools/uic/shared/writeincludesbase.h
new file mode 100644
index 0000000000..15e57b8c36
--- /dev/null
+++ b/src/tools/uic/shared/writeincludesbase.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 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$
+**
+****************************************************************************/
+
+#ifndef WRITEINCLUDES_BASE_H
+#define WRITEINCLUDES_BASE_H
+
+#include <treewalker.h>
+
+#include <QtCore/qset.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class DomCustomWidget;
+class Uic;
+
+struct ClassInfoEntry
+{
+ const char *klass;
+ const char *module;
+ const char *header;
+};
+
+struct ClassInfoEntries
+{
+ const ClassInfoEntry *begin() const { return m_begin; }
+ const ClassInfoEntry *end() const { return m_end; }
+
+ const ClassInfoEntry *m_begin;
+ const ClassInfoEntry *m_end;
+};
+
+ClassInfoEntries classInfoEntries();
+
+class WriteIncludesBase : public TreeWalker
+{
+public:
+ explicit WriteIncludesBase(Uic *uic);
+
+ void acceptUI(DomUI *node) override;
+ void acceptWidget(DomWidget *node) override;
+ void acceptLayout(DomLayout *node) override;
+ void acceptSpacer(DomSpacer *node) override;
+ void acceptProperty(DomProperty *node) override;
+
+ //
+ // actions
+ //
+ void acceptActionGroup(DomActionGroup *node) override;
+ void acceptAction(DomAction *node) override;
+ void acceptActionRef(DomActionRef *node) override;
+
+ //
+ // custom widgets
+ //
+ void acceptCustomWidget(DomCustomWidget *node) override;
+
+protected:
+ void add(const QString &className, const DomCustomWidget *dcw = nullptr);
+
+ virtual void doAdd(const QString &className, const DomCustomWidget *dcw = nullptr) = 0;
+
+ const Uic *uic() const { return m_uic; }
+ Uic *uic() { return m_uic; }
+
+private:
+ QSet<QString> m_knownClasses;
+ Uic *m_uic;
+ bool m_laidOut = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // WRITEINCLUDES_BASE_H