14#include "KConfigHeaderGenerator.h"
21 : KConfigCodeGeneratorBase(inputFile, baseDir, baseDir + cfg.baseName +
QLatin1Char(
'.') + cfg.headerExtension, cfg, result)
25void KConfigHeaderGenerator::start()
27 KConfigCodeGeneratorBase::start();
33 createForwardDeclarations();
41void KConfigHeaderGenerator::doClassDefinition()
43 stream() <<
"class " << cfg().visibility << cfg().className <<
" : public " << cfg().inherits <<
'\n';
47 if (!parseResult.signalList.
isEmpty() || cfg().generateProperties) {
48 stream() <<
" Q_OBJECT\n";
50 stream() <<
" public:\n";
55 for (
const auto *entry :
std::as_const(parseResult.entries)) {
56 const QString returnType = (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) ? enumType(entry, cfg().globalEnums) : cppType(entry->
type);
59 createProperties(entry, returnType);
60 createImmutableProperty(entry);
61 createGetters(entry, returnType);
62 createImmutableGetters(entry);
63 createDefaultValueMember(entry);
64 createItemAcessors(entry, returnType);
68 stream() <<
" protected:\n";
72 if (parseResult.hasNonModifySignals) {
73 stream() << whitespace() <<
"bool usrSave() override;\n";
77 if (!cfg().memberVariables.isEmpty()
80 stream() <<
" " << cfg().memberVariables <<
":\n";
84 for (
const auto ¶meter :
std::as_const(parseResult.parameters)) {
85 stream() << whitespace() <<
"" << cppType(parameter.type) <<
" mParam" << parameter.name <<
";\n";
88 createNonDPointerHelpers();
91 if (cfg().customAddons) {
92 stream() << whitespace() <<
"// Include custom additions\n";
93 stream() << whitespace() <<
"#include \"" << cfg().baseName <<
"_addons." << cfg().headerExtension <<
"\"\n";
96 endScope(ScopeFinalizer::Semicolon);
99void KConfigHeaderGenerator::createHeaders()
101 addHeaders(cfg().headerIncludes);
102 if (cfg().headerIncludes.size()) {
106 if (!cfg().singleton && parseResult.parameters.
isEmpty()) {
107 addHeaders({QStringLiteral(
"qglobal.h")});
110 if (cfg().inherits ==
QLatin1String(
"KCoreConfigSkeleton")) {
111 addHeaders({QStringLiteral(
"kcoreconfigskeleton.h")});
113 addHeaders({QStringLiteral(
"kconfigskeleton.h")});
116 addHeaders({QStringLiteral(
"QCoreApplication"), QStringLiteral(
"QDebug")});
117 if (!cfg().dpointer && parseResult.hasNonModifySignals) {
118 addHeaders({QStringLiteral(
"QSet")});
122 addHeaders(parseResult.includes);
123 if (parseResult.includes.
size()) {
128void KConfigHeaderGenerator::startHeaderGuards()
130 const bool hasNamespace = !cfg().nameSpace.
isEmpty();
133 const QString defineName = namespaceStr + cfg().className.
toUpper() + QStringLiteral(
"_H");
135 stream() <<
"#ifndef " << defineName <<
'\n';
136 stream() <<
"#define " << defineName <<
'\n';
140void KConfigHeaderGenerator::endHeaderGuards()
143 stream() <<
"#endif";
149void KConfigHeaderGenerator::implementChoiceEnums(
const CfgEntry *entry,
const CfgEntry::Choices &choices)
158 for (
const auto &choice :
std::as_const(chlist)) {
159 values.
append(choices.prefix + choice.name);
162 if (choices.name().
isEmpty()) {
163 if (cfg().globalEnums) {
164 stream() << whitespace() <<
"enum " << enumName(entry->name, entry->choices) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
165 if (cfg().generateProperties) {
166 stream() << whitespace() <<
"Q_ENUM(" << enumName(entry->name, entry->choices) <<
")\n";
170 stream() << whitespace() <<
"class " << enumName(entry->name, entry->choices) <<
'\n';
171 stream() << whitespace() <<
"{\n";
172 stream() << whitespace() <<
" public:\n";
173 stream() << whitespace() <<
" enum type { " << values.
join(QStringLiteral(
", ")) <<
", COUNT };\n";
174 stream() << whitespace() <<
"};\n";
176 }
else if (!choices.external()) {
178 stream() << whitespace() <<
"enum " << enumName(entry->name, entry->choices) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
182void KConfigHeaderGenerator::implementValueEnums(
const CfgEntry *entry,
const QStringList &values)
188 if (cfg().globalEnums) {
192 stream() << whitespace() <<
"enum " << enumName(entry->param) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
193 stream() << whitespace() <<
"static const char* const " << enumName(entry->param) <<
"ToString[];\n";
195 stream() << whitespace() <<
"class " << enumName(entry->param) <<
'\n';
196 stream() << whitespace() <<
"{\n";
197 stream() << whitespace() <<
" public:\n";
198 stream() << whitespace() <<
" enum type { " << values.
join(QStringLiteral(
", ")) <<
", COUNT };\n";
199 stream() << whitespace() <<
" static const char* const enumToString[];\n";
200 stream() << whitespace() <<
"};\n";
204void KConfigHeaderGenerator::implementEnums()
206 if (!parseResult.entries.
size()) {
210 for (
const auto *entry :
std::as_const(parseResult.entries)) {
211 const CfgEntry::Choices &choices = entry->choices;
214 implementChoiceEnums(entry, choices);
215 implementValueEnums(entry, values);
220void KConfigHeaderGenerator::createSignals()
223 if (parseResult.signalList.
isEmpty()) {
227 stream() <<
"\n enum {\n";
233 for (
int i = 0, end = parseResult.signalList.
size(); i <
end; i++) {
234 auto signal = parseResult.signalList.
at(i);
235 stream() << whitespace() <<
" " << signalEnumName(signal.name) <<
" = " << (i + 1);
241 stream() << whitespace() <<
"};\n\n";
243 stream() <<
" Q_SIGNALS:";
244 for (
const Signal &signal :
std::as_const(parseResult.signalList)) {
246 if (!signal.label.isEmpty()) {
247 stream() << whitespace() <<
"/**\n";
248 stream() << whitespace() <<
" " << signal.label <<
'\n';
249 stream() << whitespace() <<
"*/\n";
251 stream() << whitespace() <<
"void " << signal.name <<
"(";
253 auto it = signal.arguments.
cbegin();
254 const auto itEnd = signal.arguments.cend();
255 while (it != itEnd) {
256 Param argument = *it;
258 if (cfg().useEnumTypes && argument.type ==
QLatin1String(
"Enum")) {
259 for (
const auto *entry :
std::as_const(parseResult.entries)) {
260 if (entry->name == argument.name) {
261 type = enumType(entry, cfg().globalEnums);
266 stream() <<
type <<
" " << argument.name;
275 stream() <<
" private:\n";
276 stream() << whitespace() <<
"void itemChanged(quint64 signalFlag);\n";
280void KConfigHeaderGenerator::createDPointer()
282 if (!cfg().dpointer) {
287 stream() <<
" private:\n";
288 for (
const auto *entry :
std::as_const(parseResult.entries)) {
289 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) {
290 stream() << whitespace() <<
"";
291 if (cfg().staticAccessors) {
292 stream() <<
"static ";
294 stream() << cppType(entry->type) <<
" " << getDefaultFunction(entry->name) <<
"_helper(";
296 stream() <<
" " << cppType(entry->paramType) <<
" i ";
298 stream() <<
")" << Const() <<
";\n";
301 stream() << whitespace() <<
"" << cfg().className <<
"Private *d;\n";
304void KConfigHeaderGenerator::createConstructor()
306 if (cfg().singleton) {
307 stream() << whitespace() <<
"static " << cfg().className <<
" *self();\n";
308 if (parseResult.cfgFileNameArg) {
309 stream() << whitespace() <<
"static void instance(const QString& cfgfilename);\n";
310 stream() << whitespace() <<
"static void instance(KSharedConfig::Ptr config);\n";
315 stream() << whitespace() <<
"" << cfg().className <<
"(";
316 if (parseResult.cfgFileNameArg) {
317 if (cfg().forceStringFilename) {
318 stream() <<
" const QString &cfgfilename" << (parseResult.parameters.
isEmpty() ?
" = QString()" :
", ");
319 }
else if (parseResult.cfgStateConfig) {
320 stream() <<
" KSharedConfig::Ptr config" << (parseResult.parameters.
isEmpty() ?
" = KSharedConfig::openStateConfig()" :
", ");
322 stream() <<
" KSharedConfig::Ptr config" << (parseResult.parameters.
isEmpty() ?
" = KSharedConfig::openConfig()" :
", ");
325 if (cfg().forceStringFilename && parseResult.cfgStateConfig) {
326 std::cerr <<
"One can not use ForceStringFilename and use the stateConfig attribute, consider "
327 "removing the ForceStringFilename kcfgc option if you want to use state data"
332 for (
const auto ¶meter :
std::as_const(parseResult.parameters)) {
339 stream() <<
" " << param(parameter.type) <<
" " << parameter.name;
342 if (cfg().parentInConstructor) {
343 if (parseResult.cfgFileNameArg || !parseResult.parameters.
isEmpty()) {
346 stream() <<
" QObject *parent = nullptr";
351void KConfigHeaderGenerator::createDestructor()
353 stream() << whitespace() <<
"~" << cfg().className <<
"() override;\n\n";
356void KConfigHeaderGenerator::createForwardDeclarations()
359 if (cfg().dpointer) {
360 stream() <<
"class " << cfg().className <<
"Private;\n\n";
364void KConfigHeaderGenerator::createProperties(
const CfgEntry *entry,
const QString &returnType)
366 if (!cfg().generateProperties) {
369 stream() << whitespace() <<
"Q_PROPERTY(" << returnType <<
' ' << getFunction(entry->name);
370 stream() <<
" READ " << getFunction(entry->name);
372 if (cfg().allMutators || cfg().mutators.contains(entry->name)) {
373 const QString signal = changeSignalName(entry->name);
374 stream() <<
" WRITE " << setFunction(entry->name);
375 stream() <<
" NOTIFY " << signal;
382 parseResult.signalList.
append(s);
384 stream() <<
" CONSTANT";
389void KConfigHeaderGenerator::createImmutableProperty(
const CfgEntry *entry)
391 if (!cfg().generateProperties) {
394 stream() << whitespace();
395 stream() <<
"Q_PROPERTY(bool " << immutableFunction(entry->name);
396 stream() <<
" READ " << immutableFunction(entry->name);
397 stream() <<
" CONSTANT)\n";
400void KConfigHeaderGenerator::createSetters(
const CfgEntry *entry)
403 if (!cfg().allMutators && !cfg().mutators.contains(entry->name)) {
407 stream() << whitespace() <<
"/**\n";
408 stream() << whitespace() <<
" Set " << entry->label <<
'\n';
409 stream() << whitespace() <<
"*/\n";
411 if (cfg().staticAccessors) {
412 stream() << whitespace() <<
"static\n";
415 stream() << whitespace() <<
"void " << setFunction(entry->name) <<
"( ";
417 stream() << cppType(entry->paramType) <<
" i, ";
420 stream() << (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum") ? enumType(entry, cfg().globalEnums) : param(entry->
type));
426 if (!cfg().dpointer) {
429 memberMutatorBody(entry);
437void KConfigHeaderGenerator::createGetters(
const CfgEntry *entry,
const QString &returnType)
440 stream() << whitespace() <<
"/**\n";
441 stream() << whitespace() <<
" Get " << entry->label <<
'\n';
442 stream() << whitespace() <<
"*/\n";
443 if (cfg().staticAccessors) {
444 stream() << whitespace() <<
"static\n";
446 stream() << whitespace() <<
"";
447 stream() << returnType;
448 stream() <<
" " << getFunction(entry->name) <<
"(";
450 stream() <<
" " << cppType(entry->paramType) <<
" i ";
452 stream() <<
")" << Const();
456 if (!cfg().dpointer) {
459 stream() << whitespace() << memberAccessorBody(entry, cfg().globalEnums);
467void KConfigHeaderGenerator::createImmutableGetters(
const CfgEntry *entry)
469 stream() << whitespace() <<
"/**\n";
470 stream() << whitespace() <<
" Is " << entry->label <<
" Immutable\n";
471 stream() << whitespace() <<
"*/\n";
473 if (cfg().staticAccessors) {
474 stream() << whitespace() <<
"static\n";
476 stream() << whitespace() <<
"";
477 stream() <<
"bool " << immutableFunction(entry->name) <<
"(";
479 stream() <<
" " << cppType(entry->paramType) <<
" i ";
481 stream() <<
")" << Const();
484 if (!cfg().dpointer) {
487 memberImmutableBody(entry, cfg().globalEnums);
495void KConfigHeaderGenerator::createItemAcessors(
const CfgEntry *entry,
const QString &returnType)
500 if (!cfg().itemAccessors) {
504 const QString declType = entry->signalList.
isEmpty() ? QStringLiteral(
"Item") + itemType(entry->type) : QStringLiteral(
"KConfigCompilerSignallingItem");
506 stream() << whitespace() <<
"/**\n";
507 stream() << whitespace() <<
" Get Item object corresponding to " << entry->name <<
"()" <<
'\n';
508 stream() << whitespace() <<
"*/\n";
509 stream() << whitespace() << declType <<
" *" << getFunction(entry->name) <<
"Item(";
511 stream() <<
" " << cppType(entry->paramType) <<
" i ";
514 if (!cfg().dpointer) {
517 stream() << whitespace() << itemAccessorBody(entry, cfg());
526void KConfigHeaderGenerator::createDefaultValueMember(
const CfgEntry *entry)
529 if (!((cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) && !entry->defaultValue.
isEmpty())) {
532 stream() << whitespace() <<
"/**\n";
533 stream() << whitespace() <<
" Get " << entry->label <<
" default value\n";
534 stream() << whitespace() <<
"*/\n";
535 if (cfg().staticAccessors) {
536 stream() << whitespace() <<
"static\n";
538 stream() << whitespace() <<
"";
539 if (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) {
540 stream() << enumType(entry, cfg().globalEnums);
542 stream() << cppType(entry->type);
544 stream() <<
" " << getDefaultFunction(entry->name) <<
"(";
546 stream() <<
" " << cppType(entry->paramType) <<
" i ";
548 stream() <<
")" << Const() <<
'\n';
549 stream() << whitespace() <<
"{\n";
550 stream() << whitespace() <<
" return ";
551 if (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) {
552 stream() <<
"static_cast<" << enumType(entry, cfg().globalEnums) <<
">(";
554 stream() << getDefaultFunction(entry->name) <<
"_helper(";
559 if (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) {
563 stream() << whitespace() <<
"}\n";
567void KConfigHeaderGenerator::createSingleton()
570 if (!cfg().singleton) {
574 stream() << whitespace() <<
"" << cfg().className <<
"(";
575 if (parseResult.cfgFileNameArg) {
576 stream() <<
"KSharedConfig::Ptr config";
578 if (cfg().parentInConstructor) {
579 if (parseResult.cfgFileNameArg) {
582 stream() <<
"QObject *parent = nullptr";
585 stream() << whitespace() <<
"friend class " << cfg().className <<
"Helper;\n\n";
588void KConfigHeaderGenerator::createNonDPointerHelpers()
595 for (
const auto *entry :
std::as_const(parseResult.entries)) {
596 if (entry->group != group) {
597 group = entry->group;
599 stream() << whitespace() <<
"// " << group <<
'\n';
601 stream() << whitespace() <<
"" << cppType(entry->type) <<
" " << varName(entry->name, cfg());
603 stream() << QStringLiteral(
"[%1]").arg(entry->paramMax + 1);
607 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) {
608 stream() << whitespace() <<
"";
609 if (cfg().staticAccessors) {
610 stream() <<
"static ";
612 stream() << cppType(entry->type) <<
" " << getDefaultFunction(entry->name) <<
"_helper(";
614 stream() <<
" " << cppType(entry->paramType) <<
" i ";
616 stream() <<
")" << Const() <<
";\n";
620 stream() <<
"\n private:\n";
621 if (cfg().itemAccessors) {
622 for (
const auto *entry :
std::as_const(parseResult.entries)) {
624 entry->signalList.
isEmpty() ? QStringLiteral(
"Item") + itemType(entry->type) : QStringLiteral(
"KConfigCompilerSignallingItem");
625 stream() << whitespace() << declType <<
" *" << itemVar(entry, cfg());
627 stream() << QStringLiteral(
"[%1]").arg(entry->paramMax + 1);
633 if (parseResult.hasNonModifySignals) {
634 stream() << whitespace() <<
"QSet<quint64> " << varName(QStringLiteral(
"settingsChanged"), cfg()) <<
";\n";
Configuration Compiler Configuration.
Type type(const QSqlDatabase &db)
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
QAction * replace(const QObject *recvr, const char *slot, QObject *parent)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
bool isEmpty() const const
qsizetype size() const const
const_iterator cbegin() const const
bool isEmpty() const const
QString toUpper() const const
QString join(QChar separator) const const