diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-05-03 09:47:12 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2021-05-25 22:01:53 +0200 |
commit | 4b82c1c7278baf154a6a53fc8ce21f3b62d3479c (patch) | |
tree | 9bf20525ddc7320a7b5101f35234df6a7a2e4a8b /src/tools | |
parent | 6ecde6265a08163d47a834cb5591fdb22461d129 (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.txt | 1 | ||||
-rw-r--r-- | src/tools/uic/cpp/cppwriteincludes.cpp | 163 | ||||
-rw-r--r-- | src/tools/uic/cpp/cppwriteincludes.h | 45 | ||||
-rw-r--r-- | src/tools/uic/shared/writeincludesbase.cpp | 160 | ||||
-rw-r--r-- | src/tools/uic/shared/writeincludesbase.h | 99 |
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 |