Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
cppwriteincludes.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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 "cppwriteincludes.h"
5#include "driver.h"
6#include "ui4.h"
7#include "uic.h"
8#include "databaseinfo.h"
9
10#include <qdebug.h>
11#include <qfileinfo.h>
12#include <qtextstream.h>
13
14#include <stdio.h>
15
17
18using namespace Qt::StringLiterals;
19
20enum { debugWriteIncludes = 0 };
22
23// Format a module header as 'QtCore/QObject'
24static inline QString moduleHeader(const QString &module, const QString &header)
25{
26 QString rc = module;
27 rc += u'/';
28 rc += header;
29 return rc;
30}
31
32namespace CPP {
33
35 m_output(uic->output())
36{
37 // When possible (no namespace) use the "QtModule/QClass" convention
38 // and create a re-mapping of the old header "qclass.h" to it. Do not do this
39 // for the "Phonon::Someclass" classes, however.
40 const QLatin1StringView namespaceDelimiter = "::"_L1;
41 for (const auto &e : classInfoEntries()) {
42 const QString klass = QLatin1StringView(e.klass);
43 const QString module = QLatin1StringView(e.module);
45 if (klass.contains(namespaceDelimiter)) {
46 m_classToHeader.insert(klass, moduleHeader(module, header));
47 } else {
48 const QString newHeader = moduleHeader(module, klass);
49 m_classToHeader.insert(klass, newHeader);
50 m_oldHeaderToNewHeader.insert(header, newHeader);
51 }
52 }
53}
54
56{
57 m_localIncludes.clear();
58 m_globalIncludes.clear();
59 m_includeBaseNames.clear();
60
62
63 const auto includeFile = uic()->option().includeFile;
64 if (!includeFile.isEmpty())
65 m_globalIncludes.insert(includeFile);
66
67 writeHeaders(m_globalIncludes, true);
68 writeHeaders(m_localIncludes, false);
69
70 m_output << '\n';
71}
72
73void WriteIncludes::insertIncludeForClass(const QString &className, QString header, bool global)
74{
76 fprintf(stderr, "%s %s '%s' %d\n", Q_FUNC_INFO, qPrintable(className), qPrintable(header), global);
77
78 do {
79 if (!header.isEmpty())
80 break;
81
82 // Known class
83 const StringMap::const_iterator it = m_classToHeader.constFind(className);
84 if (it != m_classToHeader.constEnd()) {
85 header = it.value();
86 global = true;
87 break;
88 }
89
90 // Quick check by class name to detect includehints provided for custom widgets.
91 // Remove namespaces
92 QString lowerClassName = className.toLower();
93 static const auto namespaceSeparator = "::"_L1;
94 const int namespaceIndex = lowerClassName.lastIndexOf(namespaceSeparator);
95 if (namespaceIndex != -1)
96 lowerClassName.remove(0, namespaceIndex + namespaceSeparator.size());
97 if (m_includeBaseNames.contains(lowerClassName)) {
98 header.clear();
99 break;
100 }
101
102 // Last resort: Create default header
103 if (!uic()->option().implicitIncludes)
104 break;
105 header = lowerClassName;
106 header += ".h"_L1;
108 qWarning("%s: Warning: generated header '%s' for class '%s'.",
109 qPrintable(uic()->option().messagePrefix()),
111
112 }
113
114 global = true;
115 } while (false);
116
117 if (!header.isEmpty())
118 insertInclude(header, global);
119}
120
122{
123 if (dcw != nullptr)
124 addCppCustomWidget(className, dcw);
125 else
126 insertIncludeForClass(className, {}, false);
127}
128
129void WriteIncludes::addCppCustomWidget(const QString &className, const DomCustomWidget *dcw)
130{
131 const DomHeader *domHeader = dcw->elementHeader();
132 if (domHeader != nullptr && !domHeader->text().isEmpty()) {
133 // custom header unless it is a built-in qt class
135 bool global = false;
136 if (!m_classToHeader.contains(className)) {
137 global = domHeader->attributeLocation().toLower() == "global"_L1;
138 header = domHeader->text();
139 }
140 insertIncludeForClass(className, header, global);
141 return;
142 }
143}
144
146{
147 bool global = true;
148 if (node->hasAttributeLocation())
149 global = node->attributeLocation() == "global"_L1;
150 insertInclude(node->text(), global);
151}
152
153void WriteIncludes::insertInclude(const QString &header, bool global)
154{
156 fprintf(stderr, "%s %s %d\n", Q_FUNC_INFO, qPrintable(header), global);
157
158 OrderedSet &includes = global ? m_globalIncludes : m_localIncludes;
159 // Insert (if not already done).
160 const bool isNewHeader = includes.insert(header).second;
161 if (!isNewHeader)
162 return;
163 // Also remember base name for quick check of suspicious custom plugins
164 const QString lowerBaseName = QFileInfo(header).completeBaseName ().toLower();
165 m_includeBaseNames.insert(lowerBaseName);
166}
167
168void WriteIncludes::writeHeaders(const OrderedSet &headers, bool global)
169{
170 const QChar openingQuote = global ? u'<' : u'"';
171 const QChar closingQuote = global ? u'>' : u'"';
172
173 // Check for the old headers 'qslider.h' and replace by 'QtGui/QSlider'
174 for (const QString &header : headers) {
175 const QString value = m_oldHeaderToNewHeader.value(header, header);
176 const auto trimmed = QStringView(value).trimmed();
177 if (!trimmed.isEmpty())
178 m_output << "#include " << openingQuote << trimmed << closingQuote << '\n';
179 }
180}
181
182} // namespace CPP
183
void acceptUI(DomUI *node) override
void acceptInclude(DomInclude *node) override
void doAdd(const QString &className, const DomCustomWidget *dcw=nullptr) override
QString attributeLocation() const
Definition ui4.h:353
bool hasAttributeLocation() const
Definition ui4.h:352
QString text() const
Definition ui4.h:348
Definition ui4.h:116
\inmodule QtCore
QString completeBaseName() const
Returns the complete base name of the file without the path.
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
bool contains(const Key &key) const
Definition qmap.h:341
const_iterator constFind(const Key &key) const
Definition qmap.h:655
const_iterator constEnd() const
Definition qmap.h:604
void clear()
Definition qset.h:61
bool contains(const T &value) const
Definition qset.h:71
iterator insert(const T &value)
Definition qset.h:155
\inmodule QtCore
Definition qstringview.h:78
QStringView trimmed() const noexcept
Strips leading and trailing whitespace and returns the result.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString toLower() const &
Definition qstring.h:435
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1369
Definition uic.h:30
const Option & option() const
Definition uic.h:44
const Uic * uic() const
void acceptUI(DomUI *node) override
@ debugWriteIncludes
@ warnHeaderGeneration
static QString moduleHeader(const QString &module, const QString &header)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define Q_FUNC_INFO
static QString header(const QString &name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
GLuint GLenum option
#define qPrintable(string)
Definition qstring.h:1531
QT_BEGIN_NAMESPACE typedef uchar * output
const char className[16]
[1]
Definition qwizard.cpp:100
QJSValue global
QString includeFile
Definition option.h:42
ClassInfoEntries classInfoEntries()