Bug 141644 - Ada95 Code Generation Errors for Aggregation
Summary: Ada95 Code Generation Errors for Aggregation
Status: RESOLVED FIXED
Alias: None
Product: umbrello
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Fedora RPMs Linux
: NOR normal
Target Milestone: ---
Assignee: Oliver Kellogg
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-02-13 19:52 UTC by Mark Gardinier
Modified: 2007-02-16 18:52 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Ada95 class code generated by Umbrello (1.79 KB, text/x-adasrc)
2007-02-13 19:59 UTC, Mark Gardinier
Details
Ada95 code generated by Umbrello (1.82 KB, text/x-adasrc)
2007-02-13 20:01 UTC, Mark Gardinier
Details
Ada95 code generated by Umbrello (1.78 KB, text/x-adasrc)
2007-02-13 20:02 UTC, Mark Gardinier
Details
Ada95 code generated by 3rd party tool (627 bytes, text/x-adasrc)
2007-02-13 20:03 UTC, Mark Gardinier
Details
Ada95 code generated by 3rd party tool (928 bytes, text/x-adasrc)
2007-02-13 20:04 UTC, Mark Gardinier
Details
Ada95 code generated by 3rd party tool (634 bytes, text/x-adasrc)
2007-02-13 20:04 UTC, Mark Gardinier
Details
Umbrello XMl (4.02 KB, application/x-bzip2)
2007-02-13 20:11 UTC, Mark Gardinier
Details
example Ada multiplicity from another UML tool (8.33 KB, application/x-zip-compressed)
2007-02-14 20:37 UTC, Mark Gardinier
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Gardinier 2007-02-13 19:52:30 UTC
Version:            (using KDE KDE 3.5.5)
Installed from:    Fedora RPMs
Compiler:          GPS (Gnat) N/A Not a  compiler problem
OS:                Linux

The code generator for Ada95 generates inhertance correctly.  However, when using aggregation between two classes it generates wrong code.  In the example attached, there are 3 classes.  Child inherits off parent.  A_Friend is an aggregate of Child.  In the file generated by Umbrello, a_friend.ads, there are two "Aggregation" fields in the tagged record object (M_ and M_) when there should be none.  In the child.ads file, there are the same two fields.  In this child object, there should be one aggregation field called Pal (the aggregation name) and it should be typed as a "sequence" of Friends.  The parent.ads file was generated correctly.  See the note on the class model for more.

I've attached several files.  The file newtest.xmi contains the xml.  The files parent.ads, child.ads, and a_friend.ads are what is generated by Umbrello.  The files Prag_A_Friend.ads, Prag_Child.ads, and Prag_Parent.ads were generated by a different UML tool that runs on Windows.  They are almost correct. This tool generated the multiplicity of the Child-Friend aggregation as a single instance instead of an array.  The vendor of the tool admitted this was wrong but it was what the customer wanted.

In addition, a file int.ads was generated when there is no type int on the diagram.  I've had the same type of problem occur when I have a class on a diagram model that is associated to another class and I remove the assocation.  In this case, the code generator still added the association even though it was removed from the diagram and the diagram was resaved.
Comment 1 Mark Gardinier 2007-02-13 19:59:07 UTC
Created attachment 19669 [details]
Ada95 class code generated by Umbrello
Comment 2 Mark Gardinier 2007-02-13 20:01:29 UTC
Created attachment 19670 [details]
Ada95 code generated by Umbrello
Comment 3 Mark Gardinier 2007-02-13 20:02:37 UTC
Created attachment 19671 [details]
Ada95 code generated by Umbrello
Comment 4 Mark Gardinier 2007-02-13 20:03:39 UTC
Created attachment 19672 [details]
Ada95 code generated by 3rd party tool
Comment 5 Mark Gardinier 2007-02-13 20:04:11 UTC
Created attachment 19673 [details]
Ada95 code generated by 3rd party tool
Comment 6 Mark Gardinier 2007-02-13 20:04:51 UTC
Created attachment 19674 [details]
Ada95 code generated by 3rd party tool
Comment 7 Mark Gardinier 2007-02-13 20:11:24 UTC
Created attachment 19675 [details]
Umbrello XMl
Comment 8 Oliver Kellogg 2007-02-14 19:54:50 UTC
Commit 141644 on branches/KDE/3.5 restored the AdaWriter::computeAssocTypeAndRole() which was completely broken.
Basic handling of associations is back, up next is some refining.
Comment 9 Oliver Kellogg 2007-02-14 19:59:27 UTC
SVN commit 633667 by okellogg:

