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 if (cfg().qmlUncreatable) {
59 stream() <<
" QML_UNCREATABLE(\"\")\n";
62 stream() <<
" public:\n";
67 for (
const auto *entry : std::as_const(parseResult.entries)) {
68 const QString returnType = (cfg().useEnumTypes && entry->type == QLatin1String(
"Enum")) ? enumType(entry, cfg().globalEnums) : cppType(entry->type);
71 createProperties(entry, returnType);
72 createImmutableProperty(entry);
73 createGetters(entry, returnType);
74 createImmutableGetters(entry);
75 createDefaultValueMember(entry);
76 createItemAcessors(entry, returnType);
80 stream() <<
" protected:\n";
84 if (parseResult.hasNonModifySignals) {
85 stream() << whitespace() <<
"bool usrSave() override;\n";
89 if (!cfg().memberVariables.isEmpty()
90 && cfg().memberVariables != QLatin1String(
"private")
91 && cfg().memberVariables != QLatin1String(
"dpointer")) {
92 stream() <<
" " << cfg().memberVariables <<
":\n";
96 for (
const auto ¶meter : std::as_const(parseResult.parameters)) {
97 stream() << whitespace() <<
"" << cppType(parameter.type) <<
" mParam" << parameter.name <<
";\n";
100 createNonDPointerHelpers();
103 if (cfg().customAddons) {
104 stream() << whitespace() <<
"// Include custom additions\n";
105 stream() << whitespace() <<
"#include \"" << cfg().baseName <<
"_addons." << cfg().headerExtension <<
"\"\n";
108 endScope(ScopeFinalizer::Semicolon);
111void KConfigHeaderGenerator::createHeaders()
113 addHeaders(cfg().headerIncludes);
114 if (cfg().headerIncludes.size()) {
118 if (!cfg().singleton && parseResult.parameters.isEmpty()) {
119 addHeaders({QStringLiteral(
"qglobal.h")});
122 if (cfg().inherits == QLatin1String(
"KCoreConfigSkeleton")) {
123 addHeaders({QStringLiteral(
"kcoreconfigskeleton.h")});
125 addHeaders({QStringLiteral(
"kconfigskeleton.h")});
128 addHeaders({QStringLiteral(
"QCoreApplication"), QStringLiteral(
"QDebug")});
129 if (!cfg().dpointer && parseResult.hasNonModifySignals) {
130 addHeaders({QStringLiteral(
"QSet")});
133 if (cfg().qmlRegistration) {
134 addHeaders({QStringLiteral(
"qqmlintegration.h")});
139 addHeaders(parseResult.includes);
140 if (parseResult.includes.size()) {
145void KConfigHeaderGenerator::startHeaderGuards()
147 const bool hasNamespace = !cfg().nameSpace.isEmpty();
148 const QString namespaceName = QString(QString(cfg().nameSpace).
replace(QLatin1String(
"::"), QLatin1String(
"_"))).toUpper();
149 const QString namespaceStr = hasNamespace ? namespaceName + QLatin1Char(
'_') : QString{};
150 const QString defineName = namespaceStr + cfg().className.
toUpper() + QStringLiteral(
"_H");
152 stream() <<
"#ifndef " << defineName <<
'\n';
153 stream() <<
"#define " << defineName <<
'\n';
157void KConfigHeaderGenerator::endHeaderGuards()
160 stream() <<
"#endif";
166void KConfigHeaderGenerator::implementChoiceEnums(
const CfgEntry *entry,
const CfgEntry::Choices &choices)
168 const QList<CfgEntry::Choice> chlist = choices.choices;
175 for (
const auto &choice : std::as_const(chlist)) {
176 values.
append(choices.prefix + choice.name);
179 if (choices.name().
isEmpty()) {
180 if (cfg().globalEnums) {
181 stream() << whitespace() <<
"enum " << enumName(entry->name, entry->choices) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
182 if (cfg().generateProperties) {
183 stream() << whitespace() <<
"Q_ENUM(" << enumName(entry->name, entry->choices) <<
")\n";
187 stream() << whitespace() <<
"class " << enumName(entry->name, entry->choices) <<
'\n';
188 stream() << whitespace() <<
"{\n";
189 stream() << whitespace() <<
" public:\n";
190 stream() << whitespace() <<
" enum type { " << values.
join(QStringLiteral(
", ")) <<
", COUNT };\n";
191 stream() << whitespace() <<
"};\n";
193 }
else if (!choices.external()) {
195 stream() << whitespace() <<
"enum " << enumName(entry->name, entry->choices) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
196 if (cfg().generateProperties) {
197 stream() << whitespace() <<
"Q_ENUM(" << enumName(entry->name, entry->choices) <<
")\n";
202void KConfigHeaderGenerator::implementValueEnums(
const CfgEntry *entry,
const QStringList &values)
208 if (cfg().globalEnums) {
212 stream() << whitespace() <<
"enum " << enumName(entry->param) <<
" { " << values.
join(QStringLiteral(
", ")) <<
" };\n";
213 stream() << whitespace() <<
"static const char* const " << enumName(entry->param) <<
"ToString[];\n";
215 stream() << whitespace() <<
"class " << enumName(entry->param) <<
'\n';
216 stream() << whitespace() <<
"{\n";
217 stream() << whitespace() <<
" public:\n";
218 stream() << whitespace() <<
" enum type { " << values.
join(QStringLiteral(
", ")) <<
", COUNT };\n";
219 stream() << whitespace() <<
" static const char* const enumToString[];\n";
220 stream() << whitespace() <<
"};\n";
224void KConfigHeaderGenerator::implementEnums()
226 if (!parseResult.entries.size()) {
230 for (
const auto *entry : std::as_const(parseResult.entries)) {
231 const CfgEntry::Choices &choices = entry->choices;
232 const QStringList values = entry->paramValues;
234 implementChoiceEnums(entry, choices);
235 implementValueEnums(entry, values);
240void KConfigHeaderGenerator::createSignals()
243 if (parseResult.signalList.isEmpty()) {
247 stream() <<
"\n enum {\n";
253 for (
int i = 0, end = parseResult.signalList.size(); i < end; i++) {
254 auto signal = parseResult.signalList.at(i);
255 stream() << whitespace() <<
" " << signalEnumName(signal.name) <<
" = " << (i + 1);
261 stream() << whitespace() <<
"};\n\n";
263 stream() <<
" Q_SIGNALS:";
264 for (
const Signal &signal : std::as_const(parseResult.signalList)) {
266 if (!signal.label.isEmpty()) {
267 stream() << whitespace() <<
"/**\n";
268 stream() << whitespace() <<
" " << signal.label <<
'\n';
269 stream() << whitespace() <<
"*/\n";
271 stream() << whitespace() <<
"void " << signal.name <<
"(";
273 auto it = signal.arguments.cbegin();
274 const auto itEnd = signal.arguments.cend();
275 while (it != itEnd) {
276 Param argument = *it;
277 QString
type = param(argument.type);
278 if (cfg().useEnumTypes && argument.type == QLatin1String(
"Enum")) {
279 for (
const auto *entry : std::as_const(parseResult.entries)) {
280 if (entry->name == argument.name) {
281 type = enumType(entry, cfg().globalEnums);
286 stream() <<
type <<
" " << argument.name;
295 stream() <<
" private:\n";
296 stream() << whitespace() <<
"void itemChanged(quint64 signalFlag);\n";
300void KConfigHeaderGenerator::createDPointer()
302 if (!cfg().dpointer) {
307 stream() <<
" private:\n";
308 for (
const auto *entry : std::as_const(parseResult.entries)) {
309 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) {
310 stream() << whitespace() <<
"";
311 if (cfg().staticAccessors) {
312 stream() <<
"static ";
314 stream() << cppType(entry->type) <<
" " << getDefaultFunction(entry->name) <<
"_helper(";
316 stream() <<
" " << cppType(entry->paramType) <<
" i ";
318 stream() <<
")" << Const() <<
";\n";
321 stream() << whitespace() <<
"" << cfg().className <<
"Private *d;\n";
324void KConfigHeaderGenerator::createConstructor()
326 if (cfg().singleton) {
327 stream() << whitespace() <<
"static " << cfg().className <<
" *self();\n";
329 if (cfg().qmlRegistration) {
330 stream() << whitespace() <<
"static " << cfg().className <<
" *create(QQmlEngine *, QJSEngine *);\n";
333 if (parseResult.cfgFileNameArg) {
334 stream() << whitespace() <<
"static void instance(const QString& cfgfilename);\n";
335 stream() << whitespace() <<
"static void instance(KSharedConfig::Ptr config);\n";
340 stream() << whitespace() <<
"" << cfg().className <<
"(";
341 if (parseResult.cfgFileNameArg) {
342 if (cfg().forceStringFilename) {
343 stream() <<
" const QString &cfgfilename" << (parseResult.parameters.isEmpty() ?
" = QString()" :
", ");
344 }
else if (parseResult.cfgStateConfig) {
345 stream() <<
" KSharedConfig::Ptr config" << (parseResult.parameters.isEmpty() ?
" = KSharedConfig::openStateConfig()" :
", ");
347 stream() <<
" KSharedConfig::Ptr config" << (parseResult.parameters.isEmpty() ?
" = KSharedConfig::openConfig()" :
", ");
350 if (cfg().forceStringFilename && parseResult.cfgStateConfig) {
351 std::cerr <<
"One can not use ForceStringFilename and use the stateConfig attribute, consider "
352 "removing the ForceStringFilename kcfgc option if you want to use state data"
357 for (
const auto ¶meter : std::as_const(parseResult.parameters)) {
364 stream() <<
" " << param(parameter.type) <<
" " << parameter.name;
367 if (cfg().parentInConstructor) {
368 if (parseResult.cfgFileNameArg || !parseResult.parameters.isEmpty()) {
371 stream() <<
" QObject *parent = nullptr";
376void KConfigHeaderGenerator::createDestructor()
378 stream() << whitespace() <<
"~" << cfg().className <<
"() override;\n\n";
381void KConfigHeaderGenerator::createForwardDeclarations()
384 if (cfg().dpointer) {
385 stream() <<
"class " << cfg().className <<
"Private;\n\n";
388 if (cfg().qmlRegistration && cfg().singleton) {
389 stream() <<
"class QQmlEngine;\n";
390 stream() <<
"class QJSEngine;\n\n";
394void KConfigHeaderGenerator::createProperties(
const CfgEntry *entry,
const QString &returnType)
396 if (!cfg().generateProperties) {
399 stream() << whitespace() <<
"Q_PROPERTY(" << returnType <<
' ' << getFunction(entry->name);
400 stream() <<
" READ " << getFunction(entry->name);
402 if (cfg().allMutators || cfg().mutators.contains(entry->name)) {
403 const QString signal = changeSignalName(entry->name);
404 stream() <<
" WRITE " << setFunction(entry->name);
405 stream() <<
" NOTIFY " << signal;
412 parseResult.signalList.append(s);
414 stream() <<
" CONSTANT";
419void KConfigHeaderGenerator::createImmutableProperty(
const CfgEntry *entry)
421 if (!cfg().generateProperties) {
424 stream() << whitespace();
425 stream() <<
"Q_PROPERTY(bool " << immutableFunction(entry->name);
426 stream() <<
" READ " << immutableFunction(entry->name);
427 stream() <<
" CONSTANT)\n";
430void KConfigHeaderGenerator::createSetters(
const CfgEntry *entry)
433 if (!cfg().allMutators && !cfg().mutators.contains(entry->name)) {
437 stream() << whitespace() <<
"/**\n";
438 stream() << whitespace() <<
" Set " << entry->label <<
'\n';
439 stream() << whitespace() <<
"*/\n";
441 if (cfg().staticAccessors) {
442 stream() << whitespace() <<
"static\n";
445 stream() << whitespace() <<
"void " << setFunction(entry->name) <<
"( ";
447 stream() << cppType(entry->paramType) <<
" i, ";
450 stream() << (cfg().useEnumTypes && entry->type == QLatin1String(
"Enum") ? enumType(entry, cfg().globalEnums) : param(entry->
type));
456 if (!cfg().dpointer) {
459 memberMutatorBody(entry);
467void KConfigHeaderGenerator::createGetters(
const CfgEntry *entry,
const QString &returnType)
470 stream() << whitespace() <<
"/**\n";
471 stream() << whitespace() <<
" Get " << entry->label <<
'\n';
472 stream() << whitespace() <<
"*/\n";
473 if (cfg().staticAccessors) {
474 stream() << whitespace() <<
"static\n";
476 stream() << whitespace() <<
"";
477 stream() << returnType;
478 stream() <<
" " << getFunction(entry->name) <<
"(";
480 stream() <<
" " << cppType(entry->paramType) <<
" i ";
482 stream() <<
")" << Const();
486 if (!cfg().dpointer) {
489 stream() << whitespace() << memberAccessorBody(entry, cfg().globalEnums);
497void KConfigHeaderGenerator::createImmutableGetters(
const CfgEntry *entry)
499 stream() << whitespace() <<
"/**\n";
500 stream() << whitespace() <<
" Is " << entry->label <<
" Immutable\n";
501 stream() << whitespace() <<
"*/\n";
503 if (cfg().staticAccessors) {
504 stream() << whitespace() <<
"static\n";
506 stream() << whitespace() <<
"";
507 stream() <<
"bool " << immutableFunction(entry->name) <<
"(";
509 stream() <<
" " << cppType(entry->paramType) <<
" i ";
511 stream() <<
")" << Const();
514 if (!cfg().dpointer) {
517 memberImmutableBody(entry, cfg().globalEnums);
525void KConfigHeaderGenerator::createItemAcessors(
const CfgEntry *entry,
const QString &returnType)
530 if (!cfg().itemAccessors) {
534 const QString declType = entry->signalList.
isEmpty() ? QStringLiteral(
"Item") + itemType(entry->type) : QStringLiteral(
"KConfigCompilerSignallingItem");
536 stream() << whitespace() <<
"/**\n";
537 stream() << whitespace() <<
" Get Item object corresponding to " << entry->name <<
"()" <<
'\n';
538 stream() << whitespace() <<
"*/\n";
539 stream() << whitespace() << declType <<
" *" << getFunction(entry->name) <<
"Item(";
541 stream() <<
" " << cppType(entry->paramType) <<
" i ";
544 if (!cfg().dpointer) {
547 stream() << whitespace() << itemAccessorBody(entry, cfg());
556void KConfigHeaderGenerator::createDefaultValueMember(
const CfgEntry *entry)
559 if (!((cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) && !entry->defaultValue.
isEmpty())) {
562 stream() << whitespace() <<
"/**\n";
563 stream() << whitespace() <<
" Get " << entry->label <<
" default value\n";
564 stream() << whitespace() <<
"*/\n";
565 if (cfg().staticAccessors) {
566 stream() << whitespace() <<
"static\n";
568 stream() << whitespace() <<
"";
569 if (cfg().useEnumTypes && entry->type == QLatin1String(
"Enum")) {
570 stream() << enumType(entry, cfg().globalEnums);
572 stream() << cppType(entry->type);
574 stream() <<
" " << getDefaultFunction(entry->name) <<
"(";
576 stream() <<
" " << cppType(entry->paramType) <<
" i ";
578 stream() <<
")" << Const() <<
'\n';
579 stream() << whitespace() <<
"{\n";
580 stream() << whitespace() <<
" return ";
581 if (cfg().useEnumTypes && entry->type == QLatin1String(
"Enum")) {
582 stream() <<
"static_cast<" << enumType(entry, cfg().globalEnums) <<
">(";
584 stream() << getDefaultFunction(entry->name) <<
"_helper(";
589 if (cfg().useEnumTypes && entry->type == QLatin1String(
"Enum")) {
593 stream() << whitespace() <<
"}\n";
597void KConfigHeaderGenerator::createSingleton()
600 if (!cfg().singleton) {
604 stream() << whitespace() <<
"" << cfg().className <<
"(";
605 if (parseResult.cfgFileNameArg) {
606 stream() <<
"KSharedConfig::Ptr config";
608 if (cfg().parentInConstructor) {
609 if (parseResult.cfgFileNameArg) {
612 stream() <<
"QObject *parent = nullptr";
615 stream() << whitespace() <<
"friend class " << cfg().className <<
"Helper;\n\n";
618void KConfigHeaderGenerator::createNonDPointerHelpers()
620 if (cfg().memberVariables == QLatin1String(
"dpointer")) {
625 for (
const auto *entry : std::as_const(parseResult.entries)) {
626 if (entry->group != group) {
627 group = entry->group;
629 stream() << whitespace() <<
"// " << group <<
'\n';
631 stream() << whitespace() <<
"" << cppType(entry->type) <<
" " << varName(entry->name, cfg());
633 stream() << QStringLiteral(
"[%1]").arg(entry->paramMax + 1);
637 if (cfg().allDefaultGetters || cfg().defaultGetters.contains(entry->name)) {
638 stream() << whitespace() <<
"";
639 if (cfg().staticAccessors) {
640 stream() <<
"static ";
642 stream() << cppType(entry->type) <<
" " << getDefaultFunction(entry->name) <<
"_helper(";
644 stream() <<
" " << cppType(entry->paramType) <<
" i ";
646 stream() <<
")" << Const() <<
";\n";
650 stream() <<
"\n private:\n";
651 if (cfg().itemAccessors) {
652 for (
const auto *entry : std::as_const(parseResult.entries)) {
653 const QString declType =
654 entry->signalList.
isEmpty() ? QStringLiteral(
"Item") + itemType(entry->type) : QStringLiteral(
"KConfigCompilerSignallingItem");
655 stream() << whitespace() << declType <<
" *" << itemVar(entry, cfg());
657 stream() << QStringLiteral(
"[%1]").arg(entry->paramMax + 1);
663 if (parseResult.hasNonModifySignals) {
664 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)
bool isEmpty() const const
bool isEmpty() const const
QString toUpper() const const
QString join(QChar separator) const const