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