[Uml-devel] code generation changes

Paulo Sehn paulo.sehn at gmail.com
Sun Jul 17 22:03:05 UTC 2005


I'm posting some changes I've done in umbrello to increase the
coverage of cpp code generation, this changes are not to be sent to
subversion yet, I've just wold like to receive comments about this.

Changes:
======
1) assign void to operations that don't have return type and aren't
constructors/destructors
2) removal of the generate makefile entry in the cpp code generation
wizard - code generation options dialog - language options tab. It was
not working.
3) changes in the xmi file generation in order to remove the entries
for native data types. Just to see what I'm talking about: open
umbrello, set the language to cpp, save the empty file, open the xmi
file and search for fileName. You'll see things like int, float, and
so. I don't think we should have ,h/.cpp entries for native types. So,
I've removed this and the makefile entry too.
4) I've changed the the cpp code generation wizard - code generation
options dialog to manage the options generate accessors, accessors are
inline and operations are inline.
5) I've changed the umloperationdialog changing the stereotype editbox
for a stereotype combobox, this combo is filled with stereotypes
generated by the codegenerator (i.e. cppcodegenerator) plus the
stereotypes the user had defined.
6) I've defined the friend, virtual and constructor stereotypes to the
cpp language
7) I've changed the cppcodegenerator to handle these stereotypes, now
we can create friend operations, we can identify constructors, and we
can generate virtual operations that aren't abstract.
8) I've changed the cpp code import classes to identify constructors
and friend operations.

I would like to get a feedback about these changes and to know if I
have broken somethingelse :)

Here is the patch :

Index: umbrello/umbrello/codegenerators/cppcodegenerationpolicy.cpp
===================================================================
--- umbrello/umbrello/codegenerators/cppcodegenerationpolicy.cpp	(revision
435760)
+++ umbrello/umbrello/codegenerators/cppcodegenerationpolicy.cpp	(working copy)
@@ -302,11 +302,6 @@
     config->writeEntry("autoGenEmptyConstructors",getAutoGenerateConstructors());
     config->writeEntry("autoGenAccessors",getAutoGenerateAccessors());
 
-    CodeGenerator *codegen = UMLApp::app()->getGenerator();
-    CPPCodeGenerator *cppcodegen = dynamic_cast<CPPCodeGenerator*>(codegen);
-    if (cppcodegen)
-        config->writeEntry("buildMakefile",
cppcodegen->getCreateProjectMakefile());
-
     config->writeEntry("inlineAccessors",getAccessorsAreInline());
     config->writeEntry("inlineOps",getOperationsAreInline());
     config->writeEntry("virtualDestructors",getDestructorsAreVirtual());
@@ -388,13 +383,6 @@
     setAutoGenerateConstructors(config->readBoolEntry("autoGenEmptyConstructors",DEFAULT_AUTO_GEN_EMPTY_CONSTRUCTORS));
     setAutoGenerateAccessors(config->readBoolEntry("autoGenAccessors",DEFAULT_AUTO_GEN_ACCESSORS));
 
-    CodeGenerator *codegen = UMLApp::app()->getGenerator();
-    CPPCodeGenerator *cppcodegen = dynamic_cast<CPPCodeGenerator*>(codegen);
-    if (cppcodegen) {
-        bool mkmf = config->readBoolEntry("buildMakefile",
CPPCodeGenerator::DEFAULT_BUILD_MAKEFILE);
-        cppcodegen->setCreateProjectMakefile(mkmf);
-    }
-
     setAccessorsAreInline(config->readBoolEntry("inlineAccessors",DEFAULT_INLINE_ACCESSORS));
     setOperationsAreInline(config->readBoolEntry("inlineOps",DEFAULT_INLINE_OPERATIONS));
     setDestructorsAreVirtual(config->readBoolEntry("virtualDestructors",DEFAULT_VIRTUAL_DESTRUCTORS));
Index: umbrello/umbrello/codegenerators/codegen_utils.cpp
===================================================================
--- umbrello/umbrello/codegenerators/codegen_utils.cpp	(revision 435760)
+++ umbrello/umbrello/codegenerators/codegen_utils.cpp	(working copy)
@@ -390,5 +390,14 @@
     return keywords;
 }
 
