PhoenixGenerator  3.4.0
Generate code from template files and projects in C++, Rust, Python and wrapped C++ to Python
Loading...
Searching...
No Matches
generator_class_cpp.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : LGPL-3.0-only
5****************************************/
6
7#include <sstream>
8#include "phoenix_color.h"
9#include "openFileStream.h"
10#include "header_generator.h"
11#include "cmakelist_generator.h"
12#include "type_utils.h"
13#include "generator_class_cpp.h"
14
16
19bool class_hasPointerAttribute(const PClassConfig & classConfig){
20 const std::vector<PClassAttribute> & listAttr(classConfig.getListAttribute());
21 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
22 if(getIsPointerType(it->getType())){return true;}
23 }
24 return false;
25}
26
28
31PString class_getClassDefTemplate(const PVecString & listTemplate){
32 if(listTemplate.size() == 0LU){return "";}
33 PString defTemplate("<"), comma("");
34 for(PVecString::const_iterator it(listTemplate.begin()); it != listTemplate.end(); ++it){
35 PVecString vecPart = it->split(' ');
36 if(vecPart.size() != 0LU){
37 defTemplate += comma + vecPart.back();
38 comma = ", ";
39 }
40 }
41 defTemplate += ">";
42 return defTemplate;
43}
44
46
49PString class_getClassDeclTempalteDef(const PVecString & listTemplate){
50 if(listTemplate.size() == 0LU){return "";}
51 PString templateDef("template<");
52 PString comma("");
53 for(PVecString::const_iterator it(listTemplate.begin()); it != listTemplate.end(); ++it){
54 templateDef += comma;
55 templateDef += *it;
56 comma = ", ";
57 }
58 templateDef += ">\n";
59 return templateDef;
60}
61
63
67 if(attr.getDefaultValue() != ""){return attr.getDefaultValue();}
68 PString varType(attr.getType());
69 if(getIsPointerType(varType)){return "{NULL}";} //raw pointer : not implicitly null-initialised, needs an explicit NSDMI
70 PString defaultValue(getDefaultValueTypeInCpp(varType));
71 if(defaultValue != ""){return "{" + defaultValue + "}";}
72 return "";
73}
74
76
79bool generator_checkDefaultValueExist(const std::vector<PClassAttribute> & vecAttr){
80 bool hasDefaultValue = false;
81 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end() && !hasDefaultValue; ++it){
82 hasDefaultValue |= it->getDefaultValue() != "";
83 }
84 return hasDefaultValue;
85}
86
88
96void class_savePointerOwnershipSpecialMembersImpl(std::ofstream & fs, const PClassConfig & classConfig, const PString & defTemplate, const PString & templateDeclaration){
97 if(!class_hasPointerAttribute(classConfig)){return;}
98 PString name(classConfig.getName());
99 const std::vector<PClassAttribute> & listAttr(classConfig.getListAttribute());
100
102 fs << "///Destructor of class " << name << std::endl;
103 fs << templateDeclaration;
104 fs << name << defTemplate << "::~" << name << "(){" << std::endl;
105 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
106 if(getIsPointerType(it->getType())){
107 fs << "\tdelete p_" << it->getName() << ";" << std::endl;
108 }
109 }
110 fs << "}" << std::endl << std::endl;
111
113 fs << "///Copy constructor of class " << name << std::endl;
114 fs << "/**\t@param other : " << name << " we want to copy" << std::endl;
115 fs << "*/" << std::endl;
116 fs << templateDeclaration;
117 fs << name << defTemplate << "::" << name << "(const " << name << defTemplate << " & other)";
118 PString initListComma(" : ");
119 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
120 if(getIsPointerType(it->getType())){
121 fs << initListComma << "p_" << it->getName() << "(NULL)";
122 initListComma = ", ";
123 }
124 }
125 fs << "{" << std::endl;
126 fs << "\tcopy" << name << "(other);" << std::endl;
127 fs << "}" << std::endl << std::endl;
128
130 fs << "///Copy assignment operator of class " << name << std::endl;
131 fs << "/**\t@param other : " << name << " we want to copy" << std::endl;
132 fs << " * \t@return copied class " << name << std::endl;
133 fs << "*/" << std::endl;
134 fs << templateDeclaration;
135 fs << name << defTemplate << " & " << name << defTemplate << "::operator = (const " << name << defTemplate << " & other){" << std::endl;
136 fs << "\tcopy" << name << "(other);" << std::endl;
137 fs << "\treturn *this;" << std::endl;
138 fs << "}" << std::endl << std::endl;
139
141 fs << "///Copy the attributes of class " << name << std::endl;
142 fs << "/**\t@param other : " << name << " we want to copy" << std::endl;
143 fs << "*/" << std::endl;
144 fs << templateDeclaration;
145 fs << "void " << name << defTemplate << "::copy" << name << "(const " << name << defTemplate << " & other){" << std::endl;
146 fs << "\tif(this == &other){return;}" << std::endl;
147 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
148 if(getIsPointerType(it->getType())){
149 PString pointeeType(it->getType().eraseFirstLastChar(" \n\t*"));
150 fs << "\tdelete p_" << it->getName() << ";" << std::endl;
151 fs << "\tp_" << it->getName() << " = other.p_" << it->getName() << " ? new " << pointeeType << "(*other.p_" << it->getName() << ") : NULL;" << std::endl;
152 }else{
153 fs << "\tp_" << it->getName() << " = other.p_" << it->getName() << ";" << std::endl;
154 }
155 }
156 fs << "}" << std::endl << std::endl;
157
159 fs << "///Move constructor of class " << name << std::endl;
160 fs << "/**\t@param other : " << name << " we want to move" << std::endl;
161 fs << "*/" << std::endl;
162 fs << templateDeclaration;
163 fs << name << defTemplate << "::" << name << "(" << name << defTemplate << " && other) noexcept";
164 initListComma = " : ";
165 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
166 if(getIsPointerType(it->getType())){
167 fs << initListComma << "p_" << it->getName() << "(NULL)";
168 initListComma = ", ";
169 }
170 }
171 fs << "{" << std::endl;
172 fs << "\tmove" << name << "(std::move(other));" << std::endl;
173 fs << "}" << std::endl << std::endl;
174
176 fs << "///Move assignment operator of class " << name << std::endl;
177 fs << "/**\t@param other : " << name << " we want to move" << std::endl;
178 fs << " * \t@return moved class " << name << std::endl;
179 fs << "*/" << std::endl;
180 fs << templateDeclaration;
181 fs << name << defTemplate << " & " << name << defTemplate << "::operator = (" << name << defTemplate << " && other) noexcept{" << std::endl;
182 fs << "\tmove" << name << "(std::move(other));" << std::endl;
183 fs << "\treturn *this;" << std::endl;
184 fs << "}" << std::endl << std::endl;
185
187 fs << "///Move the attributes of class " << name << std::endl;
188 fs << "/**\t@param other : " << name << " we want to move" << std::endl;
189 fs << "*/" << std::endl;
190 fs << templateDeclaration;
191 fs << "void " << name << defTemplate << "::move" << name << "(" << name << defTemplate << " && other){" << std::endl;
192 fs << "\tif(this == &other){return;}" << std::endl;
193 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
194 if(getIsPointerType(it->getType())){
195 fs << "\tdelete p_" << it->getName() << ";" << std::endl;
196 fs << "\tp_" << it->getName() << " = other.p_" << it->getName() << ";" << std::endl;
197 fs << "\tother.p_" << it->getName() << " = NULL;" << std::endl;
198 }else{
199 fs << "\tp_" << it->getName() << " = std::move(other.p_" << it->getName() << ");" << std::endl;
200 }
201 }
202 fs << "}" << std::endl << std::endl;
203}
204
206
211void generator_enum_cpp_header(const PTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
212 if(classConfig.getClassDocumentation() != "") fs << classConfig.getClassDocumentation() << std::endl;
213 PString name(classConfig.getName());
214 fs << "namespace " << name << " {\n";
215 if(classConfig.getClassDocumentation() != ""){fs << "\t"<< classConfig.getClassDocumentation() << std::endl;}
216 fs << "\tenum " << name << " {\n\t\t";
217 const std::vector<PClassAttribute> & vecAttr(classConfig.getListAttribute());
218 bool isDefaultCounterActivated = !generator_checkDefaultValueExist(vecAttr);
219 PString comma("");
220 size_t i(0LU);
221 for(std::vector<PClassAttribute>::const_iterator it(vecAttr.begin()); it != vecAttr.end(); ++it){
222 if(it->getDocumentation() != "") fs << "\t\t" << it->getDocumentation() << std::endl;
223 fs << comma << it->getName();
224 if(isDefaultCounterActivated){
225 fs << " = " << i;
226 }else if(it->getDefaultValue() != ""){
227 fs << " = " << it->getDefaultValue();
228 }
229 comma = ",\n\t\t";
230 ++i;
231 }
232 fs << "\n\t};" << std::endl;
233 fs << "}" << std::endl << std::endl;
234 manager.classExtraFunctionDeclaration(fs, classConfig, mode);
235 fs << std::endl << std::endl;
236}
237
238
240
245void generator_class_cpp_header(const PTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
246 if(classConfig.getClassDocumentation() != "") fs << classConfig.getClassDocumentation() << std::endl;
247 PString name(classConfig.getName());
248 PString namespaceName(classConfig.getNamespace());
249 GeneratorMode classMode(mode);
250 const PVecString & listTemplate = classConfig.getListTemplate();
251 PString defTemplate(class_getClassDefTemplate(listTemplate));
252 PString templateDeclaration(class_getClassDeclTempalteDef(listTemplate));
253 classMode.defTemplate = defTemplate;
254 classMode.templateDeclaration = templateDeclaration;
255
256 fs << classMode.templateDeclaration;
257 fs << "class ";
258 if(namespaceName != ""){
259 fs << namespaceName << "::";
260 }
261 fs << name;
262 if(classConfig.getListParentClass().size() != 0LU){
263 PVecString::const_iterator it(classConfig.getListParentClass().begin());
264 fs << " : public " << *it;
265 if(classConfig.getListParentClass().size() > 1lu){
266 while(it != classConfig.getListParentClass().end()){
267 fs << ", " << *it;
268 ++it;
269 }
270 }
271 }
272 bool hasPointerAttribute(class_hasPointerAttribute(classConfig));
273 fs << "{" << std::endl;
274 fs << "\tpublic:" << std::endl;
275 fs << "\t\t" << name << "() = default;" << std::endl;
276 if(hasPointerAttribute){
277 //A raw pointer attribute cannot be safely copied/moved by the compiler-generated special members (shallow copy/move would double-delete) :
278 //DataStream has no shared_ptr/unique_ptr specialisation, so ownership is a raw pointer and all five special members must be hand-written (rule of five).
279 fs << "\t\tvirtual ~" << name << "();" << std::endl;
280 fs << "\t\t" << name << "(const " << name << " &);" << std::endl;
281 fs << "\t\t" << name << " & operator = (const " << name << " &);" << std::endl;
282 fs << "\t\t" << name << "(" << name << " &&) noexcept;" << std::endl;
283 fs << "\t\t" << name << " & operator = (" << name << " &&) noexcept;" << std::endl;
284 }else{
285 fs << "\t\tvirtual ~" << name << "() = default;" << std::endl;
286 //A user-declared destructor suppresses the implicitly-declared copy/move constructor and assignment : redeclare all four as defaulted.
287 fs << "\t\t" << name << "(const " << name << " &) = default;" << std::endl;
288 fs << "\t\t" << name << " & operator = (const " << name << " &) = default;" << std::endl;
289 fs << "\t\t" << name << "(" << name << " &&) = default;" << std::endl;
290 fs << "\t\t" << name << " & operator = (" << name << " &&) = default;" << std::endl;
291 }
292
293 manager.publicMethodDeclaration(fs, classConfig, classMode);
294
295 //Trait backends write to an std::ofstream& : capture their output into a string buffer first (via a buffer swap, no actual file involved)
296 //so the "protected:" label is only emitted when there is something to put under it, instead of leaving an empty access-specifier section.
297 std::ostringstream protectedContentBuf;
298 std::ofstream protectedCapture;
299 //basic_ofstream declares its own 0-arg rdbuf() (returning the internal filebuf), which hides the inherited basic_ios::rdbuf(streambuf*) setter :
300 //go through the std::ostream base to reach the setter and redirect writes into a string buffer without opening any file.
301 static_cast<std::ostream &>(protectedCapture).rdbuf(protectedContentBuf.rdbuf());
302 manager.protectedMethodDeclaration(protectedCapture, classConfig, classMode);
303 PString protectedContent(protectedContentBuf.str());
304 if(hasPointerAttribute || protectedContent != ""){
305 fs << "\tprotected:" << std::endl;
306 if(hasPointerAttribute){
307 fs << "\t\tvoid copy" << name << "(const " << name << " & other);" << std::endl;
308 fs << "\t\tvoid move" << name << "(" << name << " && other);" << std::endl;
309 }
310 fs << protectedContent;
311 }
312
313 fs << "\tprivate:" << std::endl;
314 manager.privateMethodDeclaration(fs, classConfig, classMode);
315 const std::vector<PClassAttribute> & listAttr(classConfig.getListAttribute());
316 for(std::vector<PClassAttribute>::const_iterator it(listAttr.begin()); it != listAttr.end(); ++it){
317 if(it->getDocumentation() != "") fs << "\t\t" << it->getDocumentation() << std::endl;
318 PString defaultInit(class_getAttributeDefaultInit(*it));
319 fs << "\t\t" << it->getType() << " p_" << it->getName() << defaultInit << ";" << std::endl;
320 }
321 fs << "};" << std::endl << std::endl;
322 manager.classExtraFunctionDeclaration(fs, classConfig, classMode);
323 fs << std::endl << std::endl;
324}
325
327
335bool generator_class_cpp_headerFile(const PTraitBackendManager & manager, const PPath & headerFile, const std::vector<PClassConfig> & vecClassConfig, const GeneratorMode & mode,
336 const PVecPath & vecInclude, const PString & includeTemplate)
337{
338 if(headerFile == "") return false;
339 std::ofstream fs;
340 if(!openFileStream(fs, headerFile)){return false;}
341 licenceSave(fs);
342 PString macroDef(makeMultiIncludeDefineMacro(headerFile.getFileName()));
343 fs << "#ifndef " << macroDef << std::endl;
344 fs << "#define " << macroDef << std::endl << std::endl;
345 fs << "#include <string>" << std::endl;
346 if(vecInclude.size() != 0LU){
347 for(PVecPath::const_iterator it(vecInclude.begin()); it != vecInclude.end(); ++it){
348 fs << "#include " << *it << std::endl;
349 }
350 fs << std::endl;
351 }
352 manager.headerExtraInclude(fs, mode);
353 fs << std::endl;
354 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
355 if(it->getIsEnum()){
356 generator_enum_cpp_header(manager, fs, *it, mode);
357// saveEnumDecl(fs, *it, mode);
358 }else{
359 generator_class_cpp_header(manager, fs, *it, mode);
360 }
361 }
362
363 if(includeTemplate != ""){
364 fs << "#include \""<<includeTemplate<<"\"" << std::endl << std::endl;
365 }
366
367 fs << std::endl << std::endl << "#endif" << std::endl << std::endl;
368 fs.close();
369 return true;
370}
371
373
378void generator_class_cpp_source(const PTraitBackendManager & manager, std::ofstream & fs, const PClassConfig & classConfig, const GeneratorMode & mode){
379 manager.classExtraFunctionImplementation(fs, classConfig, mode);
380 GeneratorMode classMode(mode);
381 const PVecString & listTemplate = classConfig.getListTemplate();
382 PString defTemplate(class_getClassDefTemplate(listTemplate));
383 PString templateDeclaration(class_getClassDeclTempalteDef(listTemplate));
384 classMode.defTemplate = defTemplate;
385 classMode.templateDeclaration = templateDeclaration;
386 if(!classConfig.getIsEnum()){
387 class_savePointerOwnershipSpecialMembersImpl(fs, classConfig, defTemplate, templateDeclaration);
388 }
389 manager.publicMethodImplementation(fs, classConfig, classMode);
390 manager.protectedMethodImplementation(fs, classConfig, classMode);
391 manager.privateMethodImplementation(fs, classConfig, classMode);
392}
393
395
403bool generator_class_cpp_sourceFile(const PTraitBackendManager & manager, const PPath & sourceFile, const PPath & headerFile,
404 const std::vector<PClassConfig> & vecClassConfig, const GeneratorMode & mode, bool isTemplateImpl)
405{
406 if(sourceFile == "" || headerFile == "") return false;
407 std::ofstream fs;
408 if(!openFileStream(fs, sourceFile)){return false;}
409 licenceSave(fs);
410 if(isTemplateImpl){
411 PString macroDef(makeMultiIncludeDefineMacro(headerFile.getFileName() + "_IMPL"));
412 fs << "#ifndef " << macroDef << std::endl;
413 fs << "#define " << macroDef << std::endl << std::endl;
414 }
415 fs << std::endl << "#include \"" << headerFile.getFileName() << "\"" << std::endl;
416 bool hasPointerAttribute(false);
417 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end() && !hasPointerAttribute; ++it){
418 hasPointerAttribute = class_hasPointerAttribute(*it);
419 }
420 if(hasPointerAttribute){
421 fs << "#include <utility>" << std::endl; //std::move used by the hand-written move constructor/assignment
422 }
423 fs << std::endl;
424 bool hasNamespace(false);
425 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
426 if(it->getNamespace() != "" && !hasNamespace){
427 fs << "using namespace " << it->getNamespace() << ";" << std::endl << std::endl;
428 hasNamespace = true;
429 }
430 }
431 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
432 generator_class_cpp_source(manager, fs, *it, mode);
433 }
434 if(isTemplateImpl){
435 fs << "#endif" << std::endl << std::endl;
436 }
437 fs.close();
438
439 return true;
440}
441
442
443
445
449void class_checkClassConfig(bool & hasSource, bool & hasTemplate, const std::vector<PClassConfig> & vecClassConfig){
450 hasSource = false;
451 hasTemplate = false;
452 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
453 bool isTemplate = it->getListTemplate().size() != 0LU;
454 hasSource |= !isTemplate;
455 hasTemplate |= isTemplate;
456 }
457}
458
460
467bool generator_class_cpp(const PTraitBackendManager & manager, const std::vector<PClassConfig> & vecClassConfig, const PPath & outputSourceDir, const PPath & baseFileName, const GeneratorMode & mode, const PVecPath & vecInclude){
468 if(baseFileName == ""){
469 std::cerr << termRed() << "generator_class_cpp : baseFileName is empty" << termDefault() << std::endl;
470 return false;
471 }
472 bool hasSource(false), hasTemplate(false);
473 class_checkClassConfig(hasSource, hasTemplate, vecClassConfig);
474 PString includeTemplate("");
475 if(hasTemplate){
476 includeTemplate = PString(baseFileName.getFileName() + "_impl.h");
477 }
478 PPath headerFile = outputSourceDir / PPath(baseFileName + ".h");
479 if(!generator_class_cpp_headerFile(manager, headerFile, vecClassConfig, mode, vecInclude, includeTemplate)){
480 std::cerr << termRed() << "generator_class_cpp : cannot generate header file '"<<headerFile<<"'" << termDefault() << std::endl;
481 return false;
482 }
483 if(hasSource){
484 PPath sourceFile = outputSourceDir / PPath(baseFileName + PString(".cpp"));
485 if(!generator_class_cpp_sourceFile(manager, sourceFile, PPath(baseFileName + PString(".h")), vecClassConfig, mode, false)){
486 std::cerr << termRed() << "generator_class_cpp : cannot generate source file '"<<sourceFile<<"'" << termDefault() << std::endl;
487 return false;
488 }
489 }
490 if(hasTemplate){
491 PPath implFile = outputSourceDir / PPath(baseFileName + PString("_impl.h"));
492 if(!generator_class_cpp_sourceFile(manager, implFile, PPath(baseFileName + PString(".h")), vecClassConfig, mode, true)){
493 std::cerr << termRed() << "generator_class_cpp : cannot generate impl file '"<<implFile<<"'" << termDefault() << std::endl;
494 return false;
495 }
496 }
497 return true;
498}
499
500
502
509bool generator_class_testMain(const PTraitBackendManager & manager, const PPath & outputCurrentTestDir, const PClassConfig & classConfig, const PPath & baseFileName, const GeneratorMode & mode){
510 std::ofstream fs;
511 if(!openFileStream(fs, PPath(outputCurrentTestDir + PString("/main.cpp")))){return false;}
512 licenceSave(fs);
513// body += licenceSaveStr() + "\n";
514 if(mode.assertInclude != ""){
515 fs << "#include \"" + mode.assertInclude + "\"\n\n";
516 }
517 fs << "#include \"" + baseFileName + ".h\"\n\n";
518 if(classConfig.getNamespace() != ""){fs << "using namespace " << classConfig.getNamespace() << ";\n\n";}
519 manager.testFunction(fs, classConfig, mode);
520 fs << "int main(int argc, char ** argv){\n";
521 //Do other test if the enableDataStream is true
522 manager.testCallFunction(fs, classConfig, mode);
523 fs << "\treturn 0;\n";
524 fs << "}\n";
525 fs.close();
526 return true;
527}
528
530
536bool generator_class_testCMakeLists( const PPath & outputCurrentTestDir, const PClassConfig & classConfig, const PString & projectName, const GeneratorMode & mode){
537 PString body(""), testName("test_class_" + classConfig.getName().toLowerUnderscore());
538 body += getCMakeListsHeader();
539 body += "add_executable("+testName+" main.cpp)\n";
540 body += "target_link_libraries("+testName+" ${"+projectName.toUpper()+"_TEST_DEPENDENCIES})\n";
541 body += "\n";
542 body += "add_test(NAME "+testName.firstToUpper()+"\n";
543 body += "\tCOMMAND ${CMAKE_CURRENT_BINARY_DIR}/"+testName+"\n";
544 body += "\tWORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}\n";
545 body += ")\n\n\n";
546 return PPath(outputCurrentTestDir + PString("/CMakeLists.txt")).saveFileContent(body);
547}
548
550
558bool generator_class_test(const PTraitBackendManager & manager, const PPath & outputTestDir, const PClassConfig & classConfig, const PString & projectName, const PPath & baseFileName, const GeneratorMode & mode){
559 PString name(classConfig.getName());
560 PPath outputCurrentTestDir(outputTestDir + PString("/TEST_") + name.toUpper());
561 if(!outputCurrentTestDir.createDirectory()){std::cerr << "generator_class_test : cannot create TEST directory '"<<outputCurrentTestDir<<"'" << std::endl;return false;}
562
563 bool b(true);
564 b &= generator_class_testCMakeLists(outputCurrentTestDir, classConfig, projectName, mode);
565 b &= generator_class_testMain(manager, outputCurrentTestDir, classConfig, baseFileName, mode);
566 return b;
567}
568
570
578bool generator_class_cpp_test(const PTraitBackendManager & manager, const PPath & outputTestDir, const std::vector<PClassConfig> & vecClassConfig, const PString & projectName, const PPath & baseFileName, const GeneratorMode & mode){
579 PString cmakeListBody;
580 cmakeListBody += getCMakeListsHeader();
581 bool b(true);
582 cmakeListBody += "#Generating tests for " + PString::toString(vecClassConfig.size()) + "\n";
583 for(std::vector<PClassConfig>::const_iterator it(vecClassConfig.begin()); it != vecClassConfig.end(); ++it){
584 cmakeListBody += "add_subdirectory(TEST_" + it->getName().toUpper() + ")\n";
585 b &= generator_class_test(manager, outputTestDir, *it, projectName, baseFileName, mode);
586 }
587 cmakeListBody += "\n\n";
588 PPath cmakelist(outputTestDir / PPath("CMakeLists.txt"));
589 b &= cmakelist.saveFileContent(cmakeListBody);
590 return b;
591}
592
594
598bool generator_class_full(const PTraitBackendManager & manager, const ProjectParam & projectParam){
599 bool b(true);
600 b &= projectParam.outputSourceDir.createDirectory();
601 b &= projectParam.outputTestDir.createDirectory();
602 PString cmakeListBody;
603 cmakeListBody += getCMakeListsHeader();
604 const PVecDataConfig & vecDataConfig = projectParam.vecDataConfig;
605 for(const PDataConfig & config : vecDataConfig){
606 PPath baseFileName = config.getFileName().getFileName().eraseExtension();
607 if(!generator_class_cpp(manager, config.getVecClassConfig(), projectParam.outputSourceDir, baseFileName, projectParam.mode, config.getVecInclude())){
608 std::cerr << termRed() << "generator_class_full : cannot generate C++ sources at '"<<projectParam.outputSourceDir<<"'" << termDefault() << std::endl;
609 b = false; //best effort strategy
610 }
611 PPath outputCurrentTestDir = projectParam.outputTestDir / PPath("TEST_" + config.getFileName().getFileName().eraseExtension().toUpper());
612 cmakeListBody += "add_subdirectory(" + outputCurrentTestDir.getFileName() + ")\n";
613 if(!generator_class_cpp_test(manager, outputCurrentTestDir, config.getVecClassConfig(), projectParam.name, baseFileName, projectParam.mode)){
614 std::cerr << termRed() << "generator_class_full : cannot generate C++ tests at '"<<projectParam.outputTestDir<<"'" << termDefault() << std::endl;
615 b = false; //best effort strategy
616 }
617 }
618 cmakeListBody += "\n\n";
619 PPath cmakelist(projectParam.outputTestDir / PPath("CMakeLists.txt"));
620 b &= cmakelist.saveFileContent(cmakeListBody);
621 return b;
622}
623
624
625
626
std::vector< PDataConfig > PVecDataConfig
Definition PDataConfig.h:48
Describes a class attribute.
const PString & getDefaultValue() const
Gets the defaultValue of the PClassAttribute.
const PString & getType() const
Gets the type of the PClassAttribute.
Class to describe a basic class.
const PString & getClassDocumentation() const
Returns the class documentation.
const std::vector< PClassAttribute > & getListAttribute() const
Returns the list of attributes of the class.
const PVecString & getListTemplate() const
Returns the list of the template of the class.
const PString & getName() const
Returns the class name.
bool getIsEnum() const
Say if the current PClassConfig is an enum.
const PVecString & getListParentClass() const
Returns the list of the parents of the class.
const PString & getNamespace() const
Returns the namespace of the class.
Class to describe a basic class.
Definition PDataConfig.h:17
Manager of the Trait backends.
void protectedMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of protected methods.
void classExtraFunctionDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of extra functions.
void testCallFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Call of the test function.
void classExtraFunctionImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of extra functions.
void headerExtraInclude(std::ofstream &fs, const GeneratorMode &mode) const
Add extra include on the header.
void privateMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of private methods.
void protectedMethodImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of protected methods.
void privateMethodImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of private methods.
void publicMethodImplementation(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of public methods.
void publicMethodDeclaration(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Declaration of public methods.
void testFunction(std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode) const
Implementation of test function.
PString getCMakeListsHeader()
Get the CMakeLists.txt header.
void class_savePointerOwnershipSpecialMembersImpl(std::ofstream &fs, const PClassConfig &classConfig, const PString &defTemplate, const PString &templateDeclaration)
Saves the destructor, copy constructor/assignment and move constructor/assignment of a class owning a...
bool generator_checkDefaultValueExist(const std::vector< PClassAttribute > &vecAttr)
Check if the vector of PClassAttribute has default value.
PString class_getClassDefTemplate(const PVecString &listTemplate)
Get the template call in the class declaration.
void generator_class_cpp_source(const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
Create the implementation of the given class.
PString class_getAttributeDefaultInit(const PClassAttribute &attr)
Get the in-class default member initialiser of an attribute (eg "{0}"), or an empty PString if the at...
void generator_class_cpp_header(const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
Create the declaration of the given class.
bool generator_class_cpp(const PTraitBackendManager &manager, const std::vector< PClassConfig > &vecClassConfig, const PPath &outputSourceDir, const PPath &baseFileName, const GeneratorMode &mode, const PVecPath &vecInclude)
Creates header and source files.
PString class_getClassDeclTempalteDef(const PVecString &listTemplate)
Get the template definition in the class declaration.
bool generator_class_test(const PTraitBackendManager &manager, const PPath &outputTestDir, const PClassConfig &classConfig, const PString &projectName, const PPath &baseFileName, const GeneratorMode &mode)
Save the unit test of the generated PClassConfig.
bool generator_class_cpp_sourceFile(const PTraitBackendManager &manager, const PPath &sourceFile, const PPath &headerFile, const std::vector< PClassConfig > &vecClassConfig, const GeneratorMode &mode, bool isTemplateImpl)
Create the implementation of the given file.
bool generator_class_cpp_test(const PTraitBackendManager &manager, const PPath &outputTestDir, const std::vector< PClassConfig > &vecClassConfig, const PString &projectName, const PPath &baseFileName, const GeneratorMode &mode)
Save the unit test of the generated PClassConfig.
void class_checkClassConfig(bool &hasSource, bool &hasTemplate, const std::vector< PClassConfig > &vecClassConfig)
Check if the configuration has source or template to determine if the .cpp or _impl....
bool generator_class_full(const PTraitBackendManager &manager, const ProjectParam &projectParam)
Generate the full sources and related unit tests from configuration.
bool generator_class_cpp_headerFile(const PTraitBackendManager &manager, const PPath &headerFile, const std::vector< PClassConfig > &vecClassConfig, const GeneratorMode &mode, const PVecPath &vecInclude, const PString &includeTemplate)
Create the declaration of the given class.
bool generator_class_testMain(const PTraitBackendManager &manager, const PPath &outputCurrentTestDir, const PClassConfig &classConfig, const PPath &baseFileName, const GeneratorMode &mode)
Save the CMakeLists to be used to compile the unit test.
void generator_enum_cpp_header(const PTraitBackendManager &manager, std::ofstream &fs, const PClassConfig &classConfig, const GeneratorMode &mode)
Create the declaration of the given class.
bool generator_class_testCMakeLists(const PPath &outputCurrentTestDir, const PClassConfig &classConfig, const PString &projectName, const GeneratorMode &mode)
Save the CMakeLists to be used to compile the unit test.
bool class_hasPointerAttribute(const PClassConfig &classConfig)
Check if the given class owns at least one pointer attribute.
PString makeMultiIncludeDefineMacro(const PString &fileName)
Create the macro of multi inclusion file name.
void licenceSave(std::ofstream &fs)
Saves the policy.
All the genertor modes.
PString defTemplate
Template definition for the class header.
PString assertInclude
Include of the assert to be used.
PString templateDeclaration
Template declaration of the method implementation.
Set of parameters to generate a project.
GeneratorMode mode
Mode to be used to generate the project.
PPath outputTestDir
Output path of the unit tests.
PVecDataConfig vecDataConfig
Configuration of classes to be generated.
PString name
Name of the project.
PPath outputSourceDir
Output path of the sources.
bool getIsPointerType(const PString &varType)
Say if a given type is a pointer type (i.e. it ends with a '*').
PString getDefaultValueTypeInCpp(const PString &type)
Get the default value of a type in C++.