[Uml-devel] branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators

Oliver Kellogg okellogg at users.sourceforge.net
Tue Feb 13 21:36:51 UTC 2007


SVN commit 633355 by okellogg:

computeAssocTypeAndRole(): Start fixing.
This was horribly broken, apparently not many people have been generating Ada.
More to follow.


 M  +47 -46    adawriter.cpp  
 M  +11 -1     adawriter.h  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/adawriter.cpp #633354:633355
@@ -3,7 +3,7 @@
  *                           -------------------                           *
  *  Based on javawriter.cpp by Luis De la Parra Blum                       *
  *  copyright            : (C) 2002 by Oliver Kellogg                      *
- *    (C) 2003-2006 Umbrello UML Modeller Authors <uml-devel at uml.sf.net>   *
+ *    (C) 2003-2007 Umbrello UML Modeller Authors <uml-devel at uml.sf.net>   *
  ***************************************************************************
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -103,24 +103,48 @@
     return retval;
 }
 
-void AdaWriter::computeAssocTypeAndRole
-(UMLAssociation *a, QString& typeName, QString& roleName) {
-    roleName = a->getRoleName(Uml::A);
+void AdaWriter::computeAssocTypeAndRole(UMLClassifier *c,
+                                        UMLAssociation *a,
+                                        QString& typeName, QString& roleName) {
+    UMLClassifier* assocEnd = dynamic_cast<UMLClassifier*>(a->getObject(Uml::B));
+    if (assocEnd == NULL)
+        return;
+    const Uml::Association_Type assocType = a->getAssocType();
+    if (assocType != Uml::at_Aggregation && assocType != Uml::at_Composition)
+        return;
+    const QString multi = a->getMulti(Uml::B);
+    bool hasNonUnityMultiplicity = !multi.isEmpty();
+    hasNonUnityMultiplicity &= !multi.contains(QRegExp("^1 *\\.\\. *1$"));
+    roleName = cleanName(a->getRoleName(Uml::B));
+    if (roleName.isEmpty())
+        roleName = cleanName(a->getName());
     if (roleName.isEmpty()) {
-        if (a->getMulti(Uml::A).isEmpty()) {
+        QString artificialName = cleanName(assocEnd->getName());
+        if (hasNonUnityMultiplicity) {
+            roleName = artificialName;
+            roleName.append("_Vector");
+        } else {
             roleName = "M_";
-            roleName.append(typeName);
-        } else {
-            roleName = typeName;
-            roleName.append("_Vector");
+            roleName.append(artificialName);
         }
     }
-    UMLClassifier* c = dynamic_cast<UMLClassifier*>(a->getObject(Uml::A));
-    if (c == NULL)
-        return;
-    typeName = cleanName(c->getName());
-    if (! a->getMulti(Uml::A).isEmpty())
-        typeName.append("_Array_Access");
+    if (assocEnd == c)
+        typeName = assocEnd->getName();
+    else
+        typeName = assocEnd->getFullyQualifiedName(".");
+    UMLPackage *enclosingPkg = c->getUMLPackage();
+    UMLDoc *umldoc = UMLApp::app()->getDocument();
+    // @todo If the class has an enclosing package then it is assumed that
+    //       the class name is the type name; if the class does not have an
+    //       enclosing package then the class name acts as the Ada package
+    //       name.  This rule should be applied consistently throughout the
+    //       entire code generation.
+    if (enclosingPkg == umldoc->getRootFolder(Uml::mt_Logical))
+        typeName.append(".Object");
+    if (hasNonUnityMultiplicity)
+        typeName.append("_Array_Ptr");
+    else if (assocType == Uml::at_Aggregation)
+        typeName.append("_Ptr");
 }
 
 void AdaWriter::writeClass(UMLClassifier *c) {
@@ -280,6 +304,8 @@
     }
     ada << "private;" << m_endl << m_endl;
     ada << getIndent() << "type Object_Ptr is access all Object'Class;" << m_endl << m_endl;
+    ada << getIndent() << "type Object_Array is array Positive range <> of Object_Ptr;" << m_endl << m_endl;
+    ada << getIndent() << "type Object_Array_Ptr is access Object_Array;" << m_endl << m_endl;
 
     // Generate accessors for public attributes.
     UMLAttributeList atl;
@@ -328,37 +354,8 @@
     ada << getIndent() << "private" << m_endl << m_endl;
     m_indentLevel++;
 
-    // Generate auxiliary declarations for multiplicity of associations
     UMLAssociationList aggregations = c->getAggregations();
-    if (!aggregations.isEmpty()) {
-        for (UMLAssociation *a = aggregations.first(); a; a = aggregations.next()) {
-            if (a->getMulti(Uml::A).isEmpty())
-                continue;
-            UMLClassifier* other = (UMLClassifier*)a->getObject(Uml::A);
-            QString member = cleanName(other->getName());
-            // Handling of packages is missing here
-            // A test and error action is missing here for !isOOClass()
-            ada << getIndent() << "type " << member << "_Array is array"
-            << " (Positive range <>) of " << member << ".Object_Ptr;" << m_endl;
-            ada << getIndent() << "type " << member << "_Array_Access is access "
-            << member << "_array;" << m_endl << m_endl;
-        }
-    }
     UMLAssociationList compositions = c->getCompositions();
-    if (!compositions.isEmpty()) {
-        for (UMLAssociation *a = compositions.first(); a; a = compositions.next()) {
-            if (a->getMulti(Uml::A).isEmpty())
-                continue;
-            UMLObject *other = a->getObject(Uml::A);
-            QString member = cleanName(other->getName());
-            // Handling of packages is missing here
-            // Treatment of !isOOClass() is missing here
-            ada << getIndent() << "type " << member << "_Array is array"
-            << " (Positive range <>) of " << member << ".Object;" << m_endl;
-            ada << getIndent() << "type " << member << "_Array_Access is access "
-            << member << "_array;" << m_endl << m_endl;
-        }
-    }
 
     ada << getIndent() << "type Object is ";
     if (c->getAbstract())
@@ -376,8 +373,10 @@
     if (forceSections() || !aggregations.isEmpty()) {
         ada << getIndent() << "-- Aggregations:" << m_endl;
         for (UMLAssociation *a = aggregations.first(); a; a = aggregations.next()) {
+            if (c != a->getObject(Uml::A))
+                continue;
             QString typeName, roleName;
-            computeAssocTypeAndRole(a, typeName, roleName);
+            computeAssocTypeAndRole(c, a, typeName, roleName);
             ada << getIndent() << roleName << " : " << typeName << ";" << m_endl;
         }
         ada << endl;
@@ -385,8 +384,10 @@
     if (forceSections() || !compositions.isEmpty()) {
         ada << getIndent() << "-- Compositions:" << m_endl;
         for (UMLAssociation *a = compositions.first(); a; a = compositions.next()) {
+            if (c != a->getObject(Uml::A))
+                continue;
             QString typeName, roleName;
-            computeAssocTypeAndRole(a, typeName, roleName);
+            computeAssocTypeAndRole(c, a, typeName, roleName);
             ada << getIndent() << roleName << " : " << typeName << ";" << m_endl;
         }
         ada << endl;
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/adawriter.h #633354:633355
@@ -79,7 +79,17 @@
      */
     void writeOperation (UMLOperation *op, QTextStream &ada, bool is_comment = false);
 
-    void computeAssocTypeAndRole (UMLAssociation *a, QString& typeName, QString& roleName);
+    /**
+     * Compute the type and role name from the given association.
+     *
+     * @param c         The UMLClassifier for which code is being generated.
+     * @param a         The UMLAssociation to analyze.
+     * @param typeName  Return value: type name.
+     * @param roleName  Return value: role name.
+     */
+    void computeAssocTypeAndRole (UMLClassifier *c,
+                                  UMLAssociation *a,
+                                  QString& typeName, QString& roleName);
 
     bool isOOClass (UMLClassifier *c);
 




More information about the umbrello-devel mailing list