+void createCppStereotypes(){
+    UMLDoc *umldoc = UMLApp::app()->getDocument();
+    umldoc->findOrCreateStereotype("constructor");
+    // declares an operation as friend
+    umldoc->findOrCreateStereotype("friend");
+    // to use in methods that aren't abstract
+    umldoc->findOrCreateStereotype("virtual");
+}
+
 }  // end namespace Umbrello
 
Index: umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp
===================================================================
--- umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp	(revision
435760)
+++ umbrello/umbrello/codegenerators/cppsourcecodeoperation.cpp	(working copy)
@@ -18,6 +18,7 @@
 #include "cppcodegenerator.h"
 #include "cppsourcecodedocument.h"
 #include "cppcodedocumentation.h"
+#include <klocale.h>
 
 // Constructors/Destructors
 //
@@ -84,7 +85,21 @@
             paramStr  += ", ";
     }
 
-    QString startText = returnType + " " + className + "::" +
methodName + " ("+paramStr+") {";
+    // if an operation isn't a constructor/destructor and it has no return type
+    // this operation should be  void
+    if (returnType.isEmpty() && !o->isConstructorOperation() &&
(methodName.find(i18n("~")) == -1))
+        returnType = QString("void");
+    // check for destructor, desctructor has no type
+    if (methodName.find("~") != -1)
+        returnType = "";
+
+    // if a property has a friend stereotype, the operation should
+    // not be a class name
+    QString startText;
+    if (!o->getStereotype(false).isEmpty() && o->getStereotype(false)
== "friend")
+        startText = returnType + " " + methodName + " ("+paramStr+") {";
+    else
+        startText = returnType + " " + className + "::" + methodName
+ " ("+paramStr+") {";
     setStartMethodText(startText);
 
     // Only write this out if its a child of an interface OR is abstract.
Index: umbrello/umbrello/codegenerators/cppcodegenerationform.h
===================================================================
--- umbrello/umbrello/codegenerators/cppcodegenerationform.h	(revision 435760)
+++ umbrello/umbrello/codegenerators/cppcodegenerationform.h	(working copy)
@@ -127,7 +127,6 @@
     QCheckListItem *pOptionGenerateAccessorMethods;
     QCheckListItem *pOptionOperationsAreInline;
     QCheckListItem *pOptionAccessorsAreInline;
-    QCheckListItem *pOptionGenerateMakefileDocument;
 
     /**
      * initialize all attributes
Index: umbrello/umbrello/codegenerators/cppcodegenerator.cpp
===================================================================
--- umbrello/umbrello/codegenerators/cppcodegenerator.cpp	(revision 435760)
+++ umbrello/umbrello/codegenerators/cppcodegenerator.cpp	(working copy)
@@ -335,6 +335,11 @@
     if (!obj)
         return;
 
+    // if the obj being created is a native data type
+    // there's no reason to create a .h/.cpp file
+    if (isReservedKeyword(obj->getName()))
+        return;
+
     UMLClassifier * c = dynamic_cast<UMLClassifier*>(obj);
     if(c) {
         CodeDocument * cDoc = newClassifierCodeDocument(c);
@@ -376,13 +381,6 @@
     // load Classifier documents from parent document
     initFromParentDocument();
 
-    // add in an Make build document
-    CPPMakefileCodeDocument * buildDoc = newMakefileCodeDocument( );
-    addCodeDocument(buildDoc);
-
-    // set our 'writeout' policy for that code document
-    setCreateProjectMakefile(DEFAULT_BUILD_MAKEFILE);
-
 }
 
 void CPPCodeGenerator::createDefaultDatatypes() {
@@ -393,4 +391,8 @@
     return Umbrello::reservedCppKeywords();
 }
 
+void CPPCodeGenerator::createDefaultStereotypes (){
+    Umbrello::createCppStereotypes();
+}
+
 #include "cppcodegenerator.moc"
Index: umbrello/umbrello/codegenerators/codegen_utils.h
===================================================================
--- umbrello/umbrello/codegenerators/codegen_utils.h	(revision 435760)
+++ umbrello/umbrello/codegenerators/codegen_utils.h	(working copy)
@@ -25,6 +25,11 @@
  */
 const QStringList reservedCppKeywords();
 
