~ubuntu-branches/ubuntu/intrepid/kdesdk/intrepid-updates

« back to all changes in this revision

Viewing changes to umbrello/umbrello/codegenerators/cppwriter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2008-05-28 10:11:43 UTC
  • mto: This revision was merged to the branch mainline in revision 37.
  • Revision ID: james.westby@ubuntu.com-20080528101143-gzc3styjz1b70zxu
Tags: upstream-4.0.80
ImportĀ upstreamĀ versionĀ 4.0.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
 
 *                        cppwriter.cpp  -  description                    *
3
 
 *  This is the "old" code generator that does not support code editing    *
4
 
 *  in the Modeller but uses significantly less file space because the     *
5
 
 *  source code is not replicated in the XMI file.                         *
6
 
 *                                                                         *
7
 
 *  copyright       : (C) 2003 Brian Thomas brian.thomas@gsfc.nasa.gov     *
8
 
 *  (C) 2004-2006  Umbrello UML Modeller Authors <uml-devel@uml.sf.net>    *
9
 
 *                                                                         *
 
2
                          cppwriter.cpp
 
3
    This is the "old" code generator that does not support code editing
 
4
    in the Modeller but uses significantly less file space because the
 
5
    source code is not replicated in the XMI file.
 
6
 
 
7
    Copyright (C) 2003       Brian Thomas
 
8
                             <brian.thomas@gsfc.nasa.gov>
 
9
              (C) 2004-2008  Umbrello UML Modeller Authors
 
10
                             <uml-devel@uml.sf.net>
 
11
 
10
12
 ***************************************************************************
11
13
 *                                                                         *
12
14
 *   This program is free software; you can redistribute it and/or modify  *
19
21
// own header
20
22
#include "cppwriter.h"
21
23
// qt/kde includes
22
 
#include <qfile.h>
23
 
#include <qtextstream.h>
24
 
#include <qregexp.h>
 
24
#include <QtCore/QFile>
 
25
#include <QtCore/QTextStream>
 
26
#include <QtCore/QRegExp>
25
27
#include <kdebug.h>
26
28
// app includes
27
 
#include "classifierinfo.h"
28
29
#include "codegen_utils.h"
29
30
#include "../uml.h"
30
31
#include "../umldoc.h"
 
32
#include "../association.h"
31
33
#include "../classifier.h"
32
34
#include "../operation.h"
33
35
#include "../template.h"
50
52
    // and "%ITEMCLASS%", if needed, where the class of the item is declared.
51
53
    VECTOR_METHOD_APPEND = "%VARNAME%.push_back(add_object);"; // for std::vector
52
54
    VECTOR_METHOD_REMOVE = "int i, size = %VARNAME%.size();\nfor ( i = 0; i < size; i++) {\n\t%ITEMCLASS% item = %VARNAME%.at(i);\n\tif(item == remove_object) {\n\t\tvector<%ITEMCLASS%>::iterator it = %VARNAME%.begin() + i;\n\t\t%VARNAME%.erase(it);\n\t\treturn;\n\t}\n }"; // for std::vector
53
 
    VECTOR_METHOD_INIT = QString(); // nothing to be done
 
55
    VECTOR_METHOD_INIT.clear(); // nothing to be done