className(): New. 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, and
 an artifical name "Object" is used as the name for the tagged type.
 Ideally this should be adjustable by a menu setting (later, on trunk.)
CCBUG:141644


 M  +34 -11    adawriter.cpp  
 M  +2 -0      adawriter.h  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/adawriter.cpp #633666:633667
@@ -70,7 +70,34 @@
     return true;
 }
 
+QString AdaWriter::className(UMLPackage *pkgOrClass, bool inOwnScope) {
+    // 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.
+    QString retval;
+    QString className = cleanName(pkgOrClass->getName());
+    UMLClassifier *c = dynamic_cast<UMLClassifier*>(pkgOrClass);
+    UMLPackage *umlPkg = pkgOrClass->getUMLPackage();
+    if (umlPkg == UMLApp::app()->getDocument()->getRootFolder(Uml::mt_Logical)) {
+        if (! inOwnScope)
+            retval = className + '.';
+        retval.append("Object");
+    } else {
+        if (! inOwnScope)
+            retval = umlPkg->getFullyQualifiedName(".") + '.';
+        retval.append(className);
+    }
+    return retval;
+}
+
+//QString AdaWriter::scopeName(UMLPackage *pkgOrClass, bool inOwnScope) {
+
 QString AdaWriter::qualifiedName(UMLPackage *p, bool withType, bool byValue) {
+    // 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.
     UMLPackage *umlPkg = p->getUMLPackage();
     QString className = cleanName(p->getName());
     QString retval;
@@ -134,11 +161,6 @@
         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)
@@ -292,7 +314,8 @@
 
     UMLClassifierList superclasses = c->getSuperClasses();
 
-    ada << getIndent() << "type Object is ";
+    const QString name = className(c);
+    ada << getIndent() << "type " << name << " is ";
     if (c->getAbstract())
         ada << "abstract ";
     if (superclasses.isEmpty()) {
@@ -300,12 +323,12 @@
     } else {
         // FIXME: Multiple inheritance is not yet supported
         UMLClassifier* parent = superclasses.first();
-        ada << "new " << qualifiedName(parent) << ".Object with ";
+        ada << "new " << className(parent, false) << " with ";
     }
     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;
+    ada << getIndent() << "type " << name << "_Ptr is access all " << name << "'Class;" << m_endl << m_endl;
+    ada << getIndent() << "type " << name << "_Array is array (Positive range <>) of " << name << "_Ptr;" << m_endl << m_endl;
+    ada << getIndent() << "type " << name << "_Array_Ptr is access " << name << "_Array;" << m_endl << m_endl;
 
     // Generate accessors for public attributes.
     UMLAttributeList atl;
@@ -365,7 +388,7 @@
     } else {
         // FIXME: Multiple inheritance is not yet supported
         UMLClassifier* parent = superclasses.first();
-        ada << "new " << qualifiedName(parent) << ".Object with ";
+        ada << "new " << className(parent, false) << " with ";
     }
     ada << "record" << m_endl;
     m_indentLevel++;
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/adawriter.h #633666:633667
@@ -93,6 +93,8 @@
 
     bool isOOClass (UMLClassifier *c);
 
+    QString className(UMLPackage *pkgOrClass, bool inOwnScope = true);
+
     QString qualifiedName
     (UMLPackage *p, bool withType = false, bool byValue = false);
 
Comment 10 Mark Gardinier 2007-02-14 20:37:56 UTC
Created attachment 19693 [details]
example Ada multiplicity from another UML tool 

I just thought I would show how Rational Rose handles unspecified multiplicity
(i.e., 1..n)  when generating Ada95 code.  Look at the spec to Friend
(friend.1.ada).  Inside it declares an unbounded array of type Handle
(Array_of_Handle) which is an access type to the class.  Next it declares an
access type (Access_Array_Of_Handle) to Array_Of_Handle.  Then, in class Child
(child.1.ada), it uses this type when declaring the Friend aggregation
attribute.

If only Umbrello was written in Ada.  I could then help you and code this
myself.
Comment 11 Oliver Kellogg 2007-02-15 23:07:37 UTC
SVN commit 633967 by okellogg:

computeAssocTypeAndRole(): Fix computation of type name.
Mark, is this working for you?
CCBUG:141644


 M  +3 -1      ChangeLog  
 M  +2 -9      umbrello/codegenerators/adawriter.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #633966:633967
@@ -4,6 +4,7 @@
 * Relationships for entities do not live outside of an entity relationship diagram (125146)
 * Javascript Code Generation creates bad format methods (135540)
 * Crash when deleting the link between a package and a class (141602)
+* Ada95 Code Generation Errors for Aggregation (141644)
 
 Version 1.5.61
 
