1 /*
2 SPDX-License-Identifier: GPL-2.0-or-later
3
4 SPDX-FileCopyrightText: 2003 Brian Thomas <thomas@mail630.gsfc.nasa.gov>
5 SPDX-FileCopyrightText: 2003-2020 Umbrello UML Modeller Authors <umbrello-devel@kde.org>
6 */
7
8 /**
9 * We carve the CPP document up into 2 documents, "source" and "header".
10 * The sections of each are as follows:
11 * - header
12 * - includes
13 * - constructor methods
14 * - all other methods
15 */
16
17 // own header
18 #include "cppsourcecodedocument.h"
19
20 // app includes
21 #include "cppcodegenerator.h"
22 #include "cppcodegenerationpolicy.h"
23 #include "cppcodedocumentation.h"
24 #include "cppcodeclassfield.h"
25 #include "cppsourcecodeclassfielddeclarationblock.h"
26 #include "debug_utils.h"
27 #include "uml.h"
28
29 // qt includes
30 #include <QRegExp>
31
CPPSourceCodeDocument(UMLClassifier * concept)32 CPPSourceCodeDocument::CPPSourceCodeDocument (UMLClassifier * concept)
33 : ClassifierCodeDocument (concept)
34 {
35 setFileExtension(QLatin1String(".cpp"));
36
37 m_methodsBlock = 0;
38 m_constructorBlock = 0;
39
40 /* We cannot call any virtual initialization functions here because
41 the object is still under construction and the C++ dispatch table
42 is not yet set up.
43 Full initialization is done in CodeGenFactory::newCodeOperation()
44 */
45 }
46
~CPPSourceCodeDocument()47 CPPSourceCodeDocument::~CPPSourceCodeDocument()
48 {
49 }
50
addCodeOperation(CodeOperation * op)51 bool CPPSourceCodeDocument::addCodeOperation (CodeOperation * op)
52 {
53 bool retval = false;
54 if (op->getParentOperation()->isLifeOperation()) {
55 if (m_constructorBlock)
56 retval = m_constructorBlock->addTextBlock(op);
57 else
58 uError() << "m_constructorBlock is NULL";
59 } else {
60 if (m_methodsBlock)
61 retval = m_methodsBlock->addTextBlock(op);
62 else
63 uError() << "m_methodsBlock is NULL";
64 }
65 return retval;
66 }
67
resetTextBlocks()68 void CPPSourceCodeDocument::resetTextBlocks()
69 {
70 // all special pointers need to be zero'd out.
71 m_methodsBlock = 0;
72 m_constructorBlock = 0;
73
74 // now do the traditional release of child text blocks
75 ClassifierCodeDocument::resetTextBlocks();
76 }
77
updateContent()78 void CPPSourceCodeDocument::updateContent()
79 {
80 // Gather info on the various fields and parent objects of this class...
81 //UMLClassifier * c = getParentClassifier();
82 CodeGenPolicyExt *pe = UMLApp::app()->policyExt();
83 CPPCodeGenerationPolicy * policy = dynamic_cast<CPPCodeGenerationPolicy*>(pe);
84 QString endLine = UMLApp::app()->commonPolicy()->getNewLineEndingChars();
85
86 // first, set the global flag on whether or not to show classfield info
87 const CodeClassFieldList * cfList = getCodeClassFieldList();
88 CodeClassFieldList::const_iterator it = cfList->begin();
89 CodeClassFieldList::const_iterator end = cfList->end();
90 for(; it != end; ++it)
91 (*it)->setWriteOutMethods(policy->getAutoGenerateAccessors());
92
93 // attribute-based ClassFields
94 // we do it this way to have the static fields sorted out from regular ones
95 CodeClassFieldList staticAttribClassFields = getSpecificClassFields (CodeClassField::Attribute, true);
96 CodeClassFieldList attribClassFields = getSpecificClassFields (CodeClassField::Attribute, false);
97 // association-based ClassFields
98 // don't care if they are static or not..all are lumped together
99 CodeClassFieldList plainAssocClassFields = getSpecificClassFields (CodeClassField::PlainAssociation);
100 CodeClassFieldList aggregationClassFields = getSpecificClassFields (CodeClassField::Aggregation);
101 CodeClassFieldList compositionClassFields = getSpecificClassFields (CodeClassField::Composition);
102
103 // START GENERATING CODE/TEXT BLOCKS and COMMENTS FOR THE DOCUMENT
104
105 // INCLUDE CODEBLOCK
106 QString includeStatement;
107 // Include own header file
108 QString myOwnName(getParentClassifier()->name());
109 includeStatement.append(QLatin1String("#include \"") + CodeGenerator::cleanName(myOwnName.toLower()) + QLatin1String(".h\"") + endLine);
110 CodeBlockWithComments * iblock = addOrUpdateTaggedCodeBlockWithComments(QLatin1String("includes"), includeStatement, QString(), 0, false);
111 iblock->setWriteOutText(true);
112
113 // After the includes we have just 2 big blocks basically, the "constructor" block and the
114 // block for the rest of our methods (operations + accessors)
115
116 m_constructorBlock = getHierarchicalCodeBlock(QLatin1String("constructionMethodsBlock"), QLatin1String("Constructors/Destructors"), 0);
117 m_methodsBlock = getHierarchicalCodeBlock(QLatin1String("otherMethodsBlock"), QLatin1String("Methods"), 0);
118
119 // add accessors to the methods block
120 m_methodsBlock->addCodeClassFieldMethods(staticAttribClassFields);
121 m_methodsBlock->addCodeClassFieldMethods(attribClassFields);
122 m_methodsBlock->addCodeClassFieldMethods(plainAssocClassFields);
123 m_methodsBlock->addCodeClassFieldMethods(aggregationClassFields);
124 m_methodsBlock->addCodeClassFieldMethods(compositionClassFields);
125
126 // constructors and other operations are handled by the "addCodeOperation" method above.
127 }
128
129
130