54
56
    /*
55
57
        VECTOR_METHOD_APPEND = "%VARNAME%.append(&add_object);"; // Qt lib implementation
56
58
        VECTOR_METHOD_REMOVE = "%VARNAME%.removeRef(&remove_object);"; // Qt lib implementation
61
63
 
62
64
    // boolean config params
63
65
    INLINE_ASSOCIATION_METHODS = false;
64
 
 
65
 
}
66
 
 
67
 
CppWriter::~CppWriter() { }
68
 
 
69
 
Uml::Programming_Language CppWriter::getLanguage() {
 
66
}
 
67
 
 
68
CppWriter::~CppWriter()
 
69
{
 
70
}
 
71
 
 
72
Uml::Programming_Language CppWriter::getLanguage()
 
73
{
70
74
    return Uml::pl_Cpp;
71
75
}
72
76
 
73
 
CPPCodeGenerationPolicy *CppWriter::policyExt() {
 
77
CPPCodeGenerationPolicy *CppWriter::policyExt()
 
78
{
74
79
    return static_cast<CPPCodeGenerationPolicy*>(UMLApp::app()->getPolicyExt());
75
80
}
76
81
 
77
82
void CppWriter::writeClass(UMLClassifier *c)
78
83
{
79
 
 
80
84
    if (!c) {
81
 
        kDebug() << "Cannot write class of NULL concept!\n";
 
85
        uDebug() << "Cannot write class of NULL concept!\n";
82
86
        return;
83
87
    }
84
88
 
85
89
    QFile fileh, filecpp;
86
90
 
87
91
    // find an appropriate name for our file
88
 
    QString fileName = findFileName(c, ".h");
89
 
    if (fileName.isEmpty()) {
 
92
    fileName_ = findFileName(c, ".h");
 
93
    if (fileName_.isEmpty()) {
90
94
        emit codeGenerated(c, false);
91
95
        return;
92
96
    }
93
97
 
94
 
    // preparations
95
 
    m_classifierInfo = new ClassifierInfo(c);
96
 
    m_classifierInfo->fileName = fileName;
97
 
    m_classifierInfo->className = cleanName(c->getName());
 
98
    className_ = cleanName(c->getName());
98
99
 
99
100
    if (c->getVisibility() != Uml::Visibility::Implementation) {
100
 
        if( !openFile(fileh, fileName)) {
 
101
        if( !openFile(fileh, fileName_)) {
101
102
            emit codeGenerated(c, false);
102
103
            return;
103
104
        }
113
114
        need_impl = false;
114
115
    }
115
116
    if (need_impl) {
116
 
        fileName.replace( QRegExp(".h$"), ".cpp");
117
 
        if( !openFile(filecpp, fileName)) {
 
117
        fileName_.replace( QRegExp(".h$"), ".cpp");
 
118
        if( !openFile(filecpp, fileName_)) {
118
119
            emit codeGenerated(c, false);
119
120
            return;
120
121
        }
123
124
        filecpp.close();
124
125
    }
125
126
 
126
 
    // Wrap up: free m_classifierInfo, emit done code
127
 
    m_classifierInfo = 0;
128
 
 
129
127
    emit codeGenerated(c, true);
130
 
 
131
128
}
132
129
 
133
 
void CppWriter::writeHeaderFile (UMLClassifier *c, QFile &fileh) {
134
 
 
 
130
void CppWriter::writeHeaderFile (UMLClassifier *c, QFile &fileh)
 
131
{
135
132
    // open stream for writing
136
133
    QTextStream h (&fileh);
137
134
 
140
137
 
141
138
    // write header blurb
142
139
    QString str = getHeadingFile(".h");
143
 
    if(!str.isEmpty()) {
144
 
        str.replace(QRegExp("%filename%"),m_classifierInfo->fileName + ".h");
145
 
        str.replace(QRegExp("%filepath%"),fileh.name());
 
140
    if (!str.isEmpty()) {
 
141
        str.replace(QRegExp("%filename%"), fileName_ + ".h");
 
142
        str.replace(QRegExp("%filepath%"), fileh.fileName());
146
143
        h << str<< m_endl;
147
144
    }
148
145
 
149
146
    // Write the hash define stuff to prevent multiple parsing/inclusion of header
150
 
    QString hashDefine = m_classifierInfo->className.upper().simplifyWhiteSpace().replace(QRegExp(" "),  "_");
 
147
    QString hashDefine = className_.toUpper().simplified().replace(QRegExp(" "),  "_");
151
148
    writeBlankLine(h);
152
149
    h << "#ifndef "<< hashDefine + "_H" << m_endl;
153
150
    h << "#define "<< hashDefine + "_H" << m_endl;
156
153
 
157
154
    // last thing..close our hashdefine
158
155
    h << m_endl << "#endif // " << hashDefine + "_H" << m_endl;
159
 
 
160
156
}
161
157
 
162
158
void CppWriter::writeHeaderAccessorMethodDecl(UMLClassifier *c, Uml::Visibility permitScope, QTextStream &stream)
163
159
{
164
 
 
165
160
    // attributes
166
 
    writeHeaderAttributeAccessorMethods(permitScope, true, stream); // write static attributes first
167
 
    writeHeaderAttributeAccessorMethods(permitScope, false, stream);
 
161
    writeHeaderAttributeAccessorMethods(c, permitScope, true, stream); // write static attributes first
 
162
    writeHeaderAttributeAccessorMethods(c, permitScope, false, stream);
168
163
 
169
164
    // associations
170
 
    writeAssociationMethods(m_classifierInfo->plainAssociations, permitScope,
171
 
                            true, INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
172
 
    writeAssociationMethods(m_classifierInfo->uniAssociations, permitScope,
173
 
                            true, INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
174
 
    writeAssociationMethods(m_classifierInfo->aggregations, permitScope,
 
165
    writeAssociationMethods(c->getSpecificAssocs(Uml::at_Association), permitScope,
 
166
                            true, INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
 
167
    writeAssociationMethods(c->getUniAssociationToBeImplemented(), permitScope,
 
168
                            true, INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
 
169
    writeAssociationMethods(c->getAggregations(), permitScope,
175
170
                            true,  INLINE_ASSOCIATION_METHODS, true, c->getID(), stream);
176
 
    writeAssociationMethods(m_classifierInfo->compositions, permitScope,
 
171
    writeAssociationMethods(c->getCompositions(), permitScope,
177
172
                            true, INLINE_ASSOCIATION_METHODS, false, c->getID(), stream);
178
173
 
179
174
    writeBlankLine(stream);
180
 
 
181
175
}
182
176
 
183
177
void CppWriter::writeHeaderFieldDecl(UMLClassifier *c, Uml::Visibility permitScope, QTextStream &stream)
184
178
{
185
179
    // attributes
186
 
    writeAttributeDecls(permitScope, true, stream); // write static attributes first
187
 
    writeAttributeDecls(permitScope, false, stream);
 
180
    writeAttributeDecls(c, permitScope, true, stream); // write static attributes first
 
181
    writeAttributeDecls(c, permitScope, false, stream);
188
182
 
189
183
    // associations
190
 
    writeAssociationDecls(m_classifierInfo->plainAssociations, permitScope, c->getID(), stream);
191
 
    writeAssociationDecls(m_classifierInfo->uniAssociations, permitScope, c->getID(), stream);
192
 
    writeAssociationDecls(m_classifierInfo->aggregations, permitScope, c->getID(), stream);
193
 
    writeAssociationDecls(m_classifierInfo->compositions, permitScope, c->getID(), stream);
194
 
 
 
184
    writeAssociationDecls(c->getSpecificAssocs(Uml::at_Association), permitScope, c->getID(), stream);
 
185
    writeAssociationDecls(c->getUniAssociationToBeImplemented(), permitScope, c->getID(), stream);
 
186
    writeAssociationDecls(c->getAggregations(), permitScope, c->getID(), stream);
 
187
    writeAssociationDecls(c->getCompositions(), permitScope, c->getID(), stream);
195
188
}
196
189
 
197
 
void CppWriter::writeSourceFile (UMLClassifier *c, QFile &filecpp ) {
198
 
 
 
190
void CppWriter::writeSourceFile (UMLClassifier *c, QFile &filecpp )
 
191
{
199
192
    // open stream for writing
200
193
    QTextStream cpp (&filecpp);
201
194
 
205
198
    //try to find a heading file (license, coments, etc)
206
199
    QString str;
207
200
    str = getHeadingFile(".cpp");
208
 
    if(!str.isEmpty()) {
209
 
        str.replace(QRegExp("%filename%"),m_classifierInfo->fileName + ".cpp");
210
 
        str.replace(QRegExp("%filepath%"),filecpp.name());
 
201
    if (!str.isEmpty()) {
 
202
        str.replace(QRegExp("%filename%"), fileName_ + ".cpp");
 
203
        str.replace(QRegExp("%filepath%"), filecpp.fileName());
211
204
        cpp << str << m_endl;
212
205
    }
213
206
 
215
208
    // Q: Why all utils? Isnt just List and Vector the only classes we are using?
216
209
    // Our import *should* also look at operations, and check that objects being
217
210
    // used arent in another package (and thus need to be explicitly imported here).
218
 
    cpp << "#include \"" << m_classifierInfo->className << ".h\"" << m_endl;
 
211
    cpp << "#include \"" << className_ << ".h\"" << m_endl;
219
212
    writeBlankLine(cpp);
220
213
 
221
214
    if (c->getVisibility() == Uml::Visibility::Implementation) {
226
219
 
227
220
    // Constructors: anything we more we need to do here ?
228
221
    //
229
 
    if(!m_classifierInfo->isInterface)
230
 
        writeConstructorMethods(cpp);
 
222
    if (!c->isInterface())
 
223
        writeConstructorMethods(c, cpp);
231
224
 
232
225
    // METHODS
233
226
    //
234
227
 
235
228
    // write comment for section IF needed
236
229
    QString indent = getIndent();
237
 
    if (forceDoc() || m_classifierInfo->hasAccessorMethods || m_classifierInfo->hasOperationMethods)
 
230
    if (forceDoc() || c->hasAccessorMethods() || c->hasOperationMethods())
238
231
    {
239
 
 
240
232
        writeComment(" ", indent, cpp);
241
233
        writeComment("Methods", indent, cpp);
242
234
        writeComment(" ", indent, cpp);
245
237
    }
246
238
 
247
239
    // write comment for sub-section IF needed
248
 
    if (forceDoc() || m_classifierInfo->hasAccessorMethods )
 
240
    if (forceDoc() || c->hasAccessorMethods() )
249
241
    {
250
242
        writeComment("Accessor methods", indent, cpp);
251
243
        writeComment(" ", indent, cpp);
254
246
 
255
247
    // Accessor methods for attributes
256
248
    const bool bInlineAccessors = policyExt()->getAccessorsAreInline();
257
 
    if (!bInlineAccessors && m_classifierInfo->hasAttributes)
 
249
    if (!bInlineAccessors && c->hasAttributes())
258
250
    {
259
 
        writeAttributeMethods(&(m_classifierInfo->static_atpub), Uml::Visibility::Public, false, true, !bInlineAccessors, cpp);
260
 
        writeAttributeMethods(&(m_classifierInfo->atpub), Uml::Visibility::Public, false, false, !bInlineAccessors, cpp);
261
 
        writeAttributeMethods(&(m_classifierInfo->static_atprot), Uml::Visibility::Protected, false, true, !bInlineAccessors, cpp);
262
 
        writeAttributeMethods(&(m_classifierInfo->atprot), Uml::Visibility::Protected, false, false, !bInlineAccessors, cpp);
263
 
        writeAttributeMethods(&(m_classifierInfo->static_atpriv), Uml::Visibility::Private, false, true, !bInlineAccessors, cpp);
264
 
        writeAttributeMethods(&(m_classifierInfo->atpriv), Uml::Visibility::Private, false, false, !bInlineAccessors, cpp);
 
251
        writeAttributeMethods(c->getAttributeListStatic(Uml::Visibility::Public), Uml::Visibility::Public, false, true, !bInlineAccessors, cpp);
 
252
        writeAttributeMethods(c->getAttributeList(Uml::Visibility::Public), Uml::Visibility::Public, false, false, !bInlineAccessors, cpp);
 
253
        writeAttributeMethods(c->getAttributeListStatic(Uml::Visibility::Protected), Uml::Visibility::Protected, false, true, !bInlineAccessors, cpp);
 
254
        writeAttributeMethods(c->getAttributeList(Uml::Visibility::Protected), Uml::Visibility::Protected, false, false, !bInlineAccessors, cpp);
 
255
        writeAttributeMethods(c->getAttributeListStatic(Uml::Visibility::Private), Uml::Visibility::Private, false, true, !bInlineAccessors, cpp);
 
256
        writeAttributeMethods(c->getAttributeList(Uml::Visibility::Private), Uml::Visibility::Private, false, false, !bInlineAccessors, cpp);
265
257
    }
266
258
 
267
259
    // accessor methods for associations
268
260
 
269
261
    // public
270
 
    writeAssociationMethods(m_classifierInfo->plainAssociations, Uml::Visibility::Public, false,
271
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
272
 
    writeAssociationMethods(m_classifierInfo->uniAssociations, Uml::Visibility::Public, false,
273
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
274
 
    writeAssociationMethods(m_classifierInfo->aggregations, Uml::Visibility::Public, false,
275
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
276
 
    writeAssociationMethods(m_classifierInfo->compositions, Uml::Visibility::Public, false,
 
262
    writeAssociationMethods(c->getSpecificAssocs(Uml::at_Association), Uml::Visibility::Public, false,
 
263
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
264
    writeAssociationMethods(c->getUniAssociationToBeImplemented(), Uml::Visibility::Public, false,
 
265
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
266
    writeAssociationMethods(c->getAggregations(), Uml::Visibility::Public, false,
 
267
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
268
    writeAssociationMethods(c->getCompositions(), Uml::Visibility::Public, false,
277
269
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
278
270
 
279
271
    // protected
280
 
    writeAssociationMethods(m_classifierInfo->plainAssociations, Uml::Visibility::Protected, false,
281
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
282
 
    writeAssociationMethods(m_classifierInfo->uniAssociations, Uml::Visibility::Protected, false,
283
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
284
 
    writeAssociationMethods(m_classifierInfo->aggregations, Uml::Visibility::Protected, false,
285
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
286
 
    writeAssociationMethods(m_classifierInfo->compositions, Uml::Visibility::Protected, false,
 
272
    writeAssociationMethods(c->getSpecificAssocs(Uml::at_Association), Uml::Visibility::Protected, false,
 
273
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
274
    writeAssociationMethods(c->getUniAssociationToBeImplemented(), Uml::Visibility::Protected, false,
 
275
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
276
    writeAssociationMethods(c->getAggregations(), Uml::Visibility::Protected, false,
 
277
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
278
    writeAssociationMethods(c->getCompositions(), Uml::Visibility::Protected, false,
287
279
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
288
280
 
289
281
 
290
282
    // private
291
 
    writeAssociationMethods(m_classifierInfo->plainAssociations, Uml::Visibility::Private, false,
292
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
293
 
    writeAssociationMethods(m_classifierInfo->uniAssociations, Uml::Visibility::Private, false,
294
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
295
 
    writeAssociationMethods(m_classifierInfo->aggregations, Uml::Visibility::Private, false,
296
 
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
297
 
    writeAssociationMethods(m_classifierInfo->compositions, Uml::Visibility::Private, false,
 
283
    writeAssociationMethods(c->getSpecificAssocs(Uml::at_Association), Uml::Visibility::Private, false,
 
284
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
285
    writeAssociationMethods(c->getUniAssociationToBeImplemented(), Uml::Visibility::Private, false,
 
286
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
287
    writeAssociationMethods(c->getAggregations(), Uml::Visibility::Private, false,
 
288
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
 
289
    writeAssociationMethods(c->getCompositions(), Uml::Visibility::Private, false,
298
290
                            !INLINE_ASSOCIATION_METHODS, true, c->getID(), cpp);
299
291
    writeBlankLine(cpp);
300
292
 
302
294
    //
303
295
 
304
296
    // write comment for sub-section IF needed
305
 
    if (forceDoc() || m_classifierInfo->hasOperationMethods)
 
297
    if (forceDoc() || c->hasOperationMethods())
306
298
    {
307
299
        writeComment("Other methods", indent, cpp);
308
300
        writeComment(" ", indent, cpp);
317
309
    }
318
310
 
319
311
    // Yep, bringing up the back of the bus, our initialization method for attributes
320
 
    writeInitAttibuteMethod (cpp);
 
312
    writeInitAttributeMethod(c, cpp);
321
313
 
322
314
    writeBlankLine(cpp);
323
 
 
324
315
}
325
316
 
326
317
void CppWriter::writeClassDecl(UMLClassifier *c, QTextStream &cpp)
327
318
{
328
 
    UMLClassifierList superclasses = m_classifierInfo->superclasses;
329
 
    for(UMLClassifier *classifier = superclasses.first(); classifier ;classifier = superclasses.next()) {
 
319
    UMLClassifierList superclasses = c->getSuperClasses();
 
320
    foreach (UMLClassifier* classifier, superclasses ) {
330
321
        QString headerName = findFileName(classifier, ".h");
331
322
        if (!headerName.isEmpty()) {
332
323
            cpp << "#include \"" << headerName << "\"" << m_endl;
334
325
    }
335
326
 
336
327
    writeBlankLine(cpp);
337
 
    cpp << "#include " << policyExt()->getStringClassNameInclude() << m_endl;
338
 
    if(m_classifierInfo->hasVectorFields)
 
328
    cpp << "#include <" << policyExt()->getStringClassNameInclude() << ">" << m_endl;
 
329
    if (c->hasVectorFields())
339
330
    {
340
331
        cpp << "#include " << policyExt()->getVectorClassNameInclude() << m_endl;
341
332
        writeBlankLine(cpp);
342
333
    }
343
334
 
344
 
    if(m_classifierInfo->hasAssociations)
 
335
    if (c->hasAssociations())
345
336
    {
346
337
        // write all includes we need to include other classes, that arent us.
347
 
        printAssociationIncludeDecl (m_classifierInfo->plainAssociations, c->getID(), cpp);
348
 
        printAssociationIncludeDecl (m_classifierInfo->uniAssociations, c->getID(), cpp);
349
 
        printAssociationIncludeDecl (m_classifierInfo->aggregations, c->getID(), cpp);
350
 
        printAssociationIncludeDecl (m_classifierInfo->compositions, c->getID(), cpp);
 
338
        printAssociationIncludeDecl (c->getSpecificAssocs(Uml::at_Association), c->getID(), cpp);
 
339
        printAssociationIncludeDecl (c->getUniAssociationToBeImplemented(), c->getID(), cpp);
 
340
        printAssociationIncludeDecl (c->getAggregations(), c->getID(), cpp);
 
341
        printAssociationIncludeDecl (c->getCompositions(), c->getID(), cpp);
351
342
 
352
343
        writeBlankLine(cpp);
353
344
    }
354
345
 
355
 
 
356
 
    for(UMLClassifier *classifier = superclasses.first(); classifier ; classifier = superclasses.next()) {
357
 
        if(classifier->getPackage()!=c->getPackage() && !classifier->getPackage().isEmpty()) {
 
346
    foreach (UMLClassifier* classifier, superclasses ) {
 
347
        if (classifier->getPackage()!=c->getPackage() && !classifier->getPackage().isEmpty()) {
358
348
            cpp << "using " << cleanName(classifier->getPackage()) << "::" << cleanName(classifier->getName()) << ";" << m_endl;
359
349
        }
360
350
    }
361
351
 
362
 
    if(!c->getPackage().isEmpty() && policyExt()->getPackageIsNamespace())
 
352
    if (!c->getPackage().isEmpty() && policyExt()->getPackageIsNamespace())
363
353
        cpp << m_endl << "namespace " << cleanName(c->getPackage()) << " {" << m_endl << m_endl;
364
354
 
365
355
    //Write class Documentation if there is somthing or if force option
366
 
    if(forceDoc() || !c->getDoc().isEmpty()) {
 
356
    if (forceDoc() || !c->getDoc().isEmpty()) {
367
357
        cpp << m_endl << "/**" << m_endl;
368
 
        cpp << "  * class " << m_classifierInfo->className << m_endl;
 
358
        cpp << "  * class " << className_ << m_endl;
369
359
        cpp << formatDoc(c->getDoc(),"  * ");
370
360
        cpp << "  */";