@@ -13,6 +14,7 @@
 * Bugs fixed from http://bugs.kde.org:
 * Crash on creating various types of associations (140693, 141073, 141106, 141277)
 * Unclickable use case diagram (140870)
+* Crash on opening xmi file produced by previous version (141279)
 
 Version 1.5.6
 
@@ -101,7 +103,7 @@
 * Java import: method and class visibility ignored (130794)
 * Java import - static not handled correctly (130926)
 * Java import - package visibility incorrectly represented (130932)
-* Java import - random import order can result in interface being teated as class (131006)
+* Java import - random import order can result in interface being treated as class (131006)
 * Java import - associations not setup correctly, duplicate classes created (131270)
 
 Version 1.5.3
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/adawriter.cpp #633966:633967
@@ -123,7 +123,7 @@
     if (assocType != Uml::at_Aggregation && assocType != Uml::at_Composition)
         return;
     const QString multi = a->getMulti(Uml::B);
-    bool hasNonUnityMultiplicity = !multi.isEmpty();
+    bool hasNonUnityMultiplicity = (!multi.isEmpty() && multi != "1");
     hasNonUnityMultiplicity &= !multi.contains(QRegExp("^1 *\\.\\. *1$"));
     roleName = cleanName(a->getRoleName(Uml::B));
     if (roleName.isEmpty())
@@ -138,14 +138,7 @@
             roleName.append(artificialName);
         }
     }
-    if (assocEnd == c)
-        typeName = assocEnd->getName();
-    else
-        typeName = assocEnd->getFullyQualifiedName(".");
-    UMLPackage *enclosingPkg = c->getUMLPackage();
-    UMLDoc *umldoc = UMLApp::app()->getDocument();
-    if (enclosingPkg == umldoc->getRootFolder(Uml::mt_Logical))
-        typeName.append(".Object");
+    typeName = className(assocEnd, (assocEnd == c));
     if (hasNonUnityMultiplicity)
         typeName.append("_Array_Ptr");
     else if (assocType == Uml::at_Aggregation)
Comment 12 Mark Gardinier 2007-02-16 05:04:59 UTC
Yes, thank you.  It works great.  But there is one more annoying bug I'm going to submit when I get a chance having to do with naming and association and then being unable to delete the name.  No matter how you remove the name field, an underscore is created as an attribute.

Oliver Kellogg <okellogg@users.sourceforge.net> wrote: ------- You are receiving this mail because: -------
You reported the bug, or are watching the reporter.
         
http://bugs.kde.org/show_bug.cgi?id=141644         




------- Additional Comments From okellogg users sourceforge net  2007-02-15 23:07 -------
SVN commit 633967 by okellogg:

computeAssocTypeAndRole(): Fix computation of type name.
Mark, is this working for you?
CCBUG:141644


 M  +3 -1      ChangeLog  
 M  +2 -9      umbrello/codegenerators/adawriter.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #633966:633967
 @ -4,6 +4,7  @
 * Relationships for entities do not live outside of an entity relationship diagram (125146)
 * Javascript Code Generation creates bad format methods (135540)
 * Crash when deleting the link between a package and a class (141602)
+* Ada95 Code Generation Errors for Aggregation (141644)
 
 Version 1.5.61
 
 @ -13,6 +14,7  @
 * Bugs fixed from http://bugs.kde.org:
 * Crash on creating various types of associations (140693, 141073, 141106, 141277)
 * Unclickable use case diagram (140870)
+* Crash on opening xmi file produced by previous version (141279)
 
 Version 1.5.6
 
 @ -101,7 +103,7  @
 * Java import: method and class visibility ignored (130794)
 * Java import - static not handled correctly (130926)
 * Java import - package visibility incorrectly represented (130932)
-* Java import - random import order can result in interface being teated as class (131006)
+* Java import - random import order can result in interface being treated as class (131006)
 * Java import - associations not setup correctly, duplicate classes created (131270)
 
 Version 1.5.3
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/adawriter.cpp #633966:633967
 @ -123,7 +123,7  @
     if (assocType != Uml::at_Aggregation && assocType != Uml::at_Composition)
         return;
     const QString multi = a->getMulti(Uml::B);
-    bool hasNonUnityMultiplicity = !multi.isEmpty();
+    bool hasNonUnityMultiplicity = (!multi.isEmpty() && multi != "1");
     hasNonUnityMultiplicity &= !multi.contains(QRegExp("^1 *\\.\\. *1$"));
     roleName = cleanName(a->getRoleName(Uml::B));
     if (roleName.isEmpty())
 @ -138,14 +138,7  @
             roleName.append(artificialName);
         }
     }