+/**
+ * Add C++ stereotypes
+ */
+void createCppStereotypes();
+
 }
 
 #endif  // CODEGEN_UTILS_H
Index: umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.cpp
===================================================================
--- umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.cpp	(revision
435760)
+++ umbrello/umbrello/codegenerators/cppcodegenerationpolicypage.cpp	(working
copy)
@@ -37,11 +37,6 @@
     form->setOperationsAreInline(policy->getOperationsAreInline());
     form->setAccessorsAreInline(policy->getAccessorsAreInline());
 
-    CodeGenerator *codegen = UMLApp::app()->getGenerator();
-    CPPCodeGenerator *cppcodegen = dynamic_cast<CPPCodeGenerator*>(codegen);
-    if (cppcodegen)
-        form->setGenerateMakefileDocument(cppcodegen->getCreateProjectMakefile());
-
     form->m_stringClassHCombo->setCurrentItem(policy->getStringClassName(),true);
     form->m_listClassHCombo->setCurrentItem(policy->getVectorClassName(),true);
 
@@ -85,11 +80,6 @@
     parent->setAccessorsAreInline(form->getAccessorsAreInline());
     parent->setOperationsAreInline(form->getOperationsAreInline());
 
-    CodeGenerator *codegen = UMLApp::app()->getGenerator();
-    CPPCodeGenerator *cppcodegen = dynamic_cast<CPPCodeGenerator*>(codegen);
-    if (cppcodegen)
-        cppcodegen->setCreateProjectMakefile(form->getGenerateMakefileDocument());
-
     parent->setStringClassName(form->m_stringClassHCombo->currentText());
     parent->setStringClassNameInclude(form->m_stringIncludeFileHistoryCombo->currentText());
     parent->setStringIncludeIsGlobal(form->m_globalStringCheckBox->isChecked());
Index: umbrello/umbrello/codegenerators/cppheadercodeoperation.h
===================================================================
--- umbrello/umbrello/codegenerators/cppheadercodeoperation.h	(revision 435760)
+++ umbrello/umbrello/codegenerators/cppheadercodeoperation.h	(working copy)
@@ -48,6 +48,11 @@
     virtual void updateMethodDeclaration();
     virtual void updateContent( );
 
+    /**
+     * Check to see if we ahve a valid stereotype to apply in the operation
+     */
+    virtual void applyStereotypes (QString&, UMLOperation *, bool,
bool, QString&, QString&);
+
 private:
     void init (CPPHeaderCodeDocument * doc );
 
Index: umbrello/umbrello/codegenerators/cppcodegenerationform.cpp
===================================================================
--- umbrello/umbrello/codegenerators/cppcodegenerationform.cpp	(revision 435760)
+++ umbrello/umbrello/codegenerators/cppcodegenerationform.cpp	(working copy)
@@ -46,16 +46,12 @@
     pOptionAccessorsAreInline = new QCheckListItem( GeneralOptionsListView,
                                 tr2i18n("Accessors are inline"),
                                 QCheckListItem::CheckBox );
-    pOptionGenerateMakefileDocument = new QCheckListItem(
GeneralOptionsListView,
-                                      tr2i18n("Create Makefile document"),
-                                      QCheckListItem::CheckBox );
 
-#if 0
     connect(GeneralOptionsListView,
             SIGNAL(clicked(QListViewItem *)), this,
             SLOT(generalOptionsListViewClicked(QListViewItem *))
            );
-#endif
+
 }
 
 CPPCodeGenerationForm::~CPPCodeGenerationForm()