371
361
        writeBlankLine(cpp);
373
363
    }
374
364
 
375
365
    //check if class is abstract and / or has abstract methods
376
 
    if((c->getAbstract() || m_classifierInfo->isInterface )
 
366
    if ((c->getAbstract() || c->isInterface())
377
367
            && !hasAbstractOps(c))
378
368
        cpp << "/******************************* Abstract Class ****************************" << m_endl
379
 
        <<m_classifierInfo->className << " does not have any pure virtual methods, but its author" << m_endl
380
 
        <<"  defined it as an abstract class, so you should not use it directly." << m_endl
381
 
        <<"  Inherit from it instead and create only objects from the derived classes" << m_endl
382
 
        <<"*****************************************************************************/" << m_endl << m_endl;
 
369
        << className_ << " does not have any pure virtual methods, but its author" << m_endl
 
370
        << "  defined it as an abstract class, so you should not use it directly." << m_endl
 
371
        << "  Inherit from it instead and create only objects from the derived classes" << m_endl
 
372
        << "*****************************************************************************/" << m_endl << m_endl;
383
373
 
384
374
    if (c->getBaseType() == Uml::ot_Enum) {
385
375
        UMLClassifierListItemList litList = c->getFilteredList(Uml::ot_EnumLiteral);
386
376
        uint i = 0;
387
 
        cpp << "enum " << m_classifierInfo->className << " {" << m_endl;
388
 
        for (UMLClassifierListItem *lit = litList.first(); lit; lit = litList.next()) {
 
377
        cpp << "enum " << className_ << " {" << m_endl;
 
378
        foreach (UMLClassifierListItem* lit, litList ) {
389
379
            QString enumLiteral = cleanName(lit->getName());
390
380
            cpp << getIndent() << enumLiteral;
391
 
            if (++i < litList.count())
 
381
            if (++i < ( uint )litList.count())
392
382
                cpp << ",";
393
383
            cpp << m_endl;
394
384
        }
395
385
        cpp << m_endl << "};" << m_endl;  // end of class header
396
 
        if(!c->getPackage().isEmpty() && policyExt()->getPackageIsNamespace())
 
386
        if (!c->getPackage().isEmpty() && policyExt()->getPackageIsNamespace())
397
387
            cpp << "}  // end of package namespace" << m_endl;
398
388
        return;
399
389
    }
402
392
    UMLTemplateList template_params = c->getTemplateList();
403
393
    if (template_params.count()) {
404
394
        cpp << "template<";
405
 
        for (UMLTemplate *t = template_params.first(); t; ) {
 
395
        for (UMLTemplateListIt tlit( template_params ); tlit.hasNext(); ) {
 
396
            UMLTemplate* t = tlit.next();
406
397
            QString formalName = t->getName();
407
398
            QString typeName = t->getTypeName();
408
399
            cpp << typeName << " " << formalName;
409
 
            if ((t = template_params.next()) != NULL)
 
400
            if ( tlit.hasNext() ) {
 
401
                t = tlit.next();
410
402
                cpp << ", ";
 
403
            }
411
404
        }
412
405
        cpp << ">" << m_endl;
413
406
    }
414
407
 
415
 
    cpp << "class " << m_classifierInfo->className;
416
 
    if (m_classifierInfo->superclasses.count() > 0)
 
408
    cpp << "class " << className_;
 
409
    uint numOfSuperClasses = c->getSuperClasses().count();
 
410
    if (numOfSuperClasses > 0)
417
411
        cpp << " : ";
418
 
    uint numOfSuperClasses = m_classifierInfo->superclasses.count();
419
412
    uint i = 0;
420
 
    for (UMLClassifier *superClass = m_classifierInfo->superclasses.first();
421
 
            superClass ; superClass = m_classifierInfo->superclasses.next())
422
 
    {
 
413
    foreach (UMLClassifier* superClass, c->getSuperClasses()) {
423
414
        i++;
424
415
        if (superClass->getAbstract() || superClass->isInterface())
425
416
            cpp << "virtual ";
430
421
 
431
422
    cpp << m_endl << "{" << m_endl; // begin the body of the class
432
423
 
433
 
 
434
 
    //declarations of operations
435
 
    //
436
 
 
437
424
    //
438
425
    // write out field and operations decl grouped by visibility
439
426
    //
441
428
    // PUBLIC attribs/methods
442
429
    cpp << "public:" << m_endl << m_endl; // print visibility decl.
443
430
    // for public: constructors are first ops we print out
444
 
    if(!m_classifierInfo->isInterface)
 
431
    if (!c->isInterface())
445
432
        writeConstructorDecls(cpp);
446
433
    writeHeaderFieldDecl(c,Uml::Visibility::Public, cpp);
447
434
    writeHeaderAccessorMethodDecl(c, Uml::Visibility::Public, cpp);
460
447
    writeHeaderFieldDecl(c,Uml::Visibility::Private, cpp);
461
448
    writeHeaderAccessorMethodDecl(c, Uml::Visibility::Private, cpp);
462
449
    writeOperations(c,true,Uml::Visibility::Private,cpp);
463
 
    writeInitAttibuteDecl(cpp); // this is always private, used by constructors to initialize class
 
450
    writeInitAttributeDecl(c, cpp); // this is always private, used by constructors to initialize class
464
451
 
465
452
    // end of class header
466
453
    cpp << m_endl << "};" << m_endl;
471
458
 
472
459
}
473
460
 
474
 
void CppWriter::writeAttributeDecls (Uml::Visibility visibility, bool writeStatic, QTextStream &stream )
 
461
void CppWriter::writeAttributeDecls (UMLClassifier *c, Uml::Visibility visibility, bool writeStatic, QTextStream &stream )
475
462
{
476
 
 
477
 
    if(m_classifierInfo->isInterface)
 
463
    if (c->isInterface())
478
464
        return;
479
465
 
480
 
    UMLAttributeList * list;
481
 
    switch (visibility)
482
 
    {
483
 
      case Uml::Visibility::Private:
484
 
        if(writeStatic)
485
 
            list = &(m_classifierInfo->static_atpriv);
486
 
        else
487
 
            list = &(m_classifierInfo->atpriv);
488
 
        break;
489
 
 
490
 
      case Uml::Visibility::Protected:
491
 
        if(writeStatic)
492
 
            list = &(m_classifierInfo->static_atprot);
493
 
        else
494
 
            list = &(m_classifierInfo->atprot);
495
 
        break;
496
 
 
497
 
      case Uml::Visibility::Public:
498
 
    default:
499
 
        if(writeStatic)
500
 
            list = &(m_classifierInfo->static_atpub);
501
 
        else
502
 
            list = &(m_classifierInfo->atpub);
503
 
        break;
504
 
    }
 
466
    UMLAttributeList list;
 
467
    if (writeStatic)
 
468
        list = c->getAttributeListStatic(visibility);
 
469
    else
 
470
        list = c->getAttributeList(visibility);
505
471
 
506
472
    //write documentation
507
 
    if(forceDoc() || list->count() > 0)
 
473
    if (forceDoc() || list.count() > 0)
508
474
    {
509
475
        QString strVis = Codegen_Utils::capitalizeFirstLetter(visibility.toString());
510
476
        QString strStatic = writeStatic ? "Static ":"";
513
479
        writeBlankLine(stream);
514
480
    }
515
481
 
516
 
    if (list->count() > 0) {
 
482
    if (list.count() > 0) {
517
483
 
518
484
        // write attrib declarations now
519
485
        bool isFirstAttrib = true;
520
486
        QString documentation;
521
 
        for(UMLAttribute *at=list->first(); at; at=list->next())
522
 
        {
 
487
        foreach (UMLAttribute* at, list ) {
523
488
 
524
489
            //                  bool noPriorDocExists = documentation.isEmpty();
525
490
            documentation = at->getDoc();
542
507
        }
543
508
 
544
509
        /*
545
 
                        if(list->count() > 0)
546
 
                                writeBlankLine(stream);
 
510
        if(list.count() > 0)
 
511
            writeBlankLine(stream);
547
512
        */
548
 
 
549
513
    }
550
 
 
551
514
}
552
515
 
553
 
void CppWriter::writeHeaderAttributeAccessorMethods (Uml::Visibility visibility, bool writeStatic, QTextStream &stream )
 
516
void CppWriter::writeHeaderAttributeAccessorMethods (UMLClassifier *c, Uml::Visibility visibility, bool writeStatic, QTextStream &stream )
554
517
{
555
518
    // check the current policy about generate accessors as public
556
 
    UMLAttributeList * list;
557
 
    switch (visibility)
558
 
    {
559
 
      case Uml::Visibility::Private:
560
 
        if(writeStatic)
561
 
            list = &(m_classifierInfo->static_atpriv);
562
 
        else
563
 
            list = &(m_classifierInfo->atpriv);
564
 
        break;
565
 
 
566
 
      case Uml::Visibility::Protected:
567
 
        if(writeStatic)
568
 
            list = &(m_classifierInfo->static_atprot);
569
 
        else
570
 
            list = &(m_classifierInfo->atprot);
571
 
        break;
572
 
 
573
 
      case Uml::Visibility::Public:
574
 
    default:
575
 
        if(writeStatic)
576
 
            list = &(m_classifierInfo->static_atpub);
577
 
        else
578
 
            list = &(m_classifierInfo->atpub);
579
 
        break;
580
 
    }
 
519
    UMLAttributeList list;
 
520
    if (writeStatic)
 
521
        list = c->getAttributeListStatic(visibility);
 
522
    else
 
523
        list = c->getAttributeList(visibility);
581
524
 
582
525
    // switch to public
583
526
    if (visibility != Uml::Visibility::Public)
593
536
 
594
537
// this is for writing *source* or *header* file attribute methods
595
538
//
596
 
void CppWriter::writeAttributeMethods(UMLAttributeList *attribs,
 
539
void CppWriter::writeAttributeMethods(UMLAttributeList attribs,
597
540
                                      Uml::Visibility visibility, bool isHeaderMethod,
598
541
                                      bool isStatic,
599
542
                                      bool writeMethodBody, QTextStream &stream)
600
543
{
601
 
 
602
544
    if (!policyExt()->getAutoGenerateAccessors())
603
545
        return;
604
546
 
605
 
    if (forceDoc() || attribs->count() > 0)
 
547
    if (forceDoc() || attribs.count() > 0)
606
548
    {
607
549
        QString strVis = Codegen_Utils::capitalizeFirstLetter(visibility.toString());
608
550
        QString strStatic = (isStatic ? " static" : "");
613
555
    }
614
556
 
615
557
    // return now if NO attributes to work on
616
 
    if (attribs->count() == 0)
 
558
    if (attribs.count() == 0)
617
559
        return;
618
560
 
619
 
    UMLAttribute *at;
620
 
    for(at=attribs->first(); at; at=attribs->next())
621
 
    {
622
 
 
 
561
    foreach (UMLAttribute* at, attribs ) {
623
562
        QString varName = getAttributeVariableName(at);
624
563
        QString methodBaseName = cleanName(at->getName());
625
564
 
626
565
        // force capitalizing the field name, this is silly,
627
566
        // from what I can tell, this IS the default behavior for
628
567
        // cleanName. I dunno why its not working -b.t.
629
 
        methodBaseName = methodBaseName.stripWhiteSpace();
630
 
        methodBaseName.replace(0,1,methodBaseName.at(0).upper());
 
568
        methodBaseName = methodBaseName.trimmed();
 
569
        methodBaseName.replace(0,1,methodBaseName.at(0).toUpper());
631
570
 
632
571
        writeSingleAttributeAccessorMethods(at->getTypeName(), varName,
633
572
                                            methodBaseName, at->getDoc(), Uml::chg_Changeable, isHeaderMethod,
634
573
                                            at->getStatic(), writeMethodBody, stream);
635
574
    }
636
 
 
637
575
}
638
576
 
639
577
void CppWriter::writeComment(const QString &comment, const QString &myIndent, QTextStream &cpp)
643
581
    // need to resolve for using with MAC/WinDoze eventually I assume
644
582
    if (comment.contains(QRegExp("\n"))) {
645
583
 
646
 
        QStringList lines = QStringList::split( "\n", comment);
647
 
        for(uint i= 0; i < lines.count(); i++)
 
584
        QStringList lines = comment.split( "\n" );
 
585
        for (int i= 0; i < lines.count(); i++)
648
586
        {
649
587
            cpp << myIndent << "// " << lines[i] << m_endl;
650
588
        }
667
605
        cpp << formatDoc(body, indent + " * ");
668
606
    if (!end.isEmpty())
669
607
    {
670
 
        QStringList lines = QStringList::split( "\n", end);
671
 
        for(uint i= 0; i < lines.count(); i++)
 
608
        QStringList lines = end.split( "\n" );
 
609
        for (int i= 0; i < lines.count(); i++)
672
610
            cpp << formatDoc(lines[i], indent + " * ");
673
611
    }
674
612
    cpp << indent << " */" << m_endl;
676
614
 
677
615
void CppWriter::writeAssociationDecls(UMLAssociationList associations, Uml::Visibility permitScope, Uml::IDType id, QTextStream &h)
678
616
{
679
 
 
680
617
    if( forceSections() || !associations.isEmpty() )
681
618
    {
682
619
        bool printRoleA = false, printRoleB = false;
683
 
        for(UMLAssociation *a = associations.first(); a; a = associations.next())
 
620
        foreach (UMLAssociation *a , associations )
684
621
        {
685
 
 
686
622
            // it may seem counter intuitive, but you want to insert the role of the
687
623
            // *other* class into *this* class.
688
624
            if (a->getObjectId(Uml::A) == id && !a->getRoleName(Uml::B).isEmpty())
736
672
    // declare the association based on whether it is this a single variable
737
673
    // or a List (Vector). One day this will be done correctly with special
738
674
    // multiplicity object that we don't have to figure out what it means via regex.
739
 
    if(multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
 
675
    if (multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
740
676
    {
741
 
        QString fieldVarName = "m_" + roleName.lower();
 
677
        QString fieldVarName = "m_" + roleName.toLower();
742
678
 
743
679
        // record this for later consideration of initialization IF the
744
680
        // multi value requires 1 of these objects
745
 
        if(ObjectFieldVariables.findIndex(fieldVarName) == -1 &&
746
 
                multi.contains(QRegExp("^1$"))
747
 
          )
 
681
        if (ObjectFieldVariables.indexOf(fieldVarName) == -1 &&
 
682
                multi.contains(QRegExp("^1$")))
748
683
        {
749
684
            // ugh. UGLY. Storing variable name and its class in pairs.
750
685
            ObjectFieldVariables.append(fieldVarName);
755
690
    }
756
691
    else
757
692
    {
758
 
        QString fieldVarName = "m_" + roleName.lower() + "Vector";
 
693
        QString fieldVarName = "m_" + roleName.toLower() + "Vector";
759
694
 
760
695
        // record unique occurrences for later when we want to check
761
696
        // for initialization of this vector
762
 
        if(VectorFieldVariables.findIndex(fieldVarName) == -1)
 
697
        if (VectorFieldVariables.indexOf(fieldVarName) == -1)
763
698
            VectorFieldVariables.append(fieldVarName);
764
699
 
765
700
        stream << indent << policyExt()->getVectorClassName() <<"<" << fieldClassName << "*";
775
710
        bool writePointerVar,
776
711
        Uml::IDType myID, QTextStream &stream)
777
712
{
778
 
    if( forceSections() || !associations.isEmpty() )
 
713
    if ( forceSections() || !associations.isEmpty() )
779
714
    {
780
 
        for(UMLAssociation *a = associations.first(); a; a = associations.next())
 
715
        foreach (UMLAssociation *a , associations )
781
716
        {
782
717
 
783
718
            // insert the methods to access the role of the other
785
720
            if (a->getObjectId(Uml::A) == myID && a->getVisibility(Uml::B) == permitVisib)
786
721
            {
787
722
                // only write out IF there is a rolename given
788
 
                if(!a->getRoleName(Uml::B).isEmpty()) {
 
723
                if (!a->getRoleName(Uml::B).isEmpty()) {
789
724
                    QString fieldClassName = getUMLObjectName(a->getObject(Uml::B)) + (writePointerVar ? " *":"");
790
725
                    writeAssociationRoleMethod(fieldClassName,
791
726
                                               isHeaderMethod,
799
734
            if (a->getObjectId(Uml::B) == myID && a->getVisibility(Uml::A) == permitVisib)
800
735
            {
801
736
                // only write out IF there is a rolename given
802
 
                if(!a->getRoleName(Uml::A).isEmpty()) {
 
737
                if (!a->getRoleName(Uml::A).isEmpty()) {
803
738
                    QString fieldClassName = getUMLObjectName(a->getObject(Uml::A)) + (writePointerVar ? " *":"");
804
739
                    writeAssociationRoleMethod(fieldClassName,
805
740
                                               isHeaderMethod,
823
758
        const QString &description, Uml::Changeability_Type change,
824
759
        QTextStream &stream)
825
760
{
826
 
    if(multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
 
761
    if (multi.isEmpty() || multi.contains(QRegExp("^[01]$")))
827
762
    {
828
 
        QString fieldVarName = "m_" + roleName.lower();
 
763
        QString fieldVarName = "m_" + roleName.toLower();
829
764
        writeSingleAttributeAccessorMethods(fieldClassName, fieldVarName, roleName,
830
765
                                            description, change, isHeaderMethod, false, writeMethodBody, stream);
831
766
    }
832
767
    else
833
768
    {
834
 
        QString fieldVarName = "m_" + roleName.lower() + "Vector";
 
769
        QString fieldVarName = "m_" + roleName.toLower() + "Vector";
835
770
        writeVectorAttributeAccessorMethods(fieldClassName, fieldVarName, roleName,
836
771
                                            description, change, isHeaderMethod, writeMethodBody, stream);
837
772
    }
845
780
        bool writeMethodBody,
846
781
        QTextStream &stream)
847
782
{
848
 
 
849
783
    QString className = fixTypeName(fieldClassName);
850
784
    QString fldName = Codegen_Utils::capitalizeFirstLetter(fieldName);
851
785
    QString indent = getIndent();
856
790
        writeDocumentation("Add a " + fldName + " object to the " + fieldVarName + " List",description,"",stream);
857
791
        stream << indent << "void ";
858
792
        if(!isHeaderMethod)
859
 
            stream << m_classifierInfo->className << "::";
 
793
            stream << className_ << "::";
860
794
        stream << "add" << fldName << " ( " << className << " add_object )";
861
795
        if (writeMethodBody) {
862
796
            QString method = VECTOR_METHOD_APPEND;
879
813
                           description, "", stream);
880
814
        stream << indent << "void ";
881
815
        if(!isHeaderMethod)
882
 
            stream << m_classifierInfo->className << "::";
 
816
            stream << className_ << "::";
883
817
        stream << "remove" << fldName << " ( " << className << " remove_object )";
884
818
        if (writeMethodBody) {
885
819
            QString method = VECTOR_METHOD_REMOVE;
903
837
                       stream);
904
838
    stream << indent << returnVarName << " ";
905
839
    if(!isHeaderMethod)
906
 
        stream << m_classifierInfo->className << "::";
 
840
        stream << className_ << "::";
907
841
    stream << "get" << fldName << "List ( )";
908
842
    if(writeMethodBody) {
909
843
        stream << indent << " {" << m_endl;
916
850
 
917
851
}
918
852
 
919
 
 
920
853
void CppWriter::writeSingleAttributeAccessorMethods(
921
854
        const QString& fieldClassName, const QString& fieldVarName,
922
855
        const QString& fieldName, const QString &description,
926
859
        bool writeMethodBody,
927
860
        QTextStream &stream)
928
861
{
929
 
 
930
862
    // DON'T write this IF its a source method AND writeMethodBody is "false"
931
 
    if(!isHeaderMethod && !writeMethodBody)
 
863
    if (!isHeaderMethod && !writeMethodBody)
932
864
        return;
933
865
 
934
866
    QString className = fixTypeName(fieldClassName);
940
872
        writeDocumentation("Set the value of " + fieldVarName,description,"@param new_var the new value of " + fieldVarName,stream);
941
873
        stream << indent << "void ";
942
874
        if(!isHeaderMethod)
943
 
            stream << m_classifierInfo->className << "::";
 
875
            stream << className_ << "::";
944
876
        stream << "set" << fldName << " ( " << className << " new_var )";
945
877
 
946
 
        if(writeMethodBody) {
 
878
        if (writeMethodBody) {
947
879
            stream << indent << " {" << m_endl;
948
880
            m_indentLevel++;
949
881
            stream << getIndent() << indent;
950
882
            m_indentLevel--;
951
 
            if(isStatic)
952
 
                stream << m_classifierInfo->className << "::";
 
883
            if (isStatic)
 
884
                stream << className_ << "::";
953
885
            stream << fieldVarName << " = new_var;" << m_endl;
954
886
            stream << indent << "}" << m_endl;
955
887
        } else
959
891
    // get method
960
892
    writeDocumentation("Get the value of " + fieldVarName,description,"@return the value of " + fieldVarName,stream);
961
893
    stream << indent << className << " ";
962
 
    if(!isHeaderMethod)
963
 
        stream << m_classifierInfo->className << "::";
 
894
    if (!isHeaderMethod)
 
895
        stream << className_ << "::";
964
896
    stream << "get" << fldName << " ( )";
965
897
 
966
 
    if(writeMethodBody) {
 
898
    if (writeMethodBody) {
967
899
        stream << indent << " {" << m_endl;
968
900
        m_indentLevel++;
969
901
        stream << getIndent() << "return ";
970
902
        m_indentLevel--;
971
 
        if(isStatic)
972
 
            stream << m_classifierInfo->className << "::";
 
903
        if (isStatic)
 
904
            stream << className_ << "::";
973
905
        stream << fieldVarName << ";" << m_endl;
974
906
        stream << indent << "}";
975
907
    } else
993
925
        return;
994
926
 
995
927
    writeDocumentation("", "Empty Constructor", "", stream);
996
 
    stream << getIndent() << m_classifierInfo->className << " ( );" << m_endl;
 
928
    stream << getIndent() << className_ << " ( );" << m_endl;
997
929
    writeDocumentation("", "Empty Destructor", "", stream);
998
930
    stream << getIndent();
999
 
    stream << "virtual ~" << m_classifierInfo->className << " ( );" << m_endl;
 
931
    stream << "virtual ~" << className_ << " ( );" << m_endl;
1000
932
    writeBlankLine(stream);
1001
933
}
1002
934
 
1003
 
void CppWriter::writeInitAttibuteDecl (QTextStream &stream)
 
935
void CppWriter::writeInitAttributeDecl(UMLClassifier * c, QTextStream &stream)
1004
936
{
1005
937
    if (UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors() &&
1006
 
        m_classifierInfo->hasAttributes)
 
938
        c->hasAttributes())
1007
939
        stream << getIndent() << "void initAttributes ( ) ;" << m_endl;
1008
940
}
1009
941
 
1010
 
void CppWriter::writeInitAttibuteMethod (QTextStream &stream)
 
942
void CppWriter::writeInitAttributeMethod(UMLClassifier * c, QTextStream &stream)
1011
943
{
1012
944
    // only need to do this under certain conditions
1013
945
    if (!UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors() ||
1014
 
        !m_classifierInfo->hasAttributes)
 
946
        !c->hasAttributes())
1015
947
        return;
1016
948
 
1017
 
    QString className = m_classifierInfo->className;
1018
949
    QString indent = getIndent();
1019
950
 
1020
 
    stream << indent << "void " << className << "::" << "initAttributes ( ) {" << m_endl;
 
951
    stream << indent << "void " << className_ << "::" << "initAttributes ( ) {" << m_endl;
1021
952
 
1022
953
    m_indentLevel++;
1023
954
    // first, initiation of fields derived from attributes
1024
 
    UMLAttributeList atl = m_classifierInfo->getAttList();
1025
 
    for(UMLAttribute *at = atl.first(); at ; at = atl.next()) {
 
955
    UMLAttributeList atl = c->getAttributeList();
 
956
    foreach (UMLAttribute* at, atl ) {
1026
957
        if(!at->getInitialValue().isEmpty()) {
1027
958
            QString varName = getAttributeVariableName(at);
1028
959
            stream << getIndent() << varName << " = " << at->getInitialValue() << ";" << m_endl;
1063
994
}
1064
995
 
1065
996
// one day, this should print out non-empty constructor operations too.
1066
 
void CppWriter::writeConstructorMethods(QTextStream &stream)
 
997
void CppWriter::writeConstructorMethods(UMLClassifier * c, QTextStream &stream)
1067
998
{
1068
999
    const bool generateEmptyConstructors =
1069
1000
        UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors();
1076
1007
    if (!generateEmptyConstructors)
1077
1008
        return;
1078
1009
 
1079
 
    QString className = m_classifierInfo->className;
1080
1010
    // empty constructor
1081
1011
    QString indent = getIndent();
1082
 
    stream << indent << className << "::" << className << " ( ) {" << m_endl;
1083
 
    if(m_classifierInfo->hasAttributes)
 
1012
    stream << indent << className_ << "::" << className_ << " ( ) {" << m_endl;
 
1013
    if(c->hasAttributes())
1084
1014
        stream << indent << indent << "initAttributes();" << m_endl;
1085
1015
    stream << indent << "}" << m_endl;
1086
1016
    writeBlankLine(stream);
1087
1017
 
1088
1018
    // empty destructor
1089
 
    stream << getIndent() << className << "::~" << className << " ( ) { }" << m_endl;
 
1019
    stream << getIndent() << className_ << "::~" << className_ << " ( ) { }" << m_endl;
1090
1020
    writeBlankLine(stream);
1091
1021
}
1092
1022
 
1093
 
// IF the type is "string" we need to declare it as
1094
 
// the Java Object "String" (there is no string primative in Java).
1095
1023
QString CppWriter::fixTypeName(const QString &string)
1096
1024
{
1097
1025
    if (string.isEmpty())
1102
1030
}
1103
1031
 
1104
1032
void CppWriter::writeOperations(UMLClassifier *c, bool isHeaderMethod,
1105
 
                                Uml::Visibility permitScope, QTextStream &cpp) {
1106
 
 
 
1033
                                Uml::Visibility permitScope, QTextStream &cpp)
 
1034
{
1107
1035
    UMLOperationList oplist;
1108
1036
 
1109
1037
    //sort operations by scope first and see if there are abstract methods
1110
1038
    UMLOperationList inputlist = c->getOpList();
1111
 
    for (UMLOperation *op = inputlist.first(); op; op = inputlist.next()) {
 
1039
    foreach (UMLOperation* op, inputlist ) {
1112
1040
        if (op->getVisibility() == permitScope) {
1113
1041
            oplist.append(op);
1114
1042
        }
1122
1050
        writeBlankLine(cpp);
1123
1051
      }
1124
1052
    */
1125
 
    writeOperations(oplist,isHeaderMethod, cpp);
1126
 
 
 
1053
    writeOperations(c, oplist, isHeaderMethod, cpp);
1127
1054
}
1128
1055
 
1129
 
// write operation in either header or
1130
 
// a source file
1131
 
void CppWriter::writeOperations(UMLOperationList &oplist, bool isHeaderMethod, QTextStream &cpp) {
1132
 
    QString className = m_classifierInfo->className;
 
1056
// write operation in either header or source file
 
1057
void CppWriter::writeOperations(UMLClassifier *c, UMLOperationList &oplist, bool isHeaderMethod, QTextStream &cpp)
 
1058
{
1133
1059
    const bool generateEmptyConstructors =
1134
1060
        UMLApp::app()->getCommonPolicy()->getAutoGenerateConstructors();
1135
1061
 
1136
1062
    // generate method decl for each operation given
1137
 
    for (UMLOperation *op = oplist.first(); op; op = oplist.next()) {
1138
 
 
1139
 
        QString returnStr;  // buffer for documentation
 
1063
    foreach (UMLOperation* op, oplist  ) {
 
1064
        QString doc;  // buffer for documentation
1140
1065
        QString methodReturnType;
1141
1066
        UMLAttributeList atl = op->getParmList();  // method parameters
1142
1067
 
1149
1074
        } else {
1150
1075
            methodReturnType = fixTypeName(op->getTypeName());
1151
1076
            if(methodReturnType != "void")
1152
 
                returnStr += "@return " + methodReturnType + '\n';
 
1077
                doc += "@return " + methodReturnType + '\n';
1153
1078
        }
1154
1079
 
1155
1080
        QString str;
1156
 
        if (op->getAbstract() || m_classifierInfo->isInterface) {
 
1081
        if (op->getAbstract() || c->isInterface()) {
1157
1082
            if (isHeaderMethod) {
1158
1083
                // declare abstract method as 'virtual'
1159
1084
                str += "virtual ";
1168
1093
        str += methodReturnType + ' ';
1169
1094
 
1170
1095
        if (!isHeaderMethod)
1171
 
            str += className + "::";
 
1096
            str += className_ + "::";
1172
1097
 
1173
1098
        str += cleanName(op->getName()) + " (";
1174
1099
 
1175
1100
        // generate parameters
1176
1101
        uint j = 0;
1177
 
        for (UMLAttribute *at = atl.first(); at; at = atl.next(), j++) {
 
1102
        for (UMLAttributeListIt atlIt( atl ); atlIt.hasNext() ; j++) {
 
1103
            UMLAttribute* at = atlIt.next();
1178
1104
            QString typeName = fixTypeName(at->getTypeName());
1179
1105
            QString atName = cleanName(at->getName());
1180
1106
            str += typeName + ' ' + atName;
1181
1107
            const QString initVal = at->getInitialValue();
1182
1108
            if (! initVal.isEmpty())
1183
1109
                str += " = " + initVal;
1184
 
            if (j < atl.count() - 1)
 
1110
            if (j < ( uint )( atl.count() - 1 ))
1185
1111
                str += ", ";
1186
 
            returnStr += "@param  " + atName + ' ' + at->getDoc() + '\n';
 
1112
            doc += "@param  " + atName + ' ' + at->getDoc() + m_endl;
1187
1113
        }
 
1114
        doc = doc.remove(doc.size() - 1, 1);  // remove last endl of comment
1188
1115
        str += " )";
1189
1116
 
1190
1117
        if (op->getConst())
1191
1118
            str += " const";
1192
1119
 
1193
1120
        // method body : only gets IF its not in a header
1194
 
        if (isHeaderMethod && !policyExt()->getOperationsAreInline())
 
1121
        if (isHeaderMethod && !policyExt()->getOperationsAreInline()) {
1195
1122
            str += ';'; // terminate now
1196
 
        else
1197
 
            str +=getIndent() + " {\n\n" + getIndent() + '}'; // empty method body
 
1123
        }
 
1124
        else {
 
1125
            str += m_endl + getIndent() + '{' + m_endl;
 
1126
            QString sourceCode = op->getSourceCode();
 
1127
            if (sourceCode.isEmpty()) {
 
1128
                // empty method body - TODO: throw exception
 
1129
            }
 
1130
            else {
 
1131
                str += formatSourceCode(sourceCode, getIndent() + getIndent());
 
1132
            }
 
1133
            str += getIndent() + '}';
 
1134
        }
1198
1135
 
1199
1136
        // write it out
1200
 
        writeDocumentation("", op->getDoc(), returnStr, cpp);
 
1137
        writeDocumentation("", op->getDoc(), doc, cpp);
1201
1138
        cpp << getIndent() << str << m_endl;
1202
1139
        writeBlankLine(cpp);
1203
1140
    }
1210
1147
void CppWriter::printAssociationIncludeDecl (UMLAssociationList list, Uml::IDType myId, QTextStream &stream)
1211
1148
{
1212
1149
 
1213
 
    for (UMLAssociation *a = list.first(); a; a = list.next()) {
 
1150
    foreach (UMLAssociation *a , list ) {
1214
1151
        UMLClassifier *current = NULL;
1215
1152
        bool isFirstClass = true;
1216
1153
 
1225
1162
 
1226
1163
        // as header doc for this method indicates, we need to be a bit sophisticated on
1227
1164
        // how to declare some associations.
1228
 
        if( current )
 
1165
        if (current) {
1229
1166
            if( !isFirstClass && !a->getRoleName(Uml::A).isEmpty() && !a->getRoleName(Uml::B).isEmpty())
1230
1167
                stream << "class " << current->getName() << ";" << m_endl; // special case: use forward declaration
1231
1168
            else
1232
1169
                stream << "#include \"" << current->getName() << ".h\"" << m_endl; // just the include statement
 
1170
        }
1233
1171
    }
1234
1172
}
1235
1173
 
1238
1176
    QString val = value;
1239
1177
    // check for strings only
1240
1178
    if (!val.isEmpty() && type == policyExt()->getStringClassName()) {
1241
 
        if (!val.startsWith("\""))
1242
 
            val.prepend("\"");
1243
 
        if (!val.endsWith("\""))
1244
 
            val.append("\"");
 
1179
        if (!val.startsWith('"'))
 
1180
            val.prepend('"');
 
1181
        if (!val.endsWith('"'))
 
1182
            val.append('"');
1245
1183
    }
1246
1184
    return val;
1247
1185
}
1262
1200
    if(text.isEmpty())
1263
1201
        return;
1264
1202
 
1265
 
    QStringList lines = QStringList::split( "\n", text);
1266
 
    for(uint i= 0; i < lines.count(); i++)
 
1203
    QStringList lines = text.split( "\n" );
 
1204
    for (int i= 0; i < lines.count(); i++)
1267
1205
        stream << indent << lines[i] << m_endl;
1268
1206
}
1269
1207
 
1270
1208
QString CppWriter::getAttributeVariableName (UMLAttribute *at)
1271
1209
{
1272
 
    QString fieldName = "m_" + cleanName(at->getName());
 
1210
    QString fieldName = cleanName(at->getName());
1273
1211
    return fieldName;
1274
1212
}
1275
1213
 
1276
 
QStringList CppWriter::defaultDatatypes() {
 
1214
QStringList CppWriter::defaultDatatypes()
 
1215
{
1277
1216
    return Codegen_Utils::cppDatatypes();
1278
1217
}
1279
1218
 
1280
 
const QStringList CppWriter::reservedKeywords() const {
 
1219
const QStringList CppWriter::reservedKeywords() const
 
1220
{
1281
1221
    return Codegen_Utils::reservedCppKeywords();
1282
1222
}
1283
1223