simonjwright / coldframe

ColdFrame generates Ada framework code and documentation from UML models.
https://simonjwright.github.io/coldframe
GNU General Public License v2.0
8 stars 1 forks source link

Undocumented Restriction on Subclass Naming #7

Closed AlexProudfoot closed 3 years ago

AlexProudfoot commented 3 years ago

Invalid Ada is generated for the following model.

Screenshot from 2021-03-10 06-10-36

alex@mint-vm$ make
# XXX This is a workround for ArgoUML Issue 6385.
(grep -q "xmlns:argouml" Air_Traffic_Control.uml && cp Air_Traffic_Control.uml /home/alex/coldframe/coldframeout/Air_Traffic_Control.rr~1) ||       \
sed                             \
  -e "s;<pgml ;<pgml xmlns:argouml='http://argouml.org' ;"  \
  <Air_Traffic_Control.uml                          \
  >/home/alex/coldframe/coldframeout/Air_Traffic_Control.rr~1
java -cp /home/alex/saxon/saxon.jar com.icl.saxon.StyleSheet              \
  /home/alex/coldframe/coldframeout/Air_Traffic_Control.rr~1              \
  /home/alex/coldframe/scripts/resolve-references.xsl         \
  library_path=/home/alex/coldframe/lib/              \
  >/home/alex/coldframe/coldframeout/Air_Traffic_Control.rr~2             \
  || (echo "Resolution problem."; rm -f -f /home/alex/coldframe/coldframeout/Air_Traffic_Control.rr /home/alex/coldframe/coldframeout/Air_Traffic_Control.rr~?; exit 1)
# XXX This is a workround for an XML/Ada issue.
sed                             \
  -e "s;org.omg.xmi.namespace.UML;http://www.omg.org/spec/XMI;" \
  </home/alex/coldframe/coldframeout/Air_Traffic_Control.rr~2           \
  >/home/alex/coldframe/coldframeout/Air_Traffic_Control.rr
/home/alex/coldframe/tools/normalize_xmi    \
  -c /home/alex/coldframe/scripts/emacs_case_exceptions \
            \
  /home/alex/coldframe/coldframeout/Air_Traffic_Control.rr
Reading case exceptions from '/home/alex/coldframe/scripts/emacs_case_exceptions'
Processing /home/alex/coldframe/coldframeout/Air_Traffic_Control.rr
 checking domain Air_Traffic_Controller
touch Air_Traffic_Control.norm-stamp
generating Air_Traffic_Controller.ada ...
generating Air_Traffic_Controller.gen ...
checking for unimplemented bodies ...
... none.
gnatmake -p -P Air_Traffic_Controller
Setup
   [mkdir]        object directory for project Air_Traffic_Controller
Compile
   [Ada]          test_air_traffic_controller.adb
   [Ada]          air_traffic_controller.ads
   [Ada]          air_traffic_controller-initialize.adb
   [Ada]          air_traffic_controller-tear_down.adb
air_traffic_controller-air_traffic_controller.ads:45:13: "ODC" conflicts with declaration at line 43
gprbuild: *** compilation phase failed
Makefile:11: recipe for target 'test_air_traffic_controller' failed
make: [test_air_traffic_controller] Error 5 (ignored)
rm /home/alex/coldframe/coldframeout/Air_Traffic_Control.rr Air_Traffic_Controller.ada

The problematic output is as follows.

   type R1_Child_Class is
     (Off_Duty_Controller_T,
      On_Duty_Controller_T,
      Null_T);

   type R1_Child
     (Current : R1_Child_Class := Null_T)
   is record
      case Current is
         when Off_Duty_Controller_T =>
            ODC : ColdFrame.Instances.Handle;
         when On_Duty_Controller_T =>
            ODC : ColdFrame.Instances.Handle;
         when Null_T => null;
      end case;
   end record;

So, the undocumented restriction is that we can't have child class names that abbreviate to the same text, ODC in this case.

AlexProudfoot commented 3 years ago

This is easily avoided by reconsidering the naming of the child classes, in this case I renamed Off_Duty_Controller to On_Break_Controller. On the other hand, an implementation restriction on the naming of classes in an “Analysis Model” seems wrong.

simonjwright commented 3 years ago

A problem is that the abbreviations are visible in the generated code. You’ve seen the problem in generalizations. Also, in the Library example, the association Authorship (generated in Library.Authorship) contains

   function Wrote
     (BK : Book.Handle)
     return Borrower.Handle;

   function Was_Written_By
     (A_Borrower : Borrower.Handle)
     return Book.Vectors.Vector;

where BK is the abbreviation for Book (an undocumented demo of «abbreviation»), A_Borrower is the "abbreviation" for Borrower.

Thinking about generalizations, I’m not at all sure that the named components in the _Child record are needed. Maybe something to do with multiple inheritance?

Anyway, I’ll see whether I can at least warn that there’s a potential abbreviation conflict in the model.

simonjwright commented 3 years ago

Not sure that "analysis model" is an apt description of the sort of model we have here! There’s a lot of translation-related decoration needed ...

simonjwright commented 3 years ago

Code in development (not yet committed/pushed) would give, with your model,

Processing /Users/simon/coldframe/coldframeout/Air_Traffic_Control.rr
 checking domain Air_Traffic_Control
Warning: duplicate abbreviation "ODC"
  ... class "Off_Duty_Controller"
  ... class "On_Duty_Controller"
One warning.
AlexProudfoot commented 3 years ago

I think that would be helpful. In the meantime, I've reverted to the original naming with an abbreviation tag on Off Duty Controller. Air_Traffic_Control.uml.zip

AlexProudfoot commented 3 years ago

On naming the type of model, would "ColdFrame Specification Model" be nearer the mark? Have you settled on a name?

simonjwright commented 3 years ago

Have you settled on a name?

Never really thought I needed one!