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";
51 if (cfg().qmlRegistration) {
52 stream() <<
" QML_ELEMENT\n";
54 if (cfg().singleton) {
55 stream() <<
" QML_SINGLETON\n";
58 stream() <<
" public:\n";
63 for (
const auto *entry : std::as_const(parseResult.entries)) {
64 const QString returnType = (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) ? enumType(entry, cfg().globalEnums) : cppType(entry->type);
67 createProperties(entry, returnType);
68 createImmutableProperty(entry);
69 createGetters(entry, returnType);
70 createImmutableGetters(entry);
71 createDefaultValueMember(entry);
72 createItemAcessors(entry, returnType);
76 stream() <<
" protected:\n";
80 if (parseResult.hasNonModifySignals) {
81 stream() << whitespace() <<
"bool usrSave() override;\n";
85 if (!cfg().memberVariables.isEmpty()
88 stream() <<
" " << cfg().memberVariables <<
":\n";
92 for (
const auto ¶meter : std::as_const(parseResult.parameters)) {
93 stream() << whitespace() <<
"" << cppType(parameter.type) <<
" mParam" << parameter.name <<
";\n";
96 createNonDPointerHelpers();
99 if (cfg().customAddons) {
100 stream() << whitespace() <<
"// Include custom additions\n";
101 stream() << whitespace() <<
"#include \"" << cfg().baseName <<
"_addons." << cfg().headerExtension <<
"\"\n";
104 endScope(ScopeFinalizer::Semicolon);
107void KConfigHeaderGenerator::createHeaders()
109 addHeaders(cfg().headerIncludes);
110 if (cfg().headerIncludes.size()) {
114 if (!cfg().singleton && parseResult.parameters.
isEmpty()) {
115 addHeaders({QStringLiteral(
"qglobal.h")});
118 if (cfg().inherits ==
QLatin1String(
"KCoreConfigSkeleton")) {
119 addHeaders({QStringLiteral(
"kcoreconfigskeleton.h")});
121 addHeaders({QStringLiteral(
"kconfigskeleton.h")});
124 addHeaders({QStringLiteral(
"QCoreApplication"), QStringLiteral(
"QDebug")});
125 if (!cfg().dpointer && parseResult.hasNonModifySignals) {
126 addHeaders({QStringLiteral(
"QSet")});
129 if (cfg().qmlRegistration) {
130 addHeaders({QStringLiteral(
"qqmlintegration.h")});
135 addHeaders(parseResult.includes);
136 if (parseResult.includes.
size()) {
141void KConfigHeaderGenerator::startHeaderGuards()
143 const bool hasNamespace = !cfg().nameSpace.
isEmpty();
146 const QString defineName = namespaceStr + cfg().className.
toUpper() + QStringLiteral(
"_H");
148 stream() <<
"#ifndef " << defineName <<
'\n';
149 stream() <<
"#define " << defineName <<
'\n';
153void KConfigHeaderGenerator::endHeaderGuards()
156 stream() <<
"#endif";
162void KConfigHeaderGenerator::implementChoiceEnums(
const CfgEntry *entry,
const CfgEntry::Choices &choices)
171 for (
const auto &choice : std::as_const(chlist)) {
172 values.
append(choices.prefix + choice.name);
175 if (choices.name().
isEmpty()) {
176 if (cfg().globalEnums) {
177 stream() << whitespace() <<
"enum " << enumName(entry->name, entry->choices) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
178 if (cfg().generateProperties) {
179 stream() << whitespace() <<
"Q_ENUM(" << enumName(entry->name, entry->choices) <<
")\n";
183 stream() << whitespace() <<
"class " << enumName(entry->name, entry->choices) <<
'\n';
184 stream() << whitespace() <<
"{\n";
185 stream() << whitespace() <<
" public:\n";
186 stream() << whitespace() <<
" enum type { " << values.
join(QStringLiteral(
", ")) <<
", COUNT };\n";
187 stream() << whitespace() <<
"};\n";
189 }
else if (!choices.external()) {
191 stream() << whitespace() <<
"enum " << enumName(entry->name, entry->choices) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
195void KConfigHeaderGenerator::implementValueEnums(
const CfgEntry *entry,
const QStringList &values)
201 if (cfg().globalEnums) {
205 stream() << whitespace() <<
"enum " << enumName(entry->param) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
206 stream() << whitespace() <<
"static const char* const " << enumName(entry->param) <<
"ToString[];\n";
208 stream() << whitespace() <<
"class " << enumName(entry->param) <<
'\n';
209 stream() << whitespace() <<
"{\n";
210 stream() << whitespace() <<
" public:\n";
211 stream() << whitespace() <<
" enum type { " << values.
join(QStringLiteral(
", ")) <<
", COUNT };\n";
212 stream() << whitespace() <<
" static const char* const enumToString[];\n";
213 stream() << whitespace() <<
"};\n";
217void KConfigHeaderGenerator::implementEnums()
219 if (!parseResult.entries.
size()) {
223 for (
const auto *entry : std::as_const(parseResult.entries)) {
224 const CfgEntry::Choices &choices = entry->choices;
227 implementChoiceEnums(entry, choices);
228 implementValueEnums(entry, values);
233void KConfigHeaderGenerator::createSignals()
236 if (parseResult.signalList.
isEmpty()) {
240 stream() <<
"\n enum {\n";
246 for (
int i = 0, end = parseResult.signalList.
size(); i < end; i++) {
247 auto signal = parseResult.signalList.
at(i);
248 stream() << whitespace() <<
" " << signalEnumName(signal.name) <<
" = " << (i + 1);
254 stream() << whitespace() <<
"};\n\n";
256 stream() <<
" Q_SIGNALS:";
257 for (
const Signal &signal : std::as_const(parseResult.signalList)) {
259 if (!signal.label.isEmpty()) {
260 stream() << whitespace() <<
"/**\n";
261 stream() << whitespace() <<
" " << signal.label <<
'\n';
262 stream() << whitespace() <<
"*/\n";
264 stream() << whitespace() <<
"void " << signal.name <<
"(";
266 auto it = signal.arguments.
cbegin();
267 const auto itEnd = signal.arguments.cend();
268 while (it != itEnd) {
269 Param argument = *it;
271 if (cfg().useEnumTypes && argument.type ==
QLatin1String(
"Enum")) {
272 for (
const auto *entry : std::as_const(parseResult.entries)) {
273 if (entry->name == argument.name) {
274 type = enumType(entry, cfg().globalEnums);
279 stream() <<
type <<
" " << argument.name;
288 stream() <<
" private:\n";
289 stream() << whitespace() <<
"void itemChanged(quint64 signalFlag);\n";
293void KConfigHeaderGenerator::createDPointer()
295 if (!cfg().dpointer) {
300 stream() <<
" private:\n";
301 for (
const auto *entry : std::as_const(parseResult.entries)) {
302 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) {
303 stream() << whitespace() <<
"";
304 if (cfg().staticAccessors) {
305 stream() <<
"static ";
307 stream() << cppType(entry->type) <<
" " << getDefaultFunction(entry->name) <<
"_helper(";
309 stream() <<
" " << cppType(entry->paramType) <<
" i ";
311 stream() <<
")" << Const() <<
";\n";
314 stream() << whitespace() <<
"" << cfg().className <<
"Private *d;\n";
317void KConfigHeaderGenerator::createConstructor()
319 if (cfg().singleton) {
320 stream() << whitespace() <<
"static " << cfg().className <<
" *self();\n";
322 if (cfg().qmlRegistration) {
323 stream() << whitespace() <<
"static " << cfg().className <<
" *create(QQmlEngine *, QJSEngine *);\n";
326 if (parseResult.cfgFileNameArg) {
327 stream() << whitespace() <<
"static void instance(const QString& cfgfilename);\n";
328 stream() << whitespace() <<
"static void instance(KSharedConfig::Ptr config);\n";
333 stream() << whitespace() <<
"" << cfg().className <<
"(";
334 if (parseResult.cfgFileNameArg) {
335 if (cfg().forceStringFilename) {
336 stream() <<
" const QString &cfgfilename" << (parseResult.parameters.
isEmpty() ?
" = QString()" :
", ");
337 }
else if (parseResult.cfgStateConfig) {
338 stream() <<
" KSharedConfig::Ptr config" << (parseResult.parameters.
isEmpty() ?
" = KSharedConfig::openStateConfig()" :
", ");
340 stream() <<
" KSharedConfig::Ptr config" << (parseResult.parameters.
isEmpty() ?
" = KSharedConfig::openConfig()" :
", ");
343 if (cfg().forceStringFilename && parseResult.cfgStateConfig) {
344 std::cerr <<
"One can not use ForceStringFilename and use the stateConfig attribute, consider "
345 "removing the ForceStringFilename kcfgc option if you want to use state data"
350 for (
const auto ¶meter : std::as_const(parseResult.parameters)) {
357 stream() <<
" " << param(parameter.type) <<
" " << parameter.name;
360 if (cfg().parentInConstructor) {
361 if (parseResult.cfgFileNameArg || !parseResult.parameters.
isEmpty()) {
364 stream() <<
" QObject *parent = nullptr";
369void KConfigHeaderGenerator::createDestructor()
371 stream() << whitespace() <<
"~" << cfg().className <<
"() override;\n\n";
374void KConfigHeaderGenerator::createForwardDeclarations()
377 if (cfg().dpointer) {
378 stream() <<
"class " << cfg().className <<
"Private;\n\n";
381 if (cfg().qmlRegistration && cfg().singleton) {
382 stream() <<
"class QQmlEngine;\n";
383 stream() <<
"class QJSEngine;\n\n";
387void KConfigHeaderGenerator::createProperties(
const CfgEntry *entry,
const QString &returnType)
389 if (!cfg().generateProperties) {
392 stream() << whitespace() <<
"Q_PROPERTY(" << returnType <<
' ' << getFunction(entry->name);
393 stream() <<
" READ " << getFunction(entry->name);
395 if (cfg().allMutators || cfg().mutators.contains(entry->name)) {
396 const QString signal = changeSignalName(entry->name);
397 stream() <<
" WRITE " << setFunction(entry->name);
398 stream() <<
" NOTIFY " << signal;
405 parseResult.signalList.
append(s);
407 stream() <<
" CONSTANT";
412void KConfigHeaderGenerator::createImmutableProperty(
const CfgEntry *entry)
414 if (!cfg().generateProperties) {
417 stream() << whitespace();
418 stream() <<
"Q_PROPERTY(bool " << immutableFunction(entry->name);
419 stream() <<
" READ " << immutableFunction(entry->name);
420 stream() <<
" CONSTANT)\n";
423void KConfigHeaderGenerator::createSetters(
const CfgEntry *entry)
426 if (!cfg().allMutators && !cfg().mutators.contains(entry->name)) {
430 stream() << whitespace() <<
"/**\n";
431 stream() << whitespace() <<
" Set " << entry->label <<
'\n';
432 stream() << whitespace() <<
"*/\n";
434 if (cfg().staticAccessors) {
435 stream() << whitespace() <<
"static\n";
438 stream() << whitespace() <<
"void " << setFunction(entry->name) <<
"( ";
440 stream() << cppType(entry->paramType) <<
" i, ";
443 stream() << (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum") ? enumType(entry, cfg().globalEnums) : param(entry->
type));
449 if (!cfg().dpointer) {
452 memberMutatorBody(entry);
460void KConfigHeaderGenerator::createGetters(
const CfgEntry *entry,
const QString &returnType)
463 stream() << whitespace() <<
"/**\n";
464 stream() << whitespace() <<
" Get " << entry->label <<
'\n';
465 stream() << whitespace() <<
"*/\n";
466 if (cfg().staticAccessors) {
467 stream() << whitespace() <<
"static\n";
469 stream() << whitespace() <<
"";
470 stream() << returnType;
471 stream() <<
" " << getFunction(entry->name) <<
"(";
473 stream() <<
" " << cppType(entry->paramType) <<
" i ";
475 stream() <<
")" << Const();
479 if (!cfg().dpointer) {
482 stream() << whitespace() << memberAccessorBody(entry, cfg().globalEnums);
490void KConfigHeaderGenerator::createImmutableGetters(
const CfgEntry *entry)
492 stream() << whitespace() <<
"/**\n";
493 stream() << whitespace() <<
" Is " << entry->label <<
" Immutable\n";
494 stream() << whitespace() <<
"*/\n";
496 if (cfg().staticAccessors) {
497 stream() << whitespace() <<
"static\n";
499 stream() << whitespace() <<
"";
500 stream() <<
"bool " << immutableFunction(entry->name) <<
"(";
502 stream() <<
" " << cppType(entry->paramType) <<
" i ";
504 stream() <<
")" << Const();
507 if (!cfg().dpointer) {
510 memberImmutableBody(entry, cfg().globalEnums);
518void KConfigHeaderGenerator::createItemAcessors(
const CfgEntry *entry,
const QString &returnType)
523 if (!cfg().itemAccessors) {
527 const QString declType = entry->signalList.
isEmpty() ? QStringLiteral(
"Item") + itemType(entry->type) : QStringLiteral(
"KConfigCompilerSignallingItem");
529 stream() << whitespace() <<
"/**\n";
530 stream() << whitespace() <<
" Get Item object corresponding to " << entry->name <<
"()" <<
'\n';
531 stream() << whitespace() <<
"*/\n";
532 stream() << whitespace() << declType <<
" *" << getFunction(entry->name) <<
"Item(";
534 stream() <<
" " << cppType(entry->paramType) <<
" i ";
537 if (!cfg().dpointer) {
540 stream() << whitespace() << itemAccessorBody(entry, cfg());
549void KConfigHeaderGenerator::createDefaultValueMember(
const CfgEntry *entry)
552 if (!((cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) && !entry->defaultValue.
isEmpty())) {
555 stream() << whitespace() <<
"/**\n";
556 stream() << whitespace() <<
" Get " << entry->label <<
" default value\n";
557 stream() << whitespace() <<
"*/\n";
558 if (cfg().staticAccessors) {
559 stream() << whitespace() <<
"static\n";
561 stream() << whitespace() <<
"";
562 if (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) {
563 stream() << enumType(entry, cfg().globalEnums);
565 stream() << cppType(entry->type);
567 stream() <<
" " << getDefaultFunction(entry->name) <<
"(";
569 stream() <<
" " << cppType(entry->paramType) <<
" i ";
571 stream() <<
")" << Const() <<
'\n';
572 stream() << whitespace() <<
"{\n";
573 stream() << whitespace() <<
" return ";
574 if (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) {
575 stream() <<
"static_cast<" << enumType(entry, cfg().globalEnums) <<
">(";
577 stream() << getDefaultFunction(entry->name) <<
"_helper(";
582 if (cfg().useEnumTypes && entry->type ==
QLatin1String(
"Enum")) {
586 stream() << whitespace() <<
"}\n";
590void KConfigHeaderGenerator::createSingleton()
593 if (!cfg().singleton) {
597 stream() << whitespace() <<
"" << cfg().className <<
"(";
598 if (parseResult.cfgFileNameArg) {
599 stream() <<
"KSharedConfig::Ptr config";
601 if (cfg().parentInConstructor) {
602 if (parseResult.cfgFileNameArg) {
605 stream() <<
"QObject *parent = nullptr";
608 stream() << whitespace() <<
"friend class " << cfg().className <<
"Helper;\n\n";
611void KConfigHeaderGenerator::createNonDPointerHelpers()
618 for (
const auto *entry : std::as_const(parseResult.entries)) {
619 if (entry->group != group) {
620 group = entry->group;
622 stream() << whitespace() <<
"// " << group <<
'\n';
624 stream() << whitespace() <<
"" << cppType(entry->type) <<
" " << varName(entry->name, cfg());
626 stream() << QStringLiteral(
"[%1]").arg(entry->paramMax + 1);
630 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) {
631 stream() << whitespace() <<
"";
632 if (cfg().staticAccessors) {
633 stream() <<
"static ";
635 stream() << cppType(entry->type) <<
" " << getDefaultFunction(entry->name) <<
"_helper(";
637 stream() <<
" " << cppType(entry->paramType) <<
" i ";
639 stream() <<
")" << Const() <<
";\n";
643 stream() <<
"\n private:\n";
644 if (cfg().itemAccessors) {
645 for (
const auto *entry : std::as_const(parseResult.entries)) {
647 entry->signalList.
isEmpty() ? QStringLiteral(
"Item") + itemType(entry->type) : QStringLiteral(
"KConfigCompilerSignallingItem");
648 stream() << whitespace() << declType <<
" *" << itemVar(entry, cfg());
650 stream() << QStringLiteral(
"[%1]").arg(entry->paramMax + 1);
656 if (parseResult.hasNonModifySignals) {
657 stream() << whitespace() <<
"QSet<quint64> " << varName(QStringLiteral(
"settingsChanged"), cfg()) <<
";\n";
Configuration Compiler Configuration.
Type type(const QSqlDatabase &db)
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