12#include <qtextstream.h>
18using namespace Qt::StringLiterals;
24static inline QString
moduleHeader(
const QString &module,
const QString &header)
40 const QLatin1StringView namespaceDelimiter =
"::"_L1;
42 const QString klass = QLatin1StringView(e.klass);
43 const QString module = QLatin1StringView(e.module);
44 QLatin1StringView header(e
.header);
45 if (klass.contains(namespaceDelimiter)) {
46 m_classToHeader.insert(klass, moduleHeader(module, header));
48 const QString newHeader = moduleHeader(module, klass);
49 m_classToHeader.insert(klass, newHeader);
50 m_oldHeaderToNewHeader.insert(header, newHeader);
57 m_localIncludes.clear();
58 m_globalIncludes.clear();
59 m_includeBaseNames.clear();
63 const auto includeFile = uic()->option().includeFile;
64 if (!includeFile.isEmpty())
65 m_globalIncludes.insert(includeFile);
67 writeHeaders(m_globalIncludes,
true);
68 writeHeaders(m_localIncludes,
false);
73void WriteIncludes::insertIncludeForClass(
const QString &className, QString header,
bool global)
75 if (debugWriteIncludes)
76 std::fprintf(stderr,
"%s %s '%s' %d\n", Q_FUNC_INFO,
qPrintable(className),
qPrintable(header), global);
79 if (!header.isEmpty())
83 const StringMap::const_iterator it = m_classToHeader.constFind(className);
84 if (it != m_classToHeader.constEnd()) {
92 QString lowerClassName = className.toLower();
93 static const auto namespaceSeparator =
"::"_L1;
94 const auto namespaceIndex = lowerClassName.lastIndexOf(namespaceSeparator);
95 if (namespaceIndex != -1)
96 lowerClassName.remove(0, namespaceIndex + namespaceSeparator.size());
97 if (m_includeBaseNames.contains(lowerClassName)) {
103 if (!uic()->option().implicitIncludes)
105 header = lowerClassName;
108 qWarning(
"%s: Warning: generated header '%s' for class '%s'.",
117 if (!header.isEmpty())
118 insertInclude(header, global);
121void WriteIncludes::doAdd(
const QString &className,
const DomCustomWidget *dcw)
124 addCppCustomWidget(className, dcw);
126 insertIncludeForClass(className, {},
false);
129void WriteIncludes::addCppCustomWidget(
const QString &className,
const DomCustomWidget *dcw)
131 const DomHeader *domHeader = dcw->elementHeader();
132 if (domHeader !=
nullptr && !domHeader->text().isEmpty()) {
136 if (!m_classToHeader.contains(className)) {
137 global = domHeader->attributeLocation().toLower() ==
"global"_L1;
138 header = domHeader->text();
140 insertIncludeForClass(className, header, global);
148 if (node->hasAttributeLocation())
149 global = node->attributeLocation() ==
"global"_L1;
150 insertInclude(node->text(), global);
153void WriteIncludes::insertInclude(
const QString &header,
bool global)
155 if (debugWriteIncludes)
156 fprintf(stderr,
"%s %s %d\n", Q_FUNC_INFO,
qPrintable(header), global);
158 OrderedSet &includes = global ? m_globalIncludes : m_localIncludes;
160 const bool isNewHeader = includes.insert(header).second;
164 const QString lowerBaseName = QFileInfo(header).completeBaseName ().toLower();
165 m_includeBaseNames.insert(lowerBaseName);
168void WriteIncludes::writeHeaders(
const OrderedSet &headers,
bool global)
170 const QChar openingQuote = global ? u'<' : u'"';
171 const QChar closingQuote = global ? u'>' : u'"';
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';
void acceptUI(DomUI *node) override
void acceptInclude(DomInclude *node) override
WriteIncludesBase(Uic *uic)
void acceptUI(DomUI *node) override
static QString moduleHeader(const QString &module, const QString &header)
const QString & asString(const QString &s)
#define qPrintable(string)
ClassInfoEntries classInfoEntries()