-    if (assocEnd == c)
-        typeName = assocEnd->getName();
-    else
-        typeName = assocEnd->getFullyQualifiedName(".");
-    UMLPackage *enclosingPkg = c->getUMLPackage();
-    UMLDoc *umldoc = UMLApp::app()->getDocument();
-    if (enclosingPkg == umldoc->getRootFolder(Uml::mt_Logical))
-        typeName.append(".Object");
+    typeName = className(assocEnd, (assocEnd == c));
     if (hasNonUnityMultiplicity)
         typeName.append("_Array_Ptr");
     else if (assocType == Uml::at_Aggregation)


Yes, thank you.&nbsp; It works great.&nbsp; But there is one more annoying bug I'm going to submit when I get a chance having to do with naming and association and then being unable to delete the name.&nbsp; No matter how you remove the name field, an underscore is created as an attribute.<br><br><b><i>Oliver Kellogg &lt;okellogg@users.sourceforge.net&gt;</i></b> wrote:<blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"> ------- You are receiving this mail because: -------<br>You reported the bug, or are watching the reporter.<br>         <br>http://bugs.kde.org/show_bug.cgi?id=141644         <br><br><br><br><br>------- Additional Comments From okellogg users sourceforge net  2007-02-15 23:07 -------<br>SVN commit 633967 by okellogg:<br><br>computeAssocTypeAndRole(): Fix computation of type name.<br>Mark, is this working for you?<br>CCBUG:141644<br><br><br> M  +3 -1      ChangeLog  <br> M  +2 -9     
 umbrello/codegenerators/adawriter.cpp  <br><br><br>--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #633966:633967<br> @ -4,6 +4,7  @<br> * Relationships for entities do not live outside of an entity relationship diagram (125146)<br> * Javascript Code Generation creates bad format methods (135540)<br> * Crash when deleting the link between a package and a class (141602)<br>+* Ada95 Code Generation Errors for Aggregation (141644)<br> <br> Version 1.5.61<br> <br> @ -13,6 +14,7  @<br> * Bugs fixed from http://bugs.kde.org:<br> * Crash on creating various types of associations (140693, 141073, 141106, 141277)<br> * Unclickable use case diagram (140870)<br>+* Crash on opening xmi file produced by previous version (141279)<br> <br> Version 1.5.6<br> <br> @ -101,7 +103,7  @<br> * Java import: method and class visibility ignored (130794)<br> * Java import - static not handled correctly (130926)<br> * Java import - package visibility incorrectly represented (130932)<br>-* Java import
 - random import order can result in interface being teated as class (131006)<br>+* Java import - random import order can result in interface being treated as class (131006)<br> * Java import - associations not setup correctly, duplicate classes created (131270)<br> <br> Version 1.5.3<br>--- branches/KDE/3.5/kdesdk/umbrello/umbrello/codegenerators/adawriter.cpp #633966:633967<br> @ -123,7 +123,7  @<br>     if (assocType != Uml::at_Aggregation &amp;&amp; assocType != Uml::at_Composition)<br>         return;<br>     const QString multi = a-&gt;getMulti(Uml::B);<br>-    bool hasNonUnityMultiplicity = !multi.isEmpty();<br>+    bool hasNonUnityMultiplicity = (!multi.isEmpty() &amp;&amp; multi != "1");<br>     hasNonUnityMultiplicity &amp;= !multi.contains(QRegExp("^1 *\\.\\. *1$"));<br>     roleName = cleanName(a-&gt;getRoleName(Uml::B));<br>     if (roleName.isEmpty())<br> @ -138,14 +138,7  @<br>             roleName.append(artificialName);<br>         }<br>     }<br>-    if
 (assocEnd == c)<br>-        typeName = assocEnd-&gt;getName();<br>-    else<br>-        typeName = assocEnd-&gt;getFullyQualifiedName(".");<br>-    UMLPackage *enclosingPkg = c-&gt;getUMLPackage();<br>-    UMLDoc *umldoc = UMLApp::app()-&gt;getDocument();<br>-    if (enclosingPkg == umldoc-&gt;getRootFolder(Uml::mt_Logical))<br>-        typeName.append(".Object");<br>+    typeName = className(assocEnd, (assocEnd == c));<br>     if (hasNonUnityMultiplicity)<br>         typeName.append("_Array_Ptr");<br>     else if (assocType == Uml::at_Aggregation)<br><br></blockquote><br>
Comment 13 Oliver Kellogg 2007-02-16 18:52:51 UTC
Closing with okay from OP.