@@ -81,6 +77,11 @@
 }
 
 void CPPCodeGenerationForm::generalOptionsListViewClicked(QListViewItem
*pSender) {
+
+    // operations are inline and accessors are operations :)
+    if (pOptionOperationsAreInline->isOn() &&
pOptionGenerateAccessorMethods->isOn())
+            pOptionAccessorsAreInline->setOn(true);
+
     if (pSender == pOptionPackageIsANamespace) {
 #if 0
         KMessageBox::error(0,
"CPPCodeGenerationForm::generalOptionsListViewClicked(): "
@@ -103,6 +104,10 @@
         return;
     }
     if (pSender == pOptionGenerateAccessorMethods) {
+        pOptionAccessorsAreInline->setEnabled(pOptionGenerateAccessorMethods->isOn());
+        // reset the value if needed
+        if (!pOptionGenerateAccessorMethods->isOn())
+            pOptionAccessorsAreInline->setOn(false);
 #if 0
         KMessageBox::error(0,
"CPPCodeGenerationForm::generalOptionsListViewClicked(): "
                            "sender=pOptionGenerateAccessorMethods");
@@ -123,13 +128,6 @@
 #endif
         return;
     }
-    if (pSender == pOptionGenerateMakefileDocument) {
-#if 0
-        KMessageBox::error(0,
"CPPCodeGenerationForm::generalOptionsListViewClicked(): "
-                           "sender=pOptionGenerateMakefileDocument");
-#endif
-        return;
-    }
 
 #if 0
     KMessageBox::error(0,
"CPPCodeGenerationForm::generalOptionsListViewClicked(): "
@@ -145,7 +143,6 @@
     pOptionGenerateAccessorMethods = NULL;
     pOptionOperationsAreInline = NULL;
     pOptionAccessorsAreInline = NULL;
-    pOptionGenerateMakefileDocument = NULL;
 }
 
 /**
@@ -204,15 +201,6 @@
 
 /**
  *
- * set the display state of option "Generate Makefile Document"
- *
- */
-void CPPCodeGenerationForm::setGenerateMakefileDocument(bool bFlag) {
-    pOptionGenerateMakefileDocument->setOn(bFlag);
-}
-
-/**
- *
  * get the display state of option "Package Is Namespace"
  *
  */
@@ -271,15 +259,6 @@
     return pOptionAccessorsAreInline->isOn();
 }
 
-/**
- *
- * get the display state of option "Generate Makefile Document"
- *
- */
-bool CPPCodeGenerationForm::getGenerateMakefileDocument()
-{
-    return pOptionGenerateMakefileDocument->isOn();
-}
 
 
 #include "cppcodegenerationform.moc"
Index: umbrello/umbrello/codegenerators/cppcodegenerator.h
===================================================================
--- umbrello/umbrello/codegenerators/cppcodegenerator.h	(revision 435760)
+++ umbrello/umbrello/codegenerators/cppcodegenerator.h	(working copy)
@@ -143,6 +143,11 @@
      */
     virtual const QStringList reservedKeywords() const;
 
+    /**
+     * Add the default stereotypes for c++ (constructor, int etc)
+     */
+    virtual void createDefaultStereotypes ();
+
 protected:
 
     /**
Index: umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp
===================================================================
--- umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp	(revision
435760)
+++ umbrello/umbrello/codegenerators/cppheadercodeoperation.cpp	(working copy)
@@ -18,6 +18,7 @@
 #include "cppcodegenerator.h"
 #include "cppheadercodedocument.h"
 #include "cppcodedocumentation.h"
+#include <klocale.h>
 
 // Constructors/Destructors
 //
@@ -72,7 +73,7 @@
     }
 
     // no return type for constructors
-    QString methodReturnType = o->isConstructorOperation() ?
QString("") : (o->getTypeName() + QString(" "));
+    QString methodReturnType = o->isConstructorOperation() ?
QString("") : (o->getTypeName() + QString(""));
     QString methodName = o->getName();
     QString paramStr = QString("");
 
@@ -95,21 +96,24 @@
             paramStr  += ", ";
     }
 
+    // if an operation isn't a constructor or a destructor and it has
no return type
+    // this operation should be  void
+    if (methodReturnType.isEmpty() && !o->isConstructorOperation() &&
(methodName.find(i18n("~")) == -1))
+        methodReturnType = QString("void");
+    // check for destructor, desctructor has no type
+    if (methodName.find("~") != -1)
+        methodReturnType = "";
+
     // set start/end method text
-    QString startText = methodReturnType+" "+methodName+" ("+paramStr+")";
+    QString prototype = methodReturnType+" "+methodName+" ("+paramStr+")";
 
-    // write as an abstract operation if explicitly stated OR if
child of interface
-    if((isInterface || o->getAbstract()) && !isInlineMethod)
-        startText = "virtual " + startText + " = 0";
-    else if (o->getStatic())                // prefix with "static" if required
-        startText = "static "  + startText;
-    startText += (isInlineMethod ? " {" : ";");
+    QString startText;
+    QString endText;
 
-    QString endText = (isInlineMethod ? "}" : "");
+    applyStereotypes (prototype, o, isInlineMethod, isInterface,
startText, endText);
 
-    setStartMethodText(startText);
+    setStartMethodText(prototype+startText);
     setEndMethodText(endText);
-
 }
 
 int CPPHeaderCodeOperation::lastEditableLine() {
@@ -132,6 +136,7 @@
     setOverallIndentationLevel(1);
 
     setText("");
+    setStartMethodText("");
     setEndMethodText("");
 
     updateMethodDeclaration();
@@ -139,4 +144,32 @@
 
 }
 
+void CPPHeaderCodeOperation::applyStereotypes (QString& prototype,
UMLOperation * pOp, bool inlinePolicy, bool interface, QString& start,
QString& end)
+{
+    // if the class is an interface, all methods will be declared as pure
+    // virtual functions
+    start = (inlinePolicy ? " {" : ";");
+    end = (inlinePolicy ? "}" : "");
+    if (interface || pOp->getAbstract()) {
+       // constructor can't be virtual or abstract
+       if (!pOp->isConstructorOperation()) {
+           prototype = "virtual " + prototype + " = 0";
+           if (inlinePolicy) {
+               start = ";";
+               end = "";
+           }
+       }
+    } // constructors could not be declared as static
+    else if (pOp->getStatic() && !pOp->isConstructorOperation()) {
+       prototype = "static " + prototype;
+    }
+    // apply the stereotypes
+    if (!pOp->getStereotype(false).isEmpty()) {
+        if ((pOp->getStereotype(false) == "friend") ||
(pOp->getStereotype(false) == "virtual")) {
+            if (!pOp->isConstructorOperation() && !(interface ||
pOp->getAbstract()) && !pOp->getStatic())
+                prototype = pOp->getStereotype(false) + " " + prototype; 
+        }
+    }
+}
+
 #include "cppheadercodeoperation.moc"
Index: umbrello/umbrello/dialogs/umloperationdialog.cpp
===================================================================
--- umbrello/umbrello/dialogs/umloperationdialog.cpp	(revision 435760)
+++ umbrello/umbrello/dialogs/umloperationdialog.cpp	(working copy)
@@ -46,6 +46,7 @@
 #include "../umlclassifierlistitemlist.h"
 #include "../dialog_utils.h"
 #include "parmpropdlg.h"
+#include "../stereotype.h"
 
 UMLOperationDialog::UMLOperationDialog( QWidget * parent,
UMLOperation * pOperation )
         : KDialogBase( Plain, i18n("Operation Properties"), Help | Ok
| Cancel , Ok, parent, "_UMLOPERATIONDLG_", true, true) {
@@ -78,9 +79,10 @@
     genLayout -> addWidget(m_pRtypeCB, 0, 3);
     m_pRtypeL->setBuddy(m_pRtypeCB);
 
-    Umbrello::makeLabeledEditField( m_pGenGB, genLayout, 1,
-                                    m_pStereoTypeL, i18n("Stereotype name:"),
-                                    m_pStereoTypeLE,
m_pOperation->getStereotype(false) );
+    m_pStereoTypeL = new QLabel( i18n("Stereotype name:"), m_pGenGB );
+    genLayout -> addWidget(m_pStereoTypeL, 1, 0);
+    m_pStereoTypeCB = new KComboBox(true, m_pGenGB );
+    genLayout -> addWidget(m_pStereoTypeCB, 1, 1);
 
     m_pAbstractCB = new QCheckBox( i18n("&Abstract operation"), m_pGenGB );
     m_pAbstractCB -> setChecked( m_pOperation -> getAbstract() );
@@ -180,7 +182,7 @@
         insertType( m_pOperation->getTypeName(), 0 );
         m_pRtypeCB->setCurrentItem(0);
     }
-
+    
     //fill in parm list box
     UMLAttributeList * list = m_pOperation -> getParmList();
     UMLAttribute * pAtt = 0;
@@ -196,6 +198,28 @@
     else
         m_pProtectedRB -> setChecked( true );
 
+    // manage stereotypes
+    m_pStereoTypeCB -> setDuplicatesEnabled(false);//only allow one
of each type in box
+    insertStereotype (QString("")); // an empty stereotype is the default
+    int defaultStereotype=0;
+    bool foundDefaultStereotype = false;
+    for (UMLStereotypeListIt it(m_doc->getStereotypes()); it.current(); ++it) {
+        if (!foundDefaultStereotype) {
+            if ( m_pOperation->getStereotype(false) ==
it.current()->getName()) {
+                foundDefaultStereotype = true;
+                defaultStereotype++;
+            }
+            else
+                defaultStereotype++;
+        }
+        insertStereotype (it.current()->getName());
+    }
+    // lookup for a default stereotype, if the operation doesn't have one
+    if (foundDefaultStereotype)
+        m_pStereoTypeCB -> setCurrentItem(defaultStereotype);
+    else
+        m_pStereoTypeCB -> setCurrentItem(-1);
+
     //setup parm list box signals
     connect( m_pUpButton, SIGNAL( clicked() ), this, SLOT(
slotParameterUp() ) );
     connect( m_pDownButton, SIGNAL( clicked() ), this, SLOT(
slotParameterDown() ) );
@@ -465,7 +489,7 @@
         classifier->setAbstract(true);
     }
     m_pOperation -> setStatic( m_pStaticCB -> isChecked() );
-    m_pOperation -> setStereotype( m_pStereoTypeLE->text() );
+    m_pOperation -> setStereotype( m_pStereoTypeCB->currentText() );
 
     return true;
 }
@@ -486,4 +510,10 @@
     m_pRtypeCB->completionObject()->addItem( type );
 }
 
+void UMLOperationDialog::insertStereotype( const QString& type, int index )
+{
+    m_pStereoTypeCB->insertItem( type, index );
+    m_pStereoTypeCB->completionObject()->addItem( type );
+}
+
 #include "umloperationdialog.moc"
Index: umbrello/umbrello/dialogs/umloperationdialog.h
===================================================================
--- umbrello/umbrello/dialogs/umloperationdialog.h	(revision 435760)
+++ umbrello/umbrello/dialogs/umloperationdialog.h	(working copy)
@@ -84,14 +84,19 @@
     */
     ListPopupMenu * m_pMenu;
 
+    /**
+    * Inserts @p stereotype into the stereotype-combobox as well as
its completion object.
+    */
+    void insertStereotype( const QString& type, int index = -1 );
+
     //GUI widgets
     QGroupBox  * m_pParmsGB, * m_pGenGB;
     QListBox * m_pParmsLB;
     QButtonGroup * m_pScopeBG;
     QRadioButton * m_pPublicRB, * m_pPrivateRB,  * m_pProtectedRB;
     QLabel * m_pRtypeL, * m_pNameL, * m_pStereoTypeL;
-    KComboBox * m_pRtypeCB;
-    QLineEdit * m_pNameLE, * m_pStereoTypeLE;
+    KComboBox * m_pRtypeCB, * m_pStereoTypeCB;
+    QLineEdit * m_pNameLE;
     QCheckBox * m_pAbstractCB;
     QCheckBox * m_pStaticCB;
     QPushButton* m_pDeleteButton;
Index: umbrello/umbrello/codegenerator.h
===================================================================
--- umbrello/umbrello/codegenerator.h	(revision 435760)
+++ umbrello/umbrello/codegenerator.h	(working copy)
@@ -332,6 +332,11 @@
      */
     virtual const QStringList reservedKeywords() const;
 
+    /**
+     * Create the default stereotypes for your language (constructor, int etc)
+     */
+    virtual void createDefaultStereotypes ();
+
 protected:
 
     /**
Index: umbrello/umbrello/classparser/cpptree2uml.cpp
===================================================================
--- umbrello/umbrello/classparser/cpptree2uml.cpp	(revision 435760)
+++ umbrello/umbrello/classparser/cpptree2uml.cpp	(working copy)
@@ -27,6 +27,7 @@
 #include "../datatype.h"
 // FIXME The next include is motivated by template params
 #include "../template.h"
+#include <klocale.h>
 
 CppTree2Uml::CppTree2Uml( const QString& fileName)
     : m_anon( 0 ), m_nsCnt( 0 ), m_clsCnt( 0 )
@@ -255,6 +256,7 @@
     bool isVirtual = false;
     bool isStatic = false;
     bool isInline = false;
+    bool isConstructor = false;
 
     if( funSpec ){
 	QPtrList<AST> l = funSpec->nodeList();
@@ -286,11 +288,17 @@
 		  << "): need a surrounding class." << endl;
 	return;
     }
+
     QString returnType = typeOfDeclaration( typeSpec, d );
     UMLOperation *m = ClassImport::makeOperation(c, id);
+    // if a class has no return type, it could de a constructor or
+    // a destructor
+    if (d && returnType.isEmpty() &&
(d->declaratorId()->unqualifiedName()->text().find(i18n("~")) == -1))
+        isConstructor = true;
+
     parseFunctionArguments( d, m );
     ClassImport::insertMethod( c, m, (Uml::Scope)m_currentAccess, returnType,
-			      isStatic, false /*isAbstract*/, m_comment);
+			      isStatic, false /*isAbstract*/, isFriend, isConstructor, m_comment);
     m_comment = "";
 
 /* For reference, Kdevelop does some more:
@@ -488,6 +496,7 @@
     bool isStatic = false;
     bool isInline = false;
     bool isPure = decl->initializer() != 0;
+    bool isConstructor = false;
 
     if( funSpec ){
 	QPtrList<AST> l = funSpec->nodeList();
@@ -523,9 +532,14 @@
 
     QString returnType = typeOfDeclaration( typeSpec, d );
     UMLOperation *m = ClassImport::makeOperation(c, id);
+    // if a class has no return type, it could de a constructor or
+    // a destructor
+    if (d && returnType.isEmpty() &&
(d->declaratorId()->unqualifiedName()->text().find(i18n("~")) == -1))
+        isConstructor = true;
+
     parseFunctionArguments( d, m );
     ClassImport::insertMethod( c, m, (Uml::Scope)m_currentAccess, returnType,
-			      isStatic, isPure, m_comment);
+			      isStatic, isPure, isFriend, isConstructor, m_comment);
     m_comment = "";
 }
 
Index: umbrello/umbrello/classimport.h
===================================================================
--- umbrello/umbrello/classimport.h	(revision 435760)
+++ umbrello/umbrello/classimport.h	(working copy)
@@ -80,6 +80,7 @@
     static void insertMethod(UMLClassifier *klass, UMLOperation *op,
                              Uml::Scope scope, QString type,
                              bool isStatic, bool isAbstract,
+                             bool isFriend = false, bool isConstructor = false,
                              QString comment = QString::null);
 
     /**
Index: umbrello/umbrello/codegenerator.cpp
===================================================================
--- umbrello/umbrello/codegenerator.cpp	(revision 435760)
+++ umbrello/umbrello/codegenerator.cpp	(working copy)
@@ -796,4 +796,9 @@
     return emptyList;
 }
 
+void CodeGenerator::createDefaultStereotypes()  {
+    //empty by default, override in your code generator
+    //e.g.  m_document->createDefaultStereotypes("constructor");
+}
+
 #include "codegenerator.moc"
Index: umbrello/umbrello/umldoc.h
===================================================================
--- umbrello/umbrello/umldoc.h	(revision 435760)
+++ umbrello/umbrello/umldoc.h	(working copy)
@@ -848,6 +848,19 @@
     void removeStereotype(const UMLStereotype *s);
 
     /**
+     * Add a stereotype if it doesn't already exist.
+     * Used by code generators, operations and attribute dialogue.
+     */
+    void addDefaultStereotypes();
+
+    /**
+     * Returns a list of the stereotypes in this UMLDoc.
+     *
+     * @return	List of UML stereotypes.
+     */
+    const UMLStereotypeList& getStereotypes();
+
+    /**
      * Returns a name for the new object, appended with a number
      * if the default name is taken e.g. new_actor, new_actor_1
      * etc.
Index: umbrello/umbrello/classimport.cpp
===================================================================
--- umbrello/umbrello/classimport.cpp	(revision 435760)
+++ umbrello/umbrello/classimport.cpp	(working copy)
@@ -221,7 +221,8 @@
 
 void ClassImport::insertMethod(UMLClassifier *klass, UMLOperation *op,
                                Uml::Scope scope, QString type,
-                               bool isStatic, bool isAbstract,
+                               bool isStatic, bool isAbstract, 
+                               bool isFriend, bool isConstructor,
                                QString comment) {
     op->setScope(scope);
     if (!type.isEmpty()) {  // return type may be missing
(constructor/destructor)
@@ -236,9 +237,18 @@
                 op->setType(typeObj);
             }
         }
-    }
+    } 
+    
     op->setStatic(isStatic);
     op->setAbstract(isAbstract);
+
+    // if the operation is friend, add it as a stereotype
+    if (isFriend)
+        op->setStereotype("friend");
+    // if the operation is a constructor, add it as a stereotype
+    if (isConstructor)
+        op->setStereotype("constructor");
+
     klass->addOperation(op);
     //umldoc->signalUMLObjectCreated(op);
     QString strippedComment = formatComment(comment);
Index: umbrello/umbrello/operation.cpp
===================================================================
--- umbrello/umbrello/operation.cpp	(revision 435760)
+++ umbrello/umbrello/operation.cpp	(working copy)
@@ -393,7 +393,11 @@
 
     QString cName = c->getName();
     QString opName = getName();
-
+    // if an operation has the stereotype constructor
+    // return true
+    QString strConstructor ("constructor");
+    if (getStereotype(false) == strConstructor)
+        return true;
     // It's a constructor operation if the operation name
     // matches that of the parent classifier.
     return (cName == opName);
Index: umbrello/umbrello/idlimport.cpp
===================================================================
--- umbrello/umbrello/idlimport.cpp	(revision 435760)
+++ umbrello/umbrello/idlimport.cpp	(working copy)
@@ -391,7 +391,7 @@
                     break;
                 srcIndex++;
             }
-            ClassImport::insertMethod(klass, op, Uml::Public,
typeName, false, false, comment);
+            ClassImport::insertMethod(klass, op, Uml::Public,
typeName, false, false, false, false, comment);
             if (isOneway) {
                 op->setStereotype("oneway");
                 isOneway = false;
Index: umbrello/umbrello/classifiercodedocument.cpp
===================================================================
--- umbrello/umbrello/classifiercodedocument.cpp	(revision 435760)
+++ umbrello/umbrello/classifiercodedocument.cpp	(working copy)
@@ -634,6 +634,17 @@
  * Save the XMI representation of this object
  */
 void ClassifierCodeDocument::saveToXMI ( QDomDocument & doc,
QDomElement & root ) {
+#if 0
+    // avoid the creation of primitive data type
+    QString strType;
+    if (getParentClassifier()->getBaseType() == Uml::ot_Datatype) {
+        strType = getParentClassifier()->getName();
+        // lets get the default code generator to check if it is a
primitive data type
+        // there's a reason to create files for int/boolean and so ?
+        if (getParentGenerator()->isReservedKeyword(strType))
+           return;
+    }
+#endif
     QDomElement docElement = doc.createElement( "classifiercodedocument" );
 
     setAttributesOnNode(doc, docElement);
Index: umbrello/umbrello/umldoc.cpp
===================================================================
--- umbrello/umbrello/umldoc.cpp	(revision 435760)
+++ umbrello/umbrello/umldoc.cpp	(working copy)
@@ -342,6 +342,7 @@
     }//end switch




More information about the umbrello-devel mailing list