home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / komix / DATA.Z / stgclasses.tcl < prev    next >
Text File  |  1997-12-01  |  135KB  |  4,855 lines

  1. #---------------------------------------------------------------------------
  2. #
  3. # Copyright (c) 1997 by Cayenne Software, Inc.
  4. #
  5. # This software is furnished under a license and may be used only in
  6. # accordance with the terms of such license and with the inclusion of
  7. # the above copyright notice. This software or any other copies thereof
  8. # may not be provided or otherwise made available to any other person.
  9. # No title to and ownership of the software is hereby transferred.
  10. #
  11. # The information in this software is subject to change without notice
  12. # and should not be construed as a commitment by Cayenne Software, Inc.
  13. #
  14. #---------------------------------------------------------------------------
  15. #
  16. #       File            : stgclasses.tcl
  17. #       Author          : 
  18. #       Original date   : November 1997
  19. #       Description     : Classes for code generation
  20. #
  21. #---------------------------------------------------------------------------
  22.  
  23.  
  24. #      File:           @(#)stgobject.tcl    /main/titanic/2
  25.  
  26.  
  27. # This class contains generic Smalltalk code
  28. # generation object methods.
  29.  
  30. Class STGObject : {Object} {
  31.     constructor
  32.     method destructor
  33.     method asSTName
  34.     method asArgument
  35.     method getSTName
  36.     method getArgumentName
  37.     method check
  38.     method checkLocal
  39.     method checkSTName
  40.     method checkFreeTextQuote
  41.  
  42.     # Stores name of this object in Smalltalk compliant format
  43.     # e.g. with illegal characters filtered out.
  44.     #
  45.     attribute stName
  46.  
  47.     # Used to store the argument name of this object.
  48.     #
  49.     attribute argName
  50. }
  51.  
  52. constructor STGObject {class this name} {
  53.     set this [Object::constructor $class $this $name]
  54.     # Start constructor user section
  55.     # End constructor user section
  56.     return $this
  57. }
  58.  
  59. method STGObject::destructor {this} {
  60.     # Start destructor user section
  61.     # End destructor user section
  62. }
  63.  
  64.  
  65. # Makes name an ST compliant name by filtering out
  66. # illegal characters and returns it.
  67. #
  68. method STGObject::asSTName {this name} {
  69.     # remove illegal characters from name
  70.     # Illegal characters are all characters except a-z, A-Z, 0-9 and _
  71.     if [regsub -all {[^a-zA-Z0-9_]} $name "" newName ] {
  72.         # m4_warning $WST_REMOVECHARS $name
  73.     }
  74.     return $newName
  75. }
  76.  
  77.  
  78. # Transforms <name> into argument name prepending a or an and returns it.
  79. #
  80. method STGObject::asArgument {this name} {
  81.     if { [string first [cap [string index $name 0]] "AEIOU"] > -1 } {
  82.         return "an[cap $name]"
  83.     }
  84.     return "a[cap $name]"
  85. }
  86.  
  87.  
  88. # Gets name for object, issues error if it is object without getName method.
  89. # Returns stName if it was set already, otherwise compute Smalltalk compliant
  90. # name, store in stName and return it.
  91. # Issues warning when illegal characters get filtered out.
  92. #
  93. method STGObject::getSTName {this} {
  94.     if { [$this stName] != "" } {
  95.         return [$this stName]
  96.     }
  97.     if [catch { set oldName [$this getName] } ] {
  98.         # m4_error $EST_FAILNONAME
  99.         return "error"
  100.     }
  101.     set newName [$this asSTName $oldName]
  102.     $this stName $newName
  103.     return $newName 
  104. }
  105.  
  106.  
  107. # If argName is already set, return it.
  108. # Otherwise determine argument name, set
  109. # argName and return it.
  110. #
  111. method STGObject::getArgumentName {this} {
  112.     if { [$this argName] != "" } {
  113.         return [$this argName]
  114.     }
  115.     if [catch { $this argName [$this argumentName] } ] {
  116.         # m4_error $EST_FAILNOARGNAME
  117.         return "error"
  118.     }
  119.     return [$this argName]  
  120. }
  121.  
  122.  
  123. # Returns number of errors found
  124. # in the class and cascade further
  125. #
  126. method STGObject::check {this} {
  127.     set errornr [$this checkLocal]
  128.     return $errornr
  129. }
  130.  
  131.  
  132. # Checks class
  133. #
  134. method STGObject::checkLocal {this} {
  135.     set errornr 0
  136.     return $errornr
  137. }
  138.  
  139. method STGObject::checkSTName {this} {
  140.     set errornr 0
  141.     set warningnr 0
  142.  
  143.     if { [$this stName] != "" } {
  144.         return $errornr
  145.     }
  146.  
  147.     if [catch { set oldName [$this getName] } ] {
  148.         m4_error $EST_FAILNONAME
  149.         incr errornr 1
  150.         return $errornr
  151.     }
  152.     
  153.     # remove illegal characters from name
  154.     # Illegal characters are all characters except a-z, A-Z, 0-9 and _
  155.     if [regsub -all {[^a-zA-Z0-9_]} [$this getName] "" newName ] {
  156.         m4_warning $WST_REMOVECHARS $oldName
  157.         incr warningnr 1
  158.     }
  159.     $this stName $newName
  160.  
  161.     return $errornr
  162. }
  163.  
  164. method STGObject::checkFreeTextQuote {this} {
  165.     set warningnr 0
  166.     if [regexp \' [$this getPropertyValue freeText] comment] {
  167.         m4_warning $WST_REMOVEQUOTEDESCR [$this getSTName]
  168.         incr warningnr 1
  169.     }
  170.     return $warningnr
  171. }
  172.  
  173. # Do not delete this line -- regeneration end marker
  174.  
  175.  
  176.  
  177. #---------------------------------------------------------------------------
  178. #      File:           @(#)stgassocge.tcl    /main/titanic/2
  179.  
  180.  
  181. # Generic base class for association generators.
  182.  
  183. Class STGAssocGen : {GCObject} {
  184.     method destructor
  185.     constructor
  186.     method getPrivateImplementation
  187.     method getAccessImplementation
  188.     method getModifyImplementation
  189.     method getRemoveImplementation
  190.     method getErrorMessage
  191.     method generateNilCheck
  192.     method generateConstraintCheck
  193.     method generateIncludesCheck
  194.     method generateExistenceCheck
  195.     method generateRelease
  196.     method removePermitted
  197.     method removeRequired
  198.     method upperConstraint
  199.     method lowerConstraint
  200.     method setType
  201.     method check
  202.     method checkLocal
  203.     method assocAttr
  204.  
  205.     # Used to store the instance variable name used for this association attribute.
  206.     # Set in getData.
  207.     #
  208.     attribute variableName
  209.  
  210.     # Used to hold name of this association attribute in parameter format.
  211.     #
  212.     attribute parameterName
  213.  
  214.     # Used to store role name for this association attribute.
  215.     #
  216.     attribute roleName
  217.  
  218.     # Implementation object for the class; used to speed up things.
  219.     #
  220.     attribute classImplementation
  221.  
  222.     # Holds the qualifier name for qualified associations.
  223.     #
  224.     attribute qualifierName
  225.  
  226.     # Holds the argument name of the qualifier for qualified associations.
  227.     #
  228.     attribute qualifierParameter
  229.  
  230.     # The generator of the opposite of the association
  231.     # attribute of this generator.
  232.     #
  233.     attribute opposite
  234.     attribute _assocAttr
  235. }
  236.  
  237. method STGAssocGen::destructor {this} {
  238.     # Start destructor user section
  239.     $this opposite ""
  240.     $this classImplementation ""
  241.     $this _assocAttr ""
  242.     # End destructor user section
  243. }
  244.  
  245.  
  246. # Sets the assocAttr association to <assocAttr>.
  247. #
  248. constructor STGAssocGen {class this assocAttr} {
  249.     set this [GCObject::constructor $class $this]
  250.     $this _assocAttr $assocAttr
  251.     $this opposite ""
  252.     return $this
  253. }
  254.  
  255.  
  256. # Gets an implementation object for this selector in the instance private category.
  257. #
  258. method STGAssocGen::getPrivateImplementation {this selector} {
  259.     return [[$this classImplementation] getInstanceMethodImplementation \
  260.                 $selector "private"]
  261. }
  262.  
  263.  
  264. # Gets an implementation object for this selector in the instance access associations category.
  265. #
  266. method STGAssocGen::getAccessImplementation {this selector} {
  267.     set category [[$this assocAttr] getReadCategory "association access"]
  268.     if { $category == "" } {
  269.         return ""
  270.     }
  271.     return [[$this classImplementation] getInstanceMethodImplementation \
  272.                 $selector $category]
  273. }
  274.  
  275.  
  276. # Gets an implementation for this selector in the instance modify association category.
  277. #
  278. method STGAssocGen::getModifyImplementation {this selector} {
  279.     set category [[$this assocAttr] getWriteCategory "association modification"]
  280.     if { $category == "" } {
  281.         return ""
  282.     }
  283.     return [[$this classImplementation] getInstanceMethodImplementation \
  284.                 $selector $category]
  285. }
  286.  
  287.  
  288. # Gets an implementation object for a remove method.
  289. #
  290. method STGAssocGen::getRemoveImplementation {this selector} {
  291.     set category [[$this assocAttr] getWriteCategory "association modification"]
  292.     if { ![$this removePermitted] } {
  293.         set category ""
  294.     }
  295.     if { $category == "" } {
  296.         if [$this removeRequired] {
  297.             set category "private"
  298.         } else {
  299.             return ""
  300.         }
  301.     }
  302.     return [[$this classImplementation] getInstanceMethodImplementation \
  303.                 $selector $category]
  304. }
  305.  
  306.  
  307. # Returns error call string based on error type and selector.
  308. #
  309. method STGAssocGen::getErrorMessage {this errorType selector} {
  310.     set errorMessage [[$globals errorDictionary] set $errorType]
  311.     if { $errorMessage == "" } {
  312.         m4_error $EST_UNKNOWNERRMSG $errorType
  313.         set errorMessage "Unknown error"
  314.     }
  315.     set errorMessage "$errorMessage in $selector in [[[$this assocAttr] ooplClass] getSTName]"    
  316.     return "self error: \'$errorMessage\'"
  317. }
  318.  
  319.  
  320. # Generate nil check for name in block:
  321. # if name is nil generate an error call.
  322. #
  323. method STGAssocGen::generateNilCheck {this block name} {
  324.     set expr [$block addExpression "$name isNil ifTrue:"]
  325.     set selector [$block selector]
  326.     $expr addExpression [$this getErrorMessage PARAMETER_NIL $selector]
  327. }
  328.  
  329.  
  330. # Generates a constraint check in block, this expressions
  331. # check whether the size of <name> is greater than/smaller than bound,
  332. # depending on type. Returns the expression.
  333. #
  334. method STGAssocGen::generateConstraintCheck {this selector block name bound type} {
  335.     if { $type == "upper" } {
  336.         set sizeCheck "$name size < $bound"
  337.     } else {
  338.         set sizeCheck "$name size > $bound"
  339.     }
  340.     set block [$block addExpression "$sizeCheck ifTrue:"]
  341.     set errorPart [$block addExpressionPart "ifFalse:"]
  342.     $errorPart addExpression [$this getErrorMessage CONSTRAINT $selector]
  343.     return $block
  344. }
  345.  
  346.  
  347. # Generates an include check for element in name, adds it to block and returns the new expression.
  348. #
  349. method STGAssocGen::generateIncludesCheck {this block name element} {
  350.     set block [$block addExpression "($name includes: $element) ifFalse:"]
  351.     return $block
  352. }
  353.  
  354.  
  355. # Generates a check expression that checks whether element is
  356. # in name and generates an error if this is not the case.
  357. #
  358. method STGAssocGen::generateExistenceCheck {this selector block name element} {
  359.     set block [$this generateIncludesCheck $block $name $element] 
  360.     $block addExpression [$this getErrorMessage ASSOC_OBJ_NOT_FOUND $selector]
  361. }
  362.  
  363.  
  364. # Generates additions to release to release the association
  365. # to which this association attribute belongs.
  366. #
  367. method STGAssocGen::generateRelease {this} {
  368.     set release [[$this classImplementation] release]
  369.     if [[$this assocAttr] oppositeMandatoryOne] {
  370.         $release insertExpression [$this getErrorMessage CANNOT_RELEASE release]
  371.     } else {
  372.         $this generateReleaseCode $release
  373.     }    
  374. }
  375.  
  376.  
  377. # Returns 1 if generation of a public remove is permitted.
  378. #
  379. method STGAssocGen::removePermitted {this} {
  380.     if [[$this assocAttr] oppositeMandatoryOne] {
  381.         return 0
  382.     }
  383.     return 1
  384. }
  385.  
  386.  
  387. # Returns 1 if generation of remove method is required for the generation
  388. # of other methods.
  389. #
  390. method STGAssocGen::removeRequired {this} {
  391.     set opposite [[$this assocAttr] opposite]
  392.     if { $opposite == "" } {
  393.         return 0
  394.     }
  395.     if { [$opposite isMandatory] || ([$opposite writeAccess] != "None") } {
  396.         return 1
  397.     }
  398.     return 0
  399. }
  400.  
  401.  
  402. # Gets upper bound of constraint for this association.
  403. #
  404. method STGAssocGen::upperConstraint {this} {
  405.     set constraint [[$this assocAttr] getConstraint]
  406.     if { $constraint == "" } {
  407.         return ""
  408.     }
  409.     if { [string first "\{" $constraint] != -1 } {
  410.         return ""
  411.     }
  412.     set dashIndex [string first "-" $constraint]
  413.     if { $dashIndex == -1 } {
  414.         set plusIndex [string first "+" $constraint]
  415.         if { $plusIndex == -1 } {
  416.             return $constraint
  417.         } else {
  418.             return "" 
  419.         }
  420.     } else {
  421.         return [string range $constraint [expr $dashIndex+1] end]
  422.     } 
  423. }
  424.  
  425.  
  426. # Get lower bound of constraint for this association.
  427. #
  428. method STGAssocGen::lowerConstraint {this} {
  429.     set constraint [[$this assocAttr] getConstraint]
  430.     if { $constraint == "" } {
  431.         return ""
  432.     }
  433.     if { [string first "\{" $constraint] != -1 } {
  434.         return ""
  435.     }
  436.     
  437.     set dashIndex [string first "-" $constraint]
  438.     if { $dashIndex == -1 } {
  439.         set plusIndex [string first "+" $constraint]
  440.         if { $plusIndex == -1 } {
  441.             return $constraint
  442.         } else {
  443.             return [string range $constraint 0 [expr $plusIndex-1]]
  444.         }
  445.     } else {
  446.         return [string range $constraint 0 [expr $dashIndex-1]]
  447.     } 
  448. }
  449.  
  450.  
  451. # Returns set type to be used to implement this
  452. # association.
  453. #
  454. method STGAssocGen::setType {this} {
  455.     if [[$this assocAttr] isOrdered] {
  456.         return "OrderedCollection"
  457.     }
  458.     return "Set"
  459. }
  460.  
  461. method STGAssocGen::check {this} {
  462.     set errornr [$this checkLocal]
  463.     return $errornr
  464. }
  465.  
  466. method STGAssocGen::checkLocal {this} {
  467.     set errornr 0
  468.     return $errornr
  469. }
  470.  
  471. # Do not delete this line -- regeneration end marker
  472.  
  473. method STGAssocGen::assocAttr {this args} {
  474.     if {$args == ""} {
  475.         return [$this _assocAttr]
  476.     }
  477.     set ref [$this _assocAttr]
  478.     if {$ref != ""} {
  479.         $ref _generator ""
  480.     }
  481.     set obj [lindex $args 0]
  482.     if {$obj != ""} {
  483.         $obj _generator $this
  484.     }
  485.     $this _assocAttr $obj
  486. }
  487.  
  488.  
  489.  
  490. #---------------------------------------------------------------------------
  491. #      File:           @(#)stgassocin.tcl    /main/titanic/3
  492.  
  493.  
  494. # Generator class for association initializers.
  495.  
  496. Class STGAssocInitializer : {STGObject} {
  497.     constructor
  498.     method destructor
  499.     method generate
  500.     method check
  501. }
  502.  
  503. constructor STGAssocInitializer {class this name} {
  504.     set this [STGObject::constructor $class $this $name]
  505.     # Start constructor user section
  506.     # End constructor user section
  507.     return $this
  508. }
  509.  
  510. method STGAssocInitializer::destructor {this} {
  511.     # Start destructor user section
  512.     # End destructor user section
  513. }
  514.  
  515.  
  516. # Get argument name for initializer and add it to
  517. # the constructor argument list.
  518. #
  519. method STGAssocInitializer::generate {this} {
  520.     # set hasInitializer attribute in association attribute
  521.     [$this assoc] hasInitializer 1
  522.  
  523.     set constructor [[$this constructor] methodImplementation]
  524.     set argName [[$this assoc] getArgumentName]
  525.     $constructor getUniqueArgumentName [$this getSTName] $argName
  526. }
  527.  
  528.  
  529. # For computing newRequired in 
  530. # STGConstructor
  531. #
  532. method STGAssocInitializer::check {this} {
  533.     set errornr 0
  534.     incr errornr [$this checkSTName]
  535.     return $errornr
  536. }
  537.  
  538. # Do not delete this line -- regeneration end marker
  539.  
  540. if [isCommand CMAssocInitializer] {
  541.     Class  STGAssocInitializerD : {STGAssocInitializer CMAssocInitializer} {
  542.     }
  543. } else {
  544.     Class STGAssocInitializerD : {STGAssocInitializer OPAssocInitializer} {    
  545.     }
  546. }
  547.  
  548. global mostDerivedOOPL ; set mostDerivedOOPL(OPAssocInitializer) STGAssocInitializerD
  549.  
  550. selfPromoter OPAssocInitializer {this} {
  551.     STGAssocInitializerD promote $this
  552. }
  553.  
  554.  
  555. #---------------------------------------------------------------------------
  556. #      File:           @(#)stgattribi.tcl    /main/titanic/3
  557.  
  558.  
  559. # Attribute initializer generator.
  560.  
  561. Class STGAttribInitializer : {STGObject} {
  562.     constructor
  563.     method destructor
  564.     method generate
  565.     method check
  566. }
  567.  
  568. constructor STGAttribInitializer {class this name} {
  569.     set this [STGObject::constructor $class $this $name]
  570.     # Start constructor user section
  571.     # End constructor user section
  572.     return $this
  573. }
  574.  
  575. method STGAttribInitializer::destructor {this} {
  576.     # Start destructor user section
  577.     # End destructor user section
  578. }
  579.  
  580.  
  581. # Determines the argument name and adds it to constructor parameters.
  582. # Generates an expression in the constructor to set the attribute
  583. # to the value supplied by the parameter.
  584. #
  585. method STGAttribInitializer::generate {this} {
  586.     set attrib [$this attrib]
  587.     # set hasInitializer in data attribute
  588.     $attrib hasInitializer 1
  589.  
  590.     set constructor [[$this constructor] methodImplementation]
  591.     set argName [$attrib getArgumentName]
  592.  
  593.     # Use original attrib name to avoid i_ 's
  594.     set name [$attrib getSTName]
  595.     if [$attrib isClassFeature] {
  596.         set name [cap $name]
  597.     }
  598.  
  599.     set uniqueName [$constructor getUniqueArgumentName $name $argName]
  600.     $constructor addExpression "$name := $uniqueName"
  601. }
  602.  
  603.  
  604. # For computing newRequired in 
  605. # STGConstructor
  606. #
  607. method STGAttribInitializer::check {this} {
  608.     set errornr 0
  609.     incr errornr [$this checkSTName]
  610.     return $errornr
  611. }
  612.  
  613. # Do not delete this line -- regeneration end marker
  614.  
  615. if [isCommand CMAttribInitializer] {
  616.     Class  STGAttribInitializerD : {STGAttribInitializer CMAttribInitializer} {
  617.     }
  618. } else {
  619.     Class STGAttribInitializerD : {STGAttribInitializer OPAttribInitializer} {    
  620.     }
  621. }
  622.  
  623. global mostDerivedOOPL ; set mostDerivedOOPL(OPAttribInitializer) STGAttribInitializerD
  624.  
  625. selfPromoter OPAttribInitializer {this} {
  626.     STGAttribInitializerD promote $this
  627. }
  628.  
  629.  
  630. #---------------------------------------------------------------------------
  631. #      File:           @(#)stgattribu.tcl    /main/titanic/3
  632.  
  633.  
  634. # This class contains generic attribute generation methods.
  635.  
  636. Class STGAttribute : {STGObject} {
  637.     constructor
  638.     method destructor
  639.     method getReadCategory
  640.     method getWriteCategory
  641.     method readAccess
  642.     method writeAccess
  643.  
  644.     # This attribute is set during generation and indicates whether there is an
  645.     # initializer for this attribute.
  646.     # Note: this can only work if generation for initializers is done before generation for attributes.
  647.     #
  648.     attribute hasInitializer
  649. }
  650.  
  651. constructor STGAttribute {class this name} {
  652.     set this [STGObject::constructor $class $this $name]
  653.     # Start constructor user section
  654.     # End constructor user section
  655.     return $this
  656. }
  657.  
  658. method STGAttribute::destructor {this} {
  659.     # Start destructor user section
  660.     # End destructor user section
  661.     $this STGObject::destructor
  662. }
  663.  
  664.  
  665. # Returns category name based on read access:
  666. # * return empty string if None
  667. # * return private if Private
  668. # * return <name> if Public
  669. #
  670. method STGAttribute::getReadCategory {this name} {
  671. # and return protected if Protected
  672.     set readAccess [$this readAccess]
  673.     if { $readAccess == "None" } {
  674.         return ""
  675.     } elseif { $readAccess == "Protected" } {
  676.         return "protected"
  677.     } elseif { $readAccess == "Private" } {
  678.         return "private"
  679.     } else {
  680.         return $name
  681.     }
  682. }
  683.  
  684.  
  685. # Returns category name based on write access specification:
  686. # as in getReadCategory.
  687. #
  688. method STGAttribute::getWriteCategory {this name} {
  689.     set writeAccess [$this writeAccess]
  690.     if { $writeAccess == "None" } {
  691.         return ""
  692.     } elseif { $writeAccess == "Protected" } {
  693.         return "protected"
  694.     } elseif { $writeAccess == "Private" } {
  695.         return "private"
  696.     } else {
  697.         return $name
  698.     }
  699. }
  700.  
  701.  
  702. # Returns read access specification.
  703. #
  704. method STGAttribute::readAccess {this} {
  705.     set accessList [split [$this getPropertyValue attrib_access] '-']
  706.     return [lindex $accessList 0] 
  707. }
  708.  
  709.  
  710. # Returns write access specification.
  711. #
  712. method STGAttribute::writeAccess {this} {
  713.     set accessList [split [$this getPropertyValue attrib_access] '-']
  714.     return [lindex $accessList 1] 
  715. }
  716.  
  717. # Do not delete this line -- regeneration end marker
  718.  
  719.  
  720.  
  721. #---------------------------------------------------------------------------
  722. #      File:           @(#)stgclass.tcl    /main/titanic/4
  723.  
  724.  
  725. # This class is the top level class generator.
  726. # It generates the entire class implementation.
  727.  
  728. Class STGClass : {STGObject} {
  729.     constructor
  730.     method destructor
  731.     method generate
  732.     method generateRelease
  733.     method generatePrint
  734.     method generateComment
  735.     method generateDefinition
  736.     method generateInheritanceType
  737.     method printGeneratingMessage
  738.     method printCheckingMessage
  739.     method getSTName
  740.     method check
  741.     method checkLocal
  742.     method checkSTName
  743.     method checkFreeTextQuote
  744.     method checkPrint
  745.     method checkInheritance
  746.     method checkAssocAttrSet
  747.     method checkDataAttrSet
  748.     method checkOperationSet
  749.     method checkInheritanceLoop
  750.     method checkMultipleInheritance
  751.     method checkSuperClass
  752.     method checkInheritanceType
  753.     method checkVariableByteInheritance
  754.  
  755.     # Set if this class is abstract e.g. has an abstract method.
  756.     # It is set by operation generators and used by the constructor 
  757.     #  generator.
  758.     # Correct operation assumes that operations are generated 
  759.     #  before the constructor!
  760.     #
  761.     attribute isAbstract
  762.     attribute loop
  763.  
  764.     # nr of error found in current class
  765.     # preventing redundancy
  766.     #
  767.     attribute localErrors
  768.     attribute classImplementation
  769.     attribute super
  770. }
  771.  
  772. constructor STGClass {class this name} {
  773.     set this [STGObject::constructor $class $this $name]
  774.     # Start constructor user section
  775.     # End constructor user section
  776.     return $this
  777. }
  778.  
  779. method STGClass::destructor {this} {
  780.     # Start destructor user section
  781.     # End destructor user section
  782. }
  783.  
  784.  
  785. # Generate the implementation of this class in grammar
  786. # object classImpl.
  787. #
  788. method STGClass::generate {this classImpl} {
  789.     # cache the implementation object
  790.     $this classImplementation $classImpl
  791.     
  792.     # just call the methods in the right order
  793.     $this printGeneratingMessage
  794.     $this generateDefinition
  795.     $this generateComment
  796.     
  797.     # Generate for all the features
  798.     foreach method [$this operationSet]    {
  799.         $method generate
  800.     }
  801.     $this generateRelease
  802.  
  803.     set constructor [$this constructor]
  804.     if { $constructor != "" } {
  805.         $constructor generate
  806.     }
  807.  
  808.     if [$globals generatePrint] {
  809.         $this generatePrint
  810.     }
  811.     
  812.     foreach attribute [$this dataAttrSet] {
  813.         $attribute generate
  814.     }
  815.     
  816.     foreach attribute [$this genAssocAttrSet] {
  817.         $attribute generate
  818.     }
  819.     
  820.     $this classImplementation ""
  821. }
  822.  
  823.  
  824. # Generates the release method and part of it's
  825. # implementation.
  826. #
  827. method STGClass::generateRelease {this} {
  828.     set classImpl [$this classImplementation]
  829.     set release [$classImpl getInstanceMethodImplementation "release" \
  830.                      "initialize-release"]
  831.     $release addExpression "super release"
  832.     $release hasUserCodePart 1
  833.     $classImpl release $release
  834. }
  835.  
  836.  
  837. # Generates the printing methods and part of
  838. # their implementation. If there is a user defined method
  839. # with the same selector don't generate.
  840. #
  841. method STGClass::generatePrint {this} {
  842.     set classImpl [$this classImplementation]
  843.     
  844.     # in checkPrint only oopl can be used
  845.     # here we can use the target model
  846.     if { [$classImpl methodExists "printOn:"] || \
  847.              [$classImpl methodExists "printVars:withIndent:"] } {
  848.         # not generating print functions
  849.         set printOn ""
  850.         set printVars ""
  851.     } else {
  852.         set printOn [$classImpl getInstanceMethodImplementation \
  853.                          "printOn:" "printing"]
  854.         set printVars [$classImpl getInstanceMethodImplementation \
  855.                            "printVars:withIndent:" "printing"]
  856.         
  857.         $printOn addArgument aStream
  858.         $printVars addArgument aStream
  859.         $printVars addArgument anInteger
  860.         
  861.         # generate start of printOn implementation
  862.         $printOn addExpression "super printOn: aStream"
  863.         
  864.         # if super class is in this system call it's printVars
  865.         if { [$this super] != "" } {
  866.             if { ![[$this super] isExternal] } {
  867.                 $printVars addExpression \
  868.                     "super printVars: aStream withIndent: anInteger"
  869.             }
  870.         } 
  871.     }
  872.     # cache the methods
  873.     $classImpl printOn $printOn
  874.     $classImpl printVars $printVars    
  875. }
  876.  
  877.  
  878. # Generate the FreeText property in the class comment.
  879. #
  880. method STGClass::generateComment {this} {
  881.     if [regsub -all \' [$this getPropertyValue freeText] "" comment] {
  882.         # '-s removed
  883.     }
  884.     [$this classImplementation] addCommentLine $comment 
  885. }
  886.  
  887.  
  888. # Generate superclass, inheritance type and category
  889. # in the classImplementation object. Sets the super
  890. # association.
  891. #
  892. method STGClass::generateDefinition {this} {
  893.     set classImpl [$this classImplementation]
  894.     
  895.     # get superclass
  896.     set gnodeSet [$this genNodeSet]
  897.     
  898.     if { [llength $gnodeSet] > 1 } {
  899.         
  900.     }
  901.     if { [llength $gnodeSet] == 0 } {
  902.         $this super ""
  903.         $classImpl super "Object"
  904.     } else {
  905.         $this super [[lindex $gnodeSet 0] superClass]
  906.         $classImpl super [[$this super] getSTName]
  907.     }
  908.     # warning for checkMultipleInheritance and checkSuperClass
  909.     #  already generated.
  910.     
  911.     $this generateInheritanceType
  912.     
  913.     # get category
  914.     set category [$this getPropertyValue classCategory]
  915.     if { $category == "" } {
  916.         # not set, use default: diagram or system name
  917.         if { [$globals defaultCategory] == "System" } {
  918.             set cc [ClientContext::global]
  919.             set category [[[$cc currentSystem] system] name]
  920.         } else {
  921.             # more complicated: get all components and find first
  922.             # diagram 
  923.             set smNode [$this smNode]
  924.             set component [lindex [$smNode getComponents] 0]
  925.             set category [[[$component diagram] file] name]
  926.         }
  927.     }
  928.     $classImpl category $category
  929. }
  930.  
  931.  
  932. # Generates inheritance type from the property inheritanceType.
  933. # Perfroms checks on this type and issues warnings or errors if it
  934. # is likely to give problems in Smalltalk.
  935. #
  936. method STGClass::generateInheritanceType {this} {
  937.     set errornr 0
  938.     set inheritanceType [$this getPropertyValue inheritanceType]
  939.     
  940.     if { ($inheritanceType == "regular") || ($inheritanceType == "") } {
  941.         [$this classImplementation] inheritanceType ""
  942.         set inheritanceType "regular"
  943.     } else {
  944.         [$this classImplementation] inheritanceType $inheritanceType
  945.     }
  946.     
  947.     # warnings for checkInheritanceType and checkVariableByteInheritance
  948.     #  already given.
  949.     
  950. }
  951.  
  952.  
  953. # Print a message stating that generation for this class is in progress.
  954. #
  955. method STGClass::printGeneratingMessage {this} {
  956.     m4_message $MST_GENERATE [$this getName]
  957. }
  958.  
  959. method STGClass::printCheckingMessage {this} {
  960.     m4_message $MST_CHECK [$this getName]
  961. }
  962.  
  963.  
  964. # Redefines getSTName to make sure the class name starts with an uppercase charcter.
  965. #
  966. method STGClass::getSTName {this} {
  967.     if { [$this stName] == "" } {
  968.         $this stName [cap [$this asSTName [$this getName]]]
  969.     }
  970.     return [$this stName]
  971. }
  972.  
  973.  
  974. # Like generate check is called from outside the object. 
  975. # Check calls all sub check-methods for generating errors and warnings
  976. # withoug code generation.
  977. # Generate also calls these sub-check-methods and depending on the
  978. # return values, code is generated.
  979. #
  980. method STGClass::check {this} {
  981.     set errornr 0
  982.     incr errornr [$this checkLocal]
  983.     return $errornr
  984. }
  985.  
  986. method STGClass::checkLocal {this} {
  987.     set errornr 0
  988.     set warningnr 0
  989.     $this printCheckingMessage
  990.  
  991.     incr warningnr [$this checkFreeTextQuote]
  992.  
  993.     set constructor [$this constructor]
  994.     if { $constructor != "" } {
  995.         incr errornr [$constructor check]
  996.     }
  997.  
  998.     incr errornr [$this checkSTName]
  999.  
  1000.     incr warningnr [$this checkPrint]
  1001.  
  1002.     incr errornr [$this checkInheritance]
  1003.  
  1004.     incr errornr [$this checkDataAttrSet]
  1005.     
  1006.     incr errornr [$this checkOperationSet]
  1007.  
  1008.     incr errornr [$this checkAssocAttrSet]
  1009.     return $errornr
  1010. }
  1011.  
  1012. method STGClass::checkSTName {this} {
  1013.     set errornr 0
  1014.     set warningnr 0
  1015.  
  1016.     if { [$this stName] != "" } {
  1017.         return $errornr
  1018.     }
  1019.     if [catch { set oldName [$this getName] } ] {
  1020.         m4_error $EST_FAILNONAME
  1021.         incr errornr 1
  1022.         return $errornr
  1023.     }
  1024.     # remove illegal characters from name
  1025.     # Illegal characters are all characters except a-z, A-Z, 0-9 and _
  1026.     if [regsub -all {[^a-zA-Z0-9_]} [$this getName] "" newName ] {
  1027.         m4_warning $WST_REMOVECHARS $oldName
  1028.         incr warningnr 1
  1029.     }
  1030.     # check whether first letter is cappitalized
  1031.     set capName [cap $newName]
  1032.     if {$newName != $capName} {
  1033.         m4_warning $WST_CAPITCLASS $oldName $capName
  1034.         incr warningnr 1        
  1035.         set newName $capName
  1036.     }
  1037.     $this stName $newName
  1038.  
  1039.     return $errornr
  1040.  
  1041. }
  1042.  
  1043. method STGClass::checkFreeTextQuote {this} {
  1044.     set warningnr 0
  1045.     if [regexp \' [$this getPropertyValue freeText] comment] {
  1046.         m4_warning $WST_REMOVEQUOTEDESCR [$this getSTName]
  1047.         incr warningnr 1
  1048.     }
  1049.     return $warningnr
  1050. }
  1051.  
  1052. method STGClass::checkPrint {this} {
  1053.     set warningnr 0
  1054.     if [$globals generatePrint] {
  1055.         set wrnPrn 0
  1056.         foreach operation [$this operationSet] {
  1057.             set selector [$operation getSelector]
  1058.             if { ($selector == "printOn:") || \
  1059.                      ($selector == "printVars:withIndent:") } {
  1060.                 # a corresponding print function is found , so warn somebody
  1061.                 m4_warning $WST_NOGENPRINT
  1062.                 incr warningnr 1
  1063.                 break
  1064.             }
  1065.         }
  1066.     }
  1067.     return $warningnr
  1068. }
  1069.  
  1070. method STGClass::checkInheritance {this} {
  1071.     # when a check returns a warning value is stored in
  1072.     # a temporary variable.
  1073.     set errornr 0
  1074.  
  1075.     incr errornr [$this checkSuperClass]
  1076.     
  1077.     incr errornr [$this checkMultipleInheritance]
  1078.     
  1079.     incr errornr [$this checkInheritanceLoop]
  1080.     
  1081.     incr errornr [$this checkInheritanceType]
  1082.     
  1083.     incr errornr [$this checkVariableByteInheritance]
  1084.     
  1085.     return $errornr
  1086. }
  1087.  
  1088. method STGClass::checkAssocAttrSet {this} {
  1089.     set errornr 0
  1090.     set dataAttrs [List new]
  1091.     foreach attribute [$this dataAttrSet] {
  1092.         set dName [$attribute getSTName]
  1093.         $dataAttrs append $dName
  1094.     }
  1095.     set oppQualifiers [List new]
  1096.     set opposite ""
  1097.     foreach association [$this genAssocAttrSet] {
  1098.         incr errornr [$association check]
  1099.         # check opposite qualifier names , so this class will not have
  1100.         # duplicates.
  1101.         set aOT [[$association generator] objType]
  1102.         set aRN [[$association generator] roleName]
  1103.         if {$aOT == "STGManyQual"} {
  1104.             set name "${aRN}SetDict"
  1105.         } elseif {$aOT == "STGOneQual"} {
  1106.             set name "${aRN}Dict"
  1107.         } elseif {$aOT == "STGAssocMany"} {
  1108.             set name "${aRN}Set"
  1109.         } else {
  1110.             set name "${aRN}"
  1111.         }
  1112.         if {[$dataAttrs search -exact $name] >= 0} {
  1113.             m4_error $EST_ASSOCEQALDATA [$association getName] \
  1114.                 [$this getSTName] $name 
  1115.         }
  1116.         set opposite [$association opposite]
  1117.         if {$opposite != ""} {
  1118.             if {[$opposite isQualified]} {
  1119.                 set qualifier [$opposite qualifier]
  1120.                 set qualStName [$qualifier stName]
  1121.                 set qualName [$qualifier getSTName]
  1122.                 #reset 
  1123.                 $qualifier stName $qualStName
  1124.                 # retrieve user specified qualifier
  1125.                 set userQualName [$opposite getPropertyValue qualifierName]
  1126.                 if { $userQualName != "" } {
  1127.                     set qualName $userQualName
  1128.                 }
  1129.                 if {[$dataAttrs search -exact $qualName] >= 0} {
  1130.                     m4_error $EST_DATAOPPQUAL [$association getName] \
  1131.                         [$this getSTName] $qualName
  1132.                 } elseif {[$oppQualifiers search -exact $qualName] >= 0} {
  1133.                     m4_error $EST_DUPOPPQUAL [$association getName] \
  1134.                         [$this getSTName] $qualName
  1135.                 } else {
  1136.                     $oppQualifiers append $qualName
  1137.                 }
  1138.             }
  1139.         }
  1140.     }
  1141.     return $errornr
  1142. }
  1143.  
  1144. method STGClass::checkDataAttrSet {this} {
  1145.     set errornr 0
  1146.     foreach attribute [$this dataAttrSet] {
  1147.         incr errornr [$attribute check]
  1148.     }
  1149.     return $errornr
  1150. }
  1151.  
  1152. method STGClass::checkOperationSet {this} {
  1153.     set errornr 0
  1154.     foreach operation [$this operationSet] {
  1155.         incr errornr [$operation check]
  1156.     }
  1157.     return $errornr
  1158. }
  1159.  
  1160. method STGClass::checkInheritanceLoop {this} {
  1161.     # inheritance loop:
  1162.     set errornr 0
  1163.     if {[$this loop] != 1} {
  1164.         $this loop 1
  1165.         set gnodeSet [$this genNodeSet]
  1166.         if { [llength $gnodeSet] > 0 } {
  1167.             set errornr [[[lindex $gnodeSet 0] superClass] checkInheritanceLoop]
  1168.         }
  1169.         $this loop 0
  1170.     } else {
  1171.         set errornr 1
  1172.     }
  1173.     return $errornr
  1174. }
  1175.  
  1176. method STGClass::checkMultipleInheritance {this} {
  1177.     set errornr 0
  1178.     set gnodeSet [$this genNodeSet]
  1179.     if { [llength $gnodeSet] > 1 } {
  1180.         m4_error $EST_MULTINHERIT [$this getSTName]
  1181.         set errornr 1
  1182.     }
  1183.     return $errornr
  1184. }
  1185.  
  1186. method STGClass::checkSuperClass {this} {
  1187.     # besides checking also set some things, 
  1188.     # ok, it is not necessary for checking but though for generation
  1189.     # (keeping code clean be doing sometimes something too much.)
  1190.     set errornr 0
  1191.     set gnodeSet [$this genNodeSet]
  1192.     # when checking no classImplementation is set (unlike generating)
  1193.     set classImpl [$this classImplementation]
  1194.  
  1195.     if { [llength $gnodeSet] == 0 } {
  1196.         m4_warning $WST_NOSUPERCLASS [$this getSTName]
  1197.         $this super ""
  1198.         if {$classImpl != "" } {
  1199.             $classImpl super "Object"
  1200.         }
  1201.         set errornr 0
  1202.     } else {
  1203.         $this super [[lindex $gnodeSet 0] superClass]
  1204.         if {$classImpl != "" } {
  1205.             $classImpl super [[$this super] getSTName]
  1206.         }
  1207.     }
  1208.     return $errornr
  1209. }
  1210.  
  1211. method STGClass::checkInheritanceType {this} {
  1212.     set errornr 0
  1213.     
  1214.     set inheritanceType [$this getPropertyValue inheritanceType]    
  1215.     if { ($inheritanceType == "regular") || ($inheritanceType == "") } {
  1216.         set inheritanceType "regular"
  1217.     } 
  1218.     
  1219.     if { [$this super] != "" } {
  1220.         set superInheritanceType [[$this super] getPropertyValue inheritanceType]
  1221.         if { $superInheritanceType == "" } {
  1222.             set superInheritanceType "regular"
  1223.         }
  1224.         
  1225.         # different inheritance types with superclass inheritance other
  1226.         # than regular may cause trouble. Print cautious warning as we don't
  1227.         # know for sure Smalltalk will reject it.
  1228.         if { ($superInheritanceType != $inheritanceType) && \
  1229.                  ($superInheritanceType != "regular") } {
  1230.             m4_warning $WST_DIFFINHERITTYPE [$this getSTName] $inheritanceType \
  1231.                 [[$this super] getSTName] $superInheritanceType
  1232.             set errornr 0
  1233.         }
  1234.     }
  1235.     return $errornr
  1236. }
  1237.  
  1238. method STGClass::checkVariableByteInheritance {this} {
  1239.     set errornr 0
  1240.  
  1241.     set inheritanceType [$this getPropertyValue inheritanceType]
  1242.     if { $inheritanceType != "variableByte" } {
  1243.         return $errornr
  1244.     }
  1245.  
  1246.     # If this class has instance variables (possibly by
  1247.     # inheritance it may not be accepted by Smalltalk
  1248.     # So scan superclasses. This may be slow but variableByte inheritance
  1249.     # will not be used very often (?)    
  1250.  
  1251.     set checkClass $this
  1252.     set hasInstanceVariables 0
  1253.     while { $checkClass != "" } {
  1254.         # when a loop is present this while loop 
  1255.         # not end so setting loop variable.
  1256.         # the actual loop detection is in another method.
  1257.         if {[$checkClass loop] == 1 } {
  1258.             break
  1259.         }
  1260.         $checkClass loop 1
  1261.         lappend checkedClasses $checkClass
  1262.         
  1263.         # associations cause instance variables
  1264.         if { [$checkClass genAssocAttrSet] != "" } {
  1265.             set hasInstanceVariables 1
  1266.             break
  1267.         }
  1268.         # data attributes cause instance variables if the isPoolDict
  1269.         # property is not set and isClassFeature returns 0
  1270.         foreach dataAttr [$checkClass dataAttrSet] {
  1271.             if { (![$dataAttr isClassFeature]) && \
  1272.                      ([$dataAttr getPropertyValue isPoolDict] != "1") } {
  1273.                 set hasInstanceVariables 1
  1274.                 break
  1275.             }
  1276.         }
  1277.         # find superclass
  1278.         set gnodeSet [$checkClass genNodeSet]
  1279.         if { [llength $gnodeSet] == 0 } {
  1280.             # break while
  1281.             set checkClass ""
  1282.         } else {
  1283.             # next loop
  1284.             set checkClass [[lindex $gnodeSet 0] superClass]
  1285.         }
  1286.     }
  1287.     if $hasInstanceVariables {
  1288.         m4_warning $WST_VARBYTEINHERIT [$this getSTName]
  1289.         set errornr 0
  1290.     }
  1291.  
  1292.     # setting all loop variables back to zero
  1293.     foreach checkClass $checkedClasses {
  1294.         $checkClass loop 0
  1295.     }
  1296.     set checkedClasses ""
  1297.  
  1298.     return $errornr
  1299. }
  1300.  
  1301. # Do not delete this line -- regeneration end marker
  1302.  
  1303. if [isCommand CMClass] {
  1304.     Class  STGClassD : {STGClass CMClass} {
  1305.     }
  1306. } else {
  1307.     Class STGClassD : {STGClass OPClass} {    
  1308.     }
  1309. }
  1310.  
  1311. global mostDerivedOOPL ; set mostDerivedOOPL(OPClass) STGClassD
  1312.  
  1313. selfPromoter OPClass {this} {
  1314.     STGClassD promote $this
  1315. }
  1316.  
  1317.  
  1318. #---------------------------------------------------------------------------
  1319. #      File:           @(#)stgconstru.tcl    /main/titanic/3
  1320.  
  1321.  
  1322. # Constructor generator class.
  1323.  
  1324. Class STGConstructor : {STGObject} {
  1325.     constructor
  1326.     method destructor
  1327.     method generate
  1328.     method getMethodImplementation
  1329.     method generateDescription
  1330.     method generateNew
  1331.     method generateRestrictedNew
  1332.     method getSelector
  1333.     method getMessage
  1334.     method checkLocal
  1335.     method checkFreeTextDQuote
  1336.     method checkNew
  1337.  
  1338.     # Indicates whether the instance creation method must be generated.
  1339.     # Set by super class initializer.
  1340.     #
  1341.     attribute newRequired
  1342.  
  1343.     # Used to store the selector for the instance creation method. Set in getMethodImplementation.
  1344.     #
  1345.     attribute newSelector
  1346.     attribute methodImplementation
  1347. }
  1348.  
  1349. constructor STGConstructor {class this name} {
  1350.     set this [STGObject::constructor $class $this $name]
  1351.     # Start constructor user section
  1352.     # End constructor user section
  1353.     return $this
  1354. }
  1355.  
  1356. method STGConstructor::destructor {this} {
  1357.     # Start destructor user section
  1358.     # End destructor user section
  1359. }
  1360.  
  1361.  
  1362. # Generates the equivalent of a constructor:
  1363. # * determines message selector and gets implementation object.
  1364. # * Generates a description
  1365. # * generates for the initializers
  1366. # * generates a redefined new if required.
  1367. # * generates a new if indicated by newRequired.
  1368. #
  1369. method STGConstructor::generate {this} {
  1370.     $this getMethodImplementation
  1371.     $this generateDescription
  1372.     # default for newRequired is 1
  1373.     $this newRequired 1
  1374.     foreach initializer [$this initializerSet] {
  1375.         $initializer generate
  1376.     }
  1377.     # Generate restricted new if another instance creation method is generated
  1378.     if { ([$this newSelector] != "new") && [$this newRequired] } {
  1379.         $this generateRestrictedNew    
  1380.     }
  1381.     if [$this newRequired] {
  1382.         $this generateNew
  1383.     }
  1384.     $this methodImplementation ""
  1385. }
  1386.  
  1387.  
  1388. # Determines the message selector for the initialize method and gets
  1389. # an implementation object. Sets the 'initialize' association of
  1390. # the class implementation object.
  1391. #
  1392. method STGConstructor::getMethodImplementation {this} {
  1393.     set parList [List new]
  1394.     foreach parameter [[$this ooplClass] creationParamSet] {
  1395.         $parList append [$this asSTName [$parameter getOriginalName]]
  1396.     }
  1397.     
  1398.     set selector [$this getSelector initialize $parList]
  1399.     $this newSelector [$this getSelector new $parList]
  1400.     
  1401.     # Now get the implementation object
  1402.     set classImpl [[$this ooplClass] classImplementation]
  1403.     set initialize [$classImpl getInstanceMethodImplementation $selector \
  1404.                         "initialize-release"] 
  1405.     # Store in generators
  1406.     $classImpl initialize $initialize
  1407.     $this methodImplementation $initialize
  1408.     
  1409.     $initialize hasUserCodePart 1
  1410. }
  1411.  
  1412.  
  1413. # Generates the freetext comment.
  1414. #
  1415. method STGConstructor::generateDescription {this} {
  1416.     #juno: check whether \" works instead of previous surrounded by braces
  1417.     if [regsub -all \" [$this getPropertyValue freeText] "" comment] {
  1418.         # "-s removed
  1419.     }
  1420.  
  1421.     [$this methodImplementation] comment $comment
  1422. }
  1423.  
  1424.  
  1425. # Generates the instance creation method which
  1426. # calls initialize. If the class is abstract generate 
  1427. # expressions to check if this class can be instantiated.
  1428. #
  1429. method STGConstructor::generateNew {this} {
  1430.     set selector [$this newSelector]
  1431.     
  1432.     # get implementation object
  1433.     set classImpl [[$this ooplClass] classImplementation]
  1434.     set new [$classImpl getClassMethodImplementation $selector "instance creation"]
  1435.     
  1436.     if [$new isUserDefined] {
  1437.         # m4_warning $WST_DEFCONSTRULES
  1438.         $new isUserDefined 0
  1439.     }
  1440.  
  1441.     # Create the initialize message
  1442.     set initSelector [[$this methodImplementation] selector]
  1443.     set argNames [List new]
  1444.     [[$this methodImplementation] getArguments] foreach argName {
  1445.         $argNames append [$new getNewUniqueArgumentName $argName]
  1446.     }
  1447.     set initMessage [$this getMessage $initSelector $argNames]
  1448.     
  1449.     # Make the new or basicNew message
  1450.     if { ($selector != "new") && ([$this superClassInitializerSet] != "") } {
  1451.         set newMessage "self basicNew"
  1452.     } else {
  1453.         set newMessage "super new"
  1454.     } 
  1455.     
  1456.     # Add to implementation
  1457.     # Make it conditional for abstract classes
  1458.     set block $new
  1459.     if { [[$this ooplClass] isAbstract] == 1} {
  1460.         set className [[$this ooplClass] getSTName]
  1461.         set block [$new addExpression "(self class = $className) ifTrue:"] 
  1462.         $block addExpression "\^self error: \'Cannot instantiate abstract class\'"
  1463.         set block [$block addExpressionPart "ifFalse:"]
  1464.     }
  1465.     $block addExpression "^$newMessage $initMessage"
  1466. }
  1467.  
  1468.  
  1469. # Generate a new that forbids use of new.
  1470. #
  1471. method STGConstructor::generateRestrictedNew {this} {
  1472.     set classImpl [[$this ooplClass] classImplementation]
  1473.     set new [$classImpl getClassMethodImplementation "new" "instance creation"]
  1474.     if [$new isUserDefined] {
  1475.         # m4_warning $WST_AUTOCONSTRULES
  1476.         $new isUserDefined 0 
  1477.     }
  1478.     $new addExpression "self error: \'Cannot use new, use [$this newSelector]\'"
  1479. }
  1480.  
  1481.  
  1482. # Returns selector for initialize or new.
  1483. # Base it on the <firstPart> of the selector
  1484. # and the <parameterNames>.
  1485. #
  1486. method STGConstructor::getSelector {this firstPart parameterNames} {
  1487.     set first 1
  1488.     set selector $firstPart
  1489.     $parameterNames foreach parName {
  1490.         if $first {
  1491.             if { $selector == "new" } {
  1492.                 set selector "$parName:"
  1493.             } else {
  1494.                 set selector "$selector[cap $parName]:"
  1495.             }
  1496.             set first 0
  1497.         } else {
  1498.             set selector "$selector$parName:"
  1499.         }
  1500.     }
  1501.     return $selector
  1502. }
  1503.  
  1504.  
  1505. # Makes a message with selector and the arguments of argList.
  1506. #
  1507. method STGConstructor::getMessage {this selector argList} {
  1508.     set selectorPartList [split $selector ':']
  1509.     set message [lindex $selectorPartList 0]
  1510.     set index 0
  1511.     $argList foreach argName {
  1512.         if { $index > 0 } {
  1513.             set message "$message [lindex $selectorPartList $index]: $argName"
  1514.         } else {
  1515.             set message "$message: $argName"
  1516.         }
  1517.         set index [expr $index+1]
  1518.     }
  1519.     return $message
  1520. }
  1521.  
  1522. method STGConstructor::checkLocal {this} {
  1523.     set errornr 0
  1524.     set warningnr 0
  1525.       incr warningnr [$this checkFreeTextDQuote]
  1526.       incr warningnr [$this checkNew]
  1527.     return $errornr
  1528. }
  1529.  
  1530. method STGConstructor::checkFreeTextDQuote {this} {
  1531.     set warningnr 0
  1532.     if [regexp \" [$this getPropertyValue freeText] comment] {
  1533.         m4_warning $WST_REMOVEDQUOTECST [$this getSTName]
  1534.         incr warningnr 1
  1535.     }
  1536.     return $warningnr
  1537. }
  1538.  
  1539. method STGConstructor::checkNew {this} {
  1540.     # this code is greped from almost everywhere, so 
  1541.     # check local model can be executed without using
  1542.     # the target model, as was be done while checking
  1543.     # during generation.
  1544.     set warningnr 0
  1545.     # some pre stuff:
  1546.     # from getMethodImplementation:
  1547.     set parList [List new]
  1548.     foreach parameter [[$this ooplClass] creationParamSet] {
  1549.         $parList append [$this asSTName [$parameter getOriginalName]]
  1550.     }
  1551.     set selector [$this getSelector initialize $parList]
  1552.     set newSelector [$this getSelector new $parList]
  1553.     
  1554.     
  1555.     set isUserDefined 0
  1556.  
  1557.     # default for newRequired is 1
  1558.     $this newRequired 1
  1559.     # check every initializer to test whether newRequired must be set:
  1560.     foreach initializer [$this initializerSet] {
  1561.         $initializer check
  1562.     }
  1563.     # Generate restricted new if another instance creation method is generated
  1564.     if { ($newSelector != "new") && [$this newRequired] } {
  1565.         # RestrictedNew
  1566.         # find in the operationSet a class method corresponding to the 
  1567.         #  generated new by testing the method selector
  1568.         foreach method [[$this ooplClass] operationSet] {
  1569.             # determine whether class method
  1570.             if [$method isClassFeature] {
  1571.                 # determine method selector
  1572.                 set mSelector [$method getSelector]
  1573.                 if {($mSelector == "new") || \
  1574.                         ($mSelector == $newSelector)} {
  1575.                     # found, so now test whether isUserDef and try to reset
  1576.                     #  as done in STGOperation::generate :
  1577.                     set isUserDefined 1
  1578.                     if [$method isAbstract] {
  1579.                         [$method ooplClass] isAbstract 1
  1580.                         set isUserDefined 0
  1581.                     } else {
  1582.                         set tclGenerator [$method getPropertyValue method_impl]
  1583.                         if { $tclGenerator != "" } {
  1584.                             # when an error in TclCall then reset:
  1585.                             if { [$method checkTclCall $tclGenerator] != 0 } {
  1586.                                 set isUserDefined 0
  1587.                             }
  1588.                         }
  1589.                     }
  1590.                     # a match found so break
  1591.                     break
  1592.                 }
  1593.             }
  1594.         }
  1595.         if {$isUserDefined} {
  1596.             m4_warning $WST_AUTOCONSTRULES
  1597.             set isUserDefined 0 
  1598.         }
  1599.     } elseif [$this newRequired] {
  1600.         # New
  1601.         # find in the operationSet a class method corresponding to the 
  1602.         #  generated new by testing the method selector
  1603.         foreach method [[$this ooplClass] operationSet] {
  1604.             # determine whether class method
  1605.             if [$method isClassFeature] {
  1606.                 # determine selector
  1607.                 set mSelector [$method getSelector]
  1608.                 if {($mSelector == $newSelector) } {
  1609.                     # found, so now test whether isUserDef and try to reset
  1610.                     #  as done in STGOperation::generate :
  1611.                     set isUserDefined 1
  1612.                     if [$method isAbstract] {
  1613.                         [$method ooplClass] isAbstract 1
  1614.                         set isUserDefined 0
  1615.                     } else {
  1616.                         set tclGenerator [$method getPropertyValue method_impl]
  1617.                         if { $tclGenerator != "" } {
  1618.                             # when an error in TclCall then reset:
  1619.                             if { [$method checkTclCall $tclGenerator] != 0 } {
  1620.                                 set isUserDefined 0
  1621.                             }
  1622.                         }
  1623.                     }
  1624.                     # a match found so break
  1625.                     break
  1626.                 }
  1627.             }
  1628.         }
  1629.         if {$isUserDefined} {
  1630.             m4_warning $WST_DEFCONSTRULES
  1631.             set isUserDefined 0
  1632.         }
  1633.     }
  1634.     return $warningnr
  1635. }
  1636.  
  1637. # Do not delete this line -- regeneration end marker
  1638.  
  1639. if [isCommand CMConstructor] {
  1640.     Class  STGConstructorD : {STGConstructor CMConstructor} {
  1641.     }
  1642. } else {
  1643.     Class STGConstructorD : {STGConstructor OPConstructor} {    
  1644.     }
  1645. }
  1646.  
  1647. global mostDerivedOOPL ; set mostDerivedOOPL(OPConstructor) STGConstructorD
  1648.  
  1649. selfPromoter OPConstructor {this} {
  1650.     STGConstructorD promote $this
  1651. }
  1652.  
  1653.  
  1654. #---------------------------------------------------------------------------
  1655. #      File:           @(#)stgctorpar.tcl    /main/titanic/3
  1656.  
  1657.  
  1658. # Generator class for constructor parameters.
  1659.  
  1660. Class STGCtorParameter : {STGObject} {
  1661.     constructor
  1662.     method destructor
  1663.     method argumentName
  1664. }
  1665.  
  1666. constructor STGCtorParameter {class this name} {
  1667.     set this [STGObject::constructor $class $this $name]
  1668.     # Start constructor user section
  1669.     # End constructor user section
  1670.     return $this
  1671. }
  1672.  
  1673. method STGCtorParameter::destructor {this} {
  1674.     # Start destructor user section
  1675.     # End destructor user section
  1676. }
  1677.  
  1678.  
  1679. # Determine the name of the parameter when used as argument:
  1680. # base it on the name for an association attribute, or the type or name for another type
  1681. # of attribute.
  1682. #
  1683. method STGCtorParameter::argumentName {this} {
  1684.     set attrib [$this attrib]
  1685.     if { $attrib != "" } {        
  1686.     return [$attrib getArgumentName]
  1687.     } else {
  1688.     return [$this asArgument [$this getSTName]]
  1689.     }
  1690. }
  1691.  
  1692. # Do not delete this line -- regeneration end marker
  1693.  
  1694. if [isCommand CMCtorParameter] {
  1695.     Class  STGCtorParameterD : {STGCtorParameter CMCtorParameter} {
  1696.     }
  1697. } else {
  1698.     Class STGCtorParameterD : {STGCtorParameter OPCtorParameter} {    
  1699.     }
  1700. }
  1701.  
  1702. global mostDerivedOOPL ; set mostDerivedOOPL(OPCtorParameter) STGCtorParameterD
  1703.  
  1704. selfPromoter OPCtorParameter {this} {
  1705.     STGCtorParameterD promote $this
  1706. }
  1707.  
  1708.  
  1709. #---------------------------------------------------------------------------
  1710. #      File:           @(#)stgoperati.tcl    /main/titanic/4
  1711.  
  1712.  
  1713. # This class is the generator for user defined operations.
  1714.  
  1715. Class STGOperation : {STGObject} {
  1716.     constructor
  1717.     method destructor
  1718.     method generate
  1719.     method getMethodImplementation
  1720.     method generateAbstractMethod
  1721.     method generateDescription
  1722.     method doTclCall
  1723.     method getCategory
  1724.     method getClassCategory
  1725.     method getMethodAccess
  1726.     method getSelector
  1727.     method getOperatorSelector
  1728.     method getSpecialCharacter
  1729.     method checkLocal
  1730.     method checkTclCall
  1731.     method checkOperatorSelector
  1732.     method checkParams
  1733.     method checkFreeTextQuote
  1734.     method checkFreeTextDQuote
  1735.     attribute methodImplementation
  1736. }
  1737.  
  1738. constructor STGOperation {class this name} {
  1739.     set this [STGObject::constructor $class $this $name]
  1740.     # Start constructor user section
  1741.     # End constructor user section
  1742.     return $this
  1743. }
  1744.  
  1745. method STGOperation::destructor {this} {
  1746.     # Start destructor user section
  1747.     # End destructor user section
  1748. }
  1749.  
  1750.  
  1751. # Generates for user defined operation:
  1752. # * determines category and type (instance or class or user defined constructor).
  1753. # * determines message selector.
  1754. # * Gets a method implementation object.
  1755. # * Generates comment
  1756. # * Generates for the parameters
  1757. # * Generates for abstract methods.
  1758. # * Calls Tcl method if required.
  1759. #
  1760. method STGOperation::generate {this} {
  1761.     $this getMethodImplementation
  1762.     $this generateDescription
  1763.     
  1764.     foreach parameter [$this parameterSet] {
  1765.         $parameter generate [$this methodImplementation]
  1766.     }
  1767.     if [$this isAbstract] {
  1768.         $this generateAbstractMethod
  1769.         [$this methodImplementation] isUserDefined 0
  1770.         return
  1771.     }
  1772.     set tclGenerator [$this getPropertyValue method_impl]
  1773.     if { $tclGenerator != "" } {
  1774.         [$this methodImplementation] isUserDefined 0
  1775.         if { ![$this doTclCall $tclGenerator] } {
  1776.             [$this methodImplementation] isUserDefined 1
  1777.         }
  1778.     }
  1779.     $this methodImplementation ""
  1780. }
  1781.  
  1782.  
  1783. # Determines category, type and message selector and gets
  1784. # a method implementation object.
  1785. # Sets the methodImplementation association.
  1786. # If the operator name starts with operator,
  1787. # a redefined operator is assumed and translation is done.
  1788. #
  1789. method STGOperation::getMethodImplementation {this} {
  1790.     set category [$this getCategory]
  1791.     # If name starts with operator call operator naming. If this does not
  1792.     # work use normal naming
  1793.     if [string match operator* [$this getName]] {
  1794.         set selector [$this getOperatorSelector]
  1795.         if { $selector == "" } { 
  1796.             set selector [$this getSelector]
  1797.         }
  1798.     } else {
  1799.         set selector [$this getSelector]
  1800.     }
  1801.     # Now get the implementation object through the class implementation
  1802.     set classImpl [[$this ooplClass] classImplementation]
  1803.     if [$this isClassFeature] {
  1804.         set operation [$classImpl getClassMethodImplementation $selector $category]
  1805.     } else {
  1806.         set operation [$classImpl getInstanceMethodImplementation $selector $category]
  1807.     }
  1808.     # Now store implementation in this generator
  1809.     $this methodImplementation $operation
  1810.     
  1811.     [$this methodImplementation] isUserDefined 1
  1812. }
  1813.  
  1814.  
  1815. # Generates for an abstract method.
  1816. # Sets isAbstract attribute of corresponding class.
  1817. #
  1818. method STGOperation::generateAbstractMethod {this} {
  1819.     [$this methodImplementation] addExpression "self subclassResponsibility"
  1820.     [$this ooplClass] isAbstract 1
  1821. }
  1822.  
  1823.  
  1824. # Generates comment based on free text property.
  1825. #
  1826. method STGOperation::generateDescription {this} {
  1827.     if [regsub -all \" [$this getPropertyValue freeText] "" comment] {
  1828.         # "-s removed
  1829.     }
  1830.  
  1831.     [$this methodImplementation] comment $comment
  1832. }
  1833.  
  1834.  
  1835. # Calls Tcl Implementation Method if it 
  1836. # has been defined. Checks that it exists first.
  1837. #
  1838. method STGOperation::doTclCall {this generatorMethod} {
  1839.     set index [string first "::" $generatorMethod]
  1840.     if { $index > 0 } {
  1841.         set className [string range $generatorMethod 0 [expr $index-1]]
  1842.         set generatorMethod [string range $generatorMethod [expr $index+2] end]
  1843.     } else {
  1844.         set className STGCustom
  1845.     }
  1846.     # all error already generated
  1847.     if { [info commands $className] == "" } {
  1848.         # m4_error $EST_NOTCLMETHCLS [$this getSTName]
  1849.         return 0
  1850.     }
  1851.     if { [$className info supers] == "STGOperation" } {
  1852.         # m4_error $EST_TCLUPDDERIV $className
  1853.         return 0
  1854.     }
  1855.     if { [$className info supers] != "STGOperationD" } {
  1856.         # m4_error $EST_TCLGENDERIV $className
  1857.         return 0
  1858.     }
  1859.     if { [lsearch [$className info methods] $generatorMethod] == -1 } {
  1860.         # m4_error $NOTCLMETH $generatorMethod [$this getSTName]
  1861.         return 0
  1862.     }
  1863.  
  1864.     # Found : promote to custom class and execute method
  1865.     $className promote $this
  1866.     if [catch {    
  1867.         $this $generatorMethod [$this methodImplementation]
  1868.     } error] {
  1869.         m4_error $EST_CALL $generatorMethod $error
  1870.         return 0
  1871.     }
  1872.     return 1
  1873. }
  1874.  
  1875.  
  1876. # Returns category for this operation.
  1877. #
  1878. method STGOperation::getCategory {this} {
  1879.     # both method_access and classCategory are used
  1880.     # to determine the category.
  1881.     # Protected and Private have precedence:
  1882.     set category [$this getMethodAccess]
  1883.     if {$category != ""} {
  1884.         return $category
  1885.     }
  1886.     set category [$this getClassCategory]    
  1887.     return $category    
  1888. }
  1889.  
  1890. method STGOperation::getClassCategory {this} {
  1891.     # special naming for used defined constructor
  1892.     if { [$this getName] == "create" } {
  1893.         set category "instance creation"
  1894.     } else {
  1895.         set category "misc"
  1896.     }
  1897.     # Override default category if another one is specified
  1898.     set userCategory [$this getPropertyValue methodCategory]
  1899.     if { $userCategory != "" } {
  1900.         set category $userCategory
  1901.     }
  1902.     return $category    
  1903. }
  1904.  
  1905. method STGOperation::getMethodAccess {this} {
  1906.     set methodAccess [$this getPropertyValue method_access]
  1907.     if { $methodAccess == "Public" } {
  1908.         return ""
  1909.     } elseif { $methodAccess == "Protected" } {
  1910.         return "protected"
  1911.     } elseif { $methodAccess == "Private" } {
  1912.         return "private"
  1913.     } else {
  1914.         return ""
  1915.     }
  1916. }
  1917.  
  1918.  
  1919. # Returns selector for this operation.
  1920. #
  1921. method STGOperation::getSelector {this} {
  1922.     if { [$this getSTName] == "create" } {
  1923.         set selector "new"
  1924.     } else {
  1925.         set selector [$this getSTName]
  1926.     }
  1927.     
  1928.     set first 1
  1929.     foreach parameter [$this parameterSet] {
  1930.         set parName [$parameter getSTName]
  1931.         if $first {
  1932.             set first 0
  1933.             if { $selector == "new" } {
  1934.                 set selector "$parName:"
  1935.             } else {
  1936.                 set selector "$selector:"
  1937.             } 
  1938.         } else {
  1939.             set selector "$selector$parName:"
  1940.         }
  1941.     }
  1942.     return $selector
  1943. }
  1944.  
  1945.  
  1946. # Returns a Smalltalk compliant operator selector for this operation.
  1947. # It assumes that the name starts with 'operator'.
  1948. # Perform check on number of arguments.
  1949. #
  1950. method STGOperation::getOperatorSelector {this} {
  1951.     # Assume name starts with operator and strip it
  1952.     set operatorChars [string range [$this getName] 8 end]
  1953.     
  1954.     # Now check if it really is a special operator
  1955.     # if not return empty string
  1956.     if { $operatorChars == "" } {
  1957.         return ""
  1958.     }
  1959.     # - workaround
  1960.     if { $operatorChars == "-"} {
  1961.         if { [llength [$this parameterSet]] != 1 } {
  1962.             # m4_error $EST_ONEARG "-"
  1963.             return ""
  1964.         } 
  1965.         return "operator-"
  1966.     }
  1967.     # If the first character is not a special character we assume that
  1968.     # this is not a special operator
  1969.     set firstSpecialCharacter [$this getSpecialCharacter operatorChars]
  1970.     if { $firstSpecialCharacter == "" } {
  1971.         return ""
  1972.     }
  1973.     set secondSpecialCharacter ""
  1974.     if { $operatorChars != "" } {
  1975.         set secondSpecialCharacter [$this getSpecialCharacter operatorChars]
  1976.         if { $secondSpecialCharacter == "" } {
  1977.             # m4_error $EST_INVALIDSYNT [$this getName]
  1978.             return ""
  1979.         }
  1980.     }
  1981.     # More characters?? Not syntax compliant so ignore it.    
  1982.     if { $operatorChars != "" } {
  1983.         # m4_error $EST_INVALIDSYNT [$this getName]
  1984.         return ""
  1985.         }
  1986.     
  1987.     # Now check if there is exactly one argument
  1988.     if { [llength [$this parameterSet]] != 1 } {
  1989.         # m4_error $EST_ONEARG [$this getName]
  1990.         return ""
  1991.     } 
  1992.     return "$firstSpecialCharacter$secondSpecialCharacter"
  1993. }
  1994.  
  1995.  
  1996. # If <chars> starts with a special character, strip it from chars
  1997. # and return it.
  1998. #
  1999. method STGOperation::getSpecialCharacter {this chars} {
  2000.     upvar $chars characters 
  2001.     # Implementation comment: the - as selector name gives problems.
  2002.     # Workaround: do nothing with - here but just leave it as operator-
  2003.     # and convert in language model. Dirty, but it works
  2004.     if [string match "\[\+\\\*\~\<\>\@\%\|\&\?\!\]*" $characters] {
  2005.         set result [string index $characters 0]
  2006.         set characters [string range $characters 1 end]
  2007.         return $result
  2008.     }
  2009.     foreach name "DIV EQ COMMA" {
  2010.         if [string match $name* $characters] {
  2011.             set characters [string range $characters [string length $name] end]
  2012.             if { $name == "DIV" } {
  2013.                 return "\/"
  2014.             }
  2015.             if { $name == "EQ" } {
  2016.                 return "\="
  2017.             }
  2018.             return ","
  2019.         }
  2020.     }
  2021.     return ""
  2022. }
  2023.  
  2024. method STGOperation::checkLocal {this} {
  2025.     set errornr 0
  2026.     set warningnr 0
  2027.  
  2028.     incr errornr [$this checkOperatorSelector]
  2029.     if {$errornr == 0 } {
  2030.         # there may be an operator so first get that
  2031.         # one and if empty then check STName
  2032.         if { [$this getOperatorSelector] == "" } { 
  2033.             incr errornr [$this checkSTName]
  2034.         }
  2035.     }
  2036.     
  2037.     incr warningnr [$this checkFreeTextDQuote]
  2038.     incr errornr [$this checkTclCall]
  2039.     
  2040.     return $errornr
  2041. }
  2042.  
  2043. method STGOperation::checkTclCall {this} {
  2044.     set errornr 0
  2045.     set generatorMethod [$this getPropertyValue method_impl]
  2046.     if { $generatorMethod != "" } {
  2047.         set index [string first "::" $generatorMethod]
  2048.         if { $index > 0 } {
  2049.             set className [string range $generatorMethod 0 [expr $index-1]]
  2050.             set generatorMethod [string range $generatorMethod [expr $index+2] end]
  2051.         } else {
  2052.             set className STGCustom
  2053.         }
  2054.         if { [info commands $className] == "" } {
  2055.             m4_error $EST_NOTCLMETHCLS $className [$this getSTName]
  2056.             incr errornr 1
  2057.         } elseif { [$className info supers] == "STGOperation" } {
  2058.             m4_error $EST_TCLUPDDERIV $className
  2059.             incr errornr 1
  2060.         } elseif { [$className info supers] != "STGOperationD" } {
  2061.             m4_error $EST_TCLGENDERIV $className
  2062.             incr errornr 1
  2063.         } elseif { [lsearch [$className info methods] $generatorMethod] == -1 } {
  2064.             m4_error $EST_NOTCLMETH $generatorMethod [$this getSTName]
  2065.             incr errornr 1
  2066.         }
  2067.     }
  2068.     return $errornr
  2069. }
  2070.  
  2071. method STGOperation::checkOperatorSelector {this} {
  2072.     set errornr 0
  2073.     # Assume name starts with operator and strip it
  2074.     set operatorChars [string range [$this getName] 8 end]
  2075.     
  2076.     # Now check if it really is a special operator
  2077.     # if not return empty string
  2078.     if { $operatorChars == "" } {
  2079.         return $errornr
  2080.     } elseif { $operatorChars == "-"} {
  2081.     # - workaround
  2082.         if { [llength [$this parameterSet]] != 1 } {
  2083.             m4_error $EST_ONEARG "-"
  2084.             incr errornr 1
  2085.             return $errornr
  2086.         } 
  2087.         return $errornr
  2088.     } 
  2089.  
  2090.     # If the first character is not a special character we assume that
  2091.     # this is not a special operator
  2092.     set firstSpecialCharacter [$this getSpecialCharacter operatorChars]
  2093.     set secondSpecialCharacter ""
  2094.     if { $firstSpecialCharacter == "" } {
  2095.  
  2096.     } elseif { $operatorChars != "" } {
  2097.         set secondSpecialCharacter [$this getSpecialCharacter operatorChars]
  2098.         if { $secondSpecialCharacter == "" } {
  2099.             m4_error $EST_INVALIDSYNT [$this getName]
  2100.             incr errornr 1
  2101.         }
  2102.     } elseif { $operatorChars != "" } {
  2103.     # More characters?? Not syntax compliant so ignore it.    
  2104.         m4_error $EST_INVALIDSYNT [$this getName]
  2105.         incr errornr 1
  2106.     } elseif { [llength [$this parameterSet]] != 1 } {
  2107.     # Now check if there is exactly one argument
  2108.         m4_error $EST_ONEARG [$this getName]
  2109.         incr errornr 1
  2110.     } 
  2111.     return $errornr
  2112. }
  2113.  
  2114. method STGOperation::checkParams {this} {
  2115.     set errornr 0
  2116.  
  2117.     if { [$this getSTName] == "create" } {
  2118.         set selector "new"
  2119.     } else {
  2120.         set selector [$this getSTName]
  2121.     }
  2122.     
  2123.     set first 1
  2124.     foreach parameter [$this parameterSet] {
  2125.         if $first {
  2126.             set first 0
  2127.             if { $selector == "new" } {
  2128.                 set parName [$parameter getSTName]
  2129.                 incr errornr [$parameter checkSTName]
  2130.                 set selector "$parName:"
  2131.             } else {
  2132.                 set selector "$selector:"
  2133.             } 
  2134.         } else {
  2135.             set selector "$selector$parName:"
  2136.             incr errornr [$parameter checkSTName]
  2137.         }
  2138.     }
  2139.     return $errornr
  2140. }
  2141.  
  2142. method STGOperation::checkFreeTextQuote {this} {
  2143.     set warningnr 0
  2144.     if [regexp \' [$this getPropertyValue freeText] comment] {
  2145.         m4_warning $WST_REMOVEQUOTE [$this getSTName]
  2146.         incr warningnr 1
  2147.     }
  2148.     return $warningnr
  2149. }
  2150.  
  2151. method STGOperation::checkFreeTextDQuote {this} {
  2152.     set warningnr 0
  2153.     if [regexp \" [$this getPropertyValue freeText] comment] {
  2154.         m4_warning $WST_REMOVEDQUOTE [$this getSTName]
  2155.         incr warningnr 1
  2156.     }
  2157.     return $warningnr
  2158. }
  2159.  
  2160. # Do not delete this line -- regeneration end marker
  2161.  
  2162. if [isCommand CMOperation] {
  2163.     Class  STGOperationD : {STGOperation CMOperation} {
  2164.     }
  2165. } else {
  2166.     Class STGOperationD : {STGOperation OPOperation} {    
  2167.     }
  2168. }
  2169.  
  2170. global mostDerivedOOPL ; set mostDerivedOOPL(OPOperation) STGOperationD
  2171.  
  2172. selfPromoter OPOperation {this} {
  2173.     STGOperationD promote $this
  2174. }
  2175.  
  2176.  
  2177. #---------------------------------------------------------------------------
  2178. #      File:           @(#)stgoperpar.tcl    /main/titanic/4
  2179.  
  2180.  
  2181. # Generator for operation parameters.
  2182.  
  2183. Class STGOperParameter : {STGObject} {
  2184.     constructor
  2185.     method destructor
  2186.     method generate
  2187.     method argumentName
  2188. }
  2189.  
  2190. constructor STGOperParameter {class this name} {
  2191.     set this [STGObject::constructor $class $this $name]
  2192.     # Start constructor user section
  2193.     # End constructor user section
  2194.     return $this
  2195. }
  2196.  
  2197. method STGOperParameter::destructor {this} {
  2198.     # Start destructor user section
  2199.     # End destructor user section
  2200. }
  2201.  
  2202.  
  2203. # Generates argument name in method implementation and
  2204. # default value if required.
  2205. #
  2206. method STGOperParameter::generate {this methodImplementation} {
  2207.     set argName [$this getArgumentName]
  2208.     set argName [$methodImplementation getNewUniqueArgumentName $argName]
  2209.     set defaultValue [$this getPropertyValue default_value]
  2210.  
  2211.     # If there is a default value add a conditional assignment
  2212.     if { $defaultValue!= "" } {
  2213.         set assign [$methodImplementation addExpression \
  2214.                         "$argName isNil ifTrue:"]
  2215.         $assign addExpression "$argName := $defaultValue"
  2216.     }
  2217. }
  2218.  
  2219.  
  2220. # Determine the name of the parameter when used as argument:
  2221. # base it on the type if it exists and the name otherwise.
  2222. #
  2223. method STGOperParameter::argumentName {this} {
  2224.     set type [$this ooplType]
  2225.     if { $type != "" } {
  2226.         if { [$type getType3GL] != "" } {
  2227.             return [$this asSTName [$this asArgument [$type getType3GL]]]
  2228.         } elseif { [$type getName] != "" } {
  2229.             return [$this asSTName [$this asArgument [$type getName]]]
  2230.         }
  2231.     }
  2232.     return [$this asArgument [$this getSTName]]
  2233. }
  2234.  
  2235. # Do not delete this line -- regeneration end marker
  2236.  
  2237. if [isCommand CMOperParameter] {
  2238.     Class  STGOperParameterD : {STGOperParameter CMOperParameter} {
  2239.     }
  2240. } else {
  2241.     Class STGOperParameterD : {STGOperParameter OPOperParameter} {    
  2242.     }
  2243. }
  2244.  
  2245. global mostDerivedOOPL ; set mostDerivedOOPL(OPOperParameter) STGOperParameterD
  2246.  
  2247. selfPromoter OPOperParameter {this} {
  2248.     STGOperParameterD promote $this
  2249. }
  2250.  
  2251.  
  2252. #---------------------------------------------------------------------------
  2253. #      File:           @(#)stgqualifi.tcl    /main/titanic/4
  2254.  
  2255.  
  2256. # Qualifier generator class, only used for generating argument names.
  2257.  
  2258. Class STGQualifier : {STGObject} {
  2259.     constructor
  2260.     method destructor
  2261.     method argumentName
  2262. }
  2263.  
  2264. constructor STGQualifier {class this name} {
  2265.     set this [STGObject::constructor $class $this $name]
  2266.     # Start constructor user section
  2267.     # End constructor user section
  2268.     return $this
  2269. }
  2270.  
  2271. method STGQualifier::destructor {this} {
  2272.     # Start destructor user section
  2273.     # End destructor user section
  2274. }
  2275.  
  2276.  
  2277. # Returns name for this qualifier when used as an argument.
  2278. # base it on the type if it exists
  2279. # or the name otherwise.
  2280. #
  2281. method STGQualifier::argumentName {this} {
  2282.     set type [$this ooplType]
  2283.     if { $type != "" } {
  2284.     if { [$type getType3GL] != "" } {
  2285.         return [$this asSTName [$this asArgument [$type getType3GL]]]
  2286.     }  elseif { [$type getName] != "" } {
  2287.         return [$this asSTName [$this asArgument [$type getName]]]
  2288.     }
  2289.     }
  2290.     return [$this asArgument [$this getSTName]]
  2291. }
  2292.  
  2293. # Do not delete this line -- regeneration end marker
  2294.  
  2295. if [isCommand CMQualifier] {
  2296.     Class  STGQualifierD : {STGQualifier CMQualifier} {
  2297.     }
  2298. } else {
  2299.     Class STGQualifierD : {STGQualifier OPQualifier} {    
  2300.     }
  2301. }
  2302.  
  2303. global mostDerivedOOPL ; set mostDerivedOOPL(OPQualifier) STGQualifierD
  2304.  
  2305. selfPromoter OPQualifier {this} {
  2306.     STGQualifierD promote $this
  2307. }
  2308.  
  2309.  
  2310. #---------------------------------------------------------------------------
  2311. #      File:           @(#)stgqualini.tcl    /main/titanic/3
  2312.  
  2313.  
  2314. # Generator for qualifier initializers. 
  2315. # Qualifier initializers are generated in qualified link
  2316. # associations.
  2317.  
  2318. Class STGQualInitializer : {STGObject} {
  2319.     constructor
  2320.     method destructor
  2321.     method generate
  2322.     method check
  2323. }
  2324.  
  2325. constructor STGQualInitializer {class this name} {
  2326.     set this [STGObject::constructor $class $this $name]
  2327.     # Start constructor user section
  2328.     # End constructor user section
  2329.     return $this
  2330. }
  2331.  
  2332. method STGQualInitializer::destructor {this} {
  2333.     # Start destructor user section
  2334.     # End destructor user section
  2335. }
  2336.  
  2337.  
  2338. # Get argument name for initializer and add it to constructor parameters.
  2339. #
  2340. method STGQualInitializer::generate {this} {
  2341.     set constructor [[$this constructor] methodImplementation]
  2342.     set argName [[$this qualifier] getArgumentName]
  2343.     $constructor getUniqueArgumentName [$this getSTName] $argName
  2344. }
  2345.  
  2346.  
  2347. # For computing newRequired in 
  2348. # STGConstructor
  2349. #
  2350. method STGQualInitializer::check {this} {
  2351.     set errornr 0
  2352.     incr errornr [$this checkSTName]
  2353.     return $errornr
  2354. }
  2355.  
  2356. # Do not delete this line -- regeneration end marker
  2357.  
  2358. if [isCommand CMQualInitializer] {
  2359.     Class  STGQualInitializerD : {STGQualInitializer CMQualInitializer} {
  2360.     }
  2361. } else {
  2362.     Class STGQualInitializerD : {STGQualInitializer OPQualInitializer} {    
  2363.     }
  2364. }
  2365.  
  2366. global mostDerivedOOPL ; set mostDerivedOOPL(OPQualInitializer) STGQualInitializerD
  2367.  
  2368. selfPromoter OPQualInitializer {this} {
  2369.     STGQualInitializerD promote $this
  2370. }
  2371.  
  2372.  
  2373. #---------------------------------------------------------------------------
  2374. #      File:           @(#)stgsupercl.tcl    /main/titanic/3
  2375.  
  2376.  
  2377. # This is the generator for super class initializers.
  2378.  
  2379. Class STGSuperClassInitializer : {STGObject} {
  2380.     constructor
  2381.     method destructor
  2382.     method generate
  2383.     method check
  2384. }
  2385.  
  2386. constructor STGSuperClassInitializer {class this name} {
  2387.     set this [STGObject::constructor $class $this $name]
  2388.     # Start constructor user section
  2389.     # End constructor user section
  2390.     return $this
  2391. }
  2392.  
  2393. method STGSuperClassInitializer::destructor {this} {
  2394.     # Start destructor user section
  2395.     # End destructor user section
  2396. }
  2397.  
  2398.  
  2399. # Determines parameter names for super call.
  2400. # Generates the call of the initialize method in the super class and
  2401. # inserts it as first constructor statement.
  2402. # Sets newRequired in the constructor generator:
  2403. # 0 if the class to which this initializer
  2404. # belongs has the same constructor parameters
  2405. # as the superclass, 1 otherwise.
  2406. #
  2407. method STGSuperClassInitializer::generate {this} {
  2408.     if [[$this ooplClass] isExternal] {
  2409.         return
  2410.     }
  2411.     
  2412.     set constructor [$this constructor]
  2413.     set initialize [$constructor methodImplementation]
  2414.     
  2415.     set parList [List new]
  2416.     set argList [List new]
  2417.     # get parameter and argument list for super class constructor
  2418.     foreach parameter [$this parameterSet] {
  2419.         set parName [$this asSTName [$parameter getOriginalName]]
  2420.         $parList append $parName
  2421.         set argName [$parameter getArgumentName]
  2422.         $argList append [$initialize getUniqueArgumentName $parName $argName]
  2423.     }
  2424.  
  2425.     set superNewSelector [$constructor getSelector new $parList]
  2426.     set superInitSelector [$constructor getSelector initialize $parList]
  2427.     set superInitMessage [$constructor getMessage $superInitSelector $argList]
  2428.  
  2429.     # Insert message to initialize in super as first expression
  2430.     $initialize insertExpression "super $superInitMessage"
  2431.  
  2432.     # Now compute newRequired
  2433.     # needed if difference in constructor parameters or abstract property 
  2434.     set thisAbstract [[$constructor ooplClass] isAbstract]
  2435.     set superAbstract [[$this ooplClass] isAbstract]
  2436.     if { ([$constructor newSelector] == $superNewSelector) && \
  2437.              ($thisAbstract == $superAbstract) } {
  2438.         $constructor newRequired 0
  2439.     }
  2440. }
  2441.  
  2442.  
  2443. # For computing newRequired in 
  2444. # STGConstructor
  2445. #
  2446. method STGSuperClassInitializer::check {this} {
  2447.     #body is an abstract of generate!
  2448.     set errornr 0
  2449.     if [[$this ooplClass] isExternal] {
  2450.         return $errornr
  2451.     }
  2452.     incr errornr [$this checkSTName]
  2453.  
  2454.     set constructor [$this constructor]
  2455.  
  2456.     set parList [List new]
  2457.     # get parameter list for super class constructor
  2458.     foreach parameter [$this parameterSet] {
  2459.         set parName [$this asSTName [$parameter getOriginalName]]
  2460.         $parList append $parName
  2461.     }
  2462.  
  2463.     set superNewSelector [$constructor getSelector new $parList]
  2464.  
  2465.     # Now compute newRequired
  2466.     # needed if difference in constructor parameters or abstract property 
  2467.     set thisAbstract [[$constructor ooplClass] isAbstract]
  2468.     set superAbstract [[$this ooplClass] isAbstract]
  2469.     if { ([$constructor newSelector] == $superNewSelector) && \
  2470.              ($thisAbstract == $superAbstract) } {
  2471.         $constructor newRequired 0
  2472.     }
  2473.     return $errornr
  2474. }
  2475.  
  2476. # Do not delete this line -- regeneration end marker
  2477.  
  2478. if [isCommand CMSuperClassInitializer] {
  2479.     Class  STGSuperClassInitializerD : {STGSuperClassInitializer CMSuperClassInitializer} {
  2480.     }
  2481. } else {
  2482.     Class STGSuperClassInitializerD : {STGSuperClassInitializer OPSuperClassInitializer} {    
  2483.     }
  2484. }
  2485.  
  2486. global mostDerivedOOPL ; set mostDerivedOOPL(OPSuperClassInitializer) STGSuperClassInitializerD
  2487.  
  2488. selfPromoter OPSuperClassInitializer {this} {
  2489.     STGSuperClassInitializerD promote $this
  2490. }
  2491.  
  2492.  
  2493. #---------------------------------------------------------------------------
  2494. #      File:           @(#)stgassocma.tcl    /main/titanic/2
  2495.  
  2496.  
  2497. # This is the generator for normal associations with multiplicity many.
  2498.  
  2499. Class STGAssocMany : {STGAssocGen} {
  2500.     constructor
  2501.     method destructor
  2502.     method generateData
  2503.     method generateSet
  2504.     method generateGet
  2505.     method generateRemove
  2506.     method generateSetRef
  2507.     method generateRemoveRef
  2508.     method generateRemoveRefMessage
  2509.     method generateSetRefMessage
  2510.     method generateRemoveMessage
  2511.     method generateSetCode
  2512.     method generateRemoveCode
  2513.     method generateInitialize
  2514.     method generateReleaseCode
  2515.     method generatePrintCode
  2516.     method removeRequired
  2517. }
  2518.  
  2519. constructor STGAssocMany {class this assocAttr} {
  2520.     set this [STGAssocGen::constructor $class $this $assocAttr]
  2521.     # Start constructor user section
  2522.     # End constructor user section
  2523.     return $this
  2524. }
  2525.  
  2526. method STGAssocMany::destructor {this} {
  2527.     # Start destructor user section
  2528.     # End destructor user section
  2529.     $this STGAssocGen::destructor
  2530. }
  2531.  
  2532.  
  2533. # Generates instance variable to implement this association
  2534. # an sets variableName. The name of the instance
  2535. # variable is <roleName>Set.
  2536. #
  2537. method STGAssocMany::generateData {this} {
  2538.     set name "[$this roleName]Set"
  2539.     [$this classImplementation] addInstanceVariable $name
  2540.     $this variableName $name
  2541. }
  2542.  
  2543.  
  2544. # Generates the set method that adds to the association.
  2545. #
  2546. method STGAssocMany::generateSet {this} {
  2547.     set selector "add[cap [$this roleName]]:"
  2548.     set set [$this getModifyImplementation $selector]
  2549.     if { $set == "" } {
  2550.     return
  2551.     }
  2552.     $this generateSetCode $set [$this opposite]
  2553. }
  2554.  
  2555.  
  2556. # Generates the get method which executes a block for all associated objects.
  2557. #
  2558. method STGAssocMany::generateGet {this} {
  2559.     set selector "[$this roleName]SetDo:"
  2560.     set get [$this getAccessImplementation $selector]
  2561.     if { $get == "" } {
  2562.     return
  2563.     }
  2564.  
  2565.     $get addArgument aBlock
  2566.     $get addExpression "[$this variableName] do: aBlock"
  2567. }
  2568.  
  2569.  
  2570. # Generate the set method remove which removes an element from the association.
  2571. #
  2572. method STGAssocMany::generateRemove {this} {
  2573.     set selector "remove[cap [$this roleName]]:"
  2574.     set remove [$this getRemoveImplementation $selector]    
  2575.     if { $remove == "" } {
  2576.     return
  2577.     }
  2578.     $this generateRemoveCode $remove [$this opposite]
  2579. }
  2580.  
  2581.  
  2582. # Generates the implementation method to add to the instance variable for the association.
  2583. #
  2584. method STGAssocMany::generateSetRef {this} {
  2585.     set selector "add[cap [$this roleName]]Ref:"
  2586.     set setRef [$this getPrivateImplementation $selector]
  2587.     $this generateSetCode $setRef ""
  2588. }
  2589.  
  2590.  
  2591. # Generates the implementation method to remove an element from the
  2592. # instance variable for the association.
  2593. #
  2594. method STGAssocMany::generateRemoveRef {this} {
  2595.     set selector "remove[cap [$this roleName]]Ref:"
  2596.     set removeRef [$this getPrivateImplementation $selector]    
  2597.     $this generateRemoveCode $removeRef ""
  2598. }
  2599.  
  2600.  
  2601. # Generates an expression in block that sends a removeRef message to
  2602. # object with parameter <parameter>.
  2603. #
  2604. method STGAssocMany::generateRemoveRefMessage {this block object parameter args} {
  2605.     set removeRefName "remove[cap [$this roleName]]Ref:"
  2606.     $block addExpression "$object $removeRefName $parameter"
  2607. }
  2608.  
  2609.  
  2610. # Generates an expression in block that sends a SetRef message to object
  2611. # with parameter <parameter>.
  2612. #
  2613. method STGAssocMany::generateSetRefMessage {this block object parameter args} {
  2614.     set setRefName "add[cap [$this roleName]]Ref:"
  2615.     $block addExpression "$object $setRefName $parameter"
  2616. }
  2617.  
  2618.  
  2619. # Does nothing: present for interface consistency.
  2620. #
  2621. method STGAssocMany::generateRemoveMessage {this block object args} {
  2622.     # Do nothing: remove must not be called for many associations
  2623. }
  2624.  
  2625.  
  2626. # Generates the expressions for a set method in block.
  2627. #
  2628. method STGAssocMany::generateSetCode {this block opposite} {
  2629.     set name [$this variableName]
  2630.     set parName [$this parameterName]
  2631.     set selector [$block selector]
  2632.  
  2633.     $block addArgument $parName
  2634.  
  2635.     set upper [$this upperConstraint]
  2636.     if { $upper != "" } {
  2637.     set block [$this generateConstraintCheck $selector $block $name $upper upper]
  2638.     }
  2639.  
  2640.     if { $opposite != "" } {
  2641.     $opposite generateRemoveMessage $block $parName
  2642.     $opposite generateSetRefMessage $block $parName self
  2643.     }
  2644.  
  2645.     # add to Set. If it is an orderedCollection check for no duplicates
  2646.     if { [$this setType] == "OrderedCollection" } {
  2647.     set block [$this generateIncludesCheck $block $name $parName]
  2648.     }
  2649.     $block addExpression "$name add: $parName"
  2650. }
  2651.  
  2652.  
  2653. # Generates the expressions for the remove method in block.
  2654. #
  2655. method STGAssocMany::generateRemoveCode {this block opposite} {
  2656.     set name [$this variableName]
  2657.     set parName [$this parameterName]    
  2658.     set selector [$block selector]
  2659.     $block addArgument $parName
  2660.  
  2661.     # existence check must be done separately with includes:
  2662.     set lower [$this lowerConstraint]
  2663.     if { $lower != "" } {
  2664.     $this generateExistenceCheck $selector $block $name $parName
  2665.     set block [$this generateConstraintCheck $selector $block $name $lower lower]
  2666.     }
  2667.  
  2668.     if { $opposite != "" } {
  2669.     $opposite generateRemoveRefMessage $block $parName self
  2670.     }
  2671.  
  2672.     # Remove it. Different for constraint and no constraint:
  2673.     # in the constraint ifAbsent: is not needed because an includes:
  2674.     # test was already generated
  2675.     set removeText "$name remove: $parName"
  2676.     if { $lower == "" } {
  2677.     set  removeExpr [$block addExpression "$removeText ifAbsent:"]
  2678.     $removeExpr addExpression [$this getErrorMessage ASSOC_OBJ_NOT_FOUND $selector]
  2679.     } else { 
  2680.     $block addExpression $removeText
  2681.     }
  2682. }
  2683.  
  2684.  
  2685. # Generates additions to initialize method, if it exists.
  2686. #
  2687. method STGAssocMany::generateInitialize {this} {
  2688.     set initialize [[$this classImplementation] initialize]
  2689.     if { $initialize == "" } {
  2690.     return
  2691.     }
  2692.  
  2693.     $initialize addExpression "[$this variableName] := [$this setType] new"
  2694.     if { [$this lowerConstraint] != "" } {
  2695.     set comment "Warning: put association [$this roleName] in consistent state"
  2696.     $initialize addCommentLine $comment
  2697.     }
  2698. }
  2699.  
  2700.  
  2701. # Generates expressions for addition to release in block.
  2702. #
  2703. method STGAssocMany::generateReleaseCode {this block} {
  2704.     set name [$this variableName]
  2705.     set parName [$this parameterName]
  2706.     if { [$this opposite] != "" } {
  2707.     set setBlock [$block addExpression "$name do:"]
  2708.     $setBlock addArgument $parName
  2709.     [$this opposite] generateRemoveRefMessage $setBlock $parName self
  2710.     }
  2711.     $block addExpression "$name := nil"
  2712. }
  2713.  
  2714.  
  2715. # Generates expressions in block to print information about the association.
  2716. #
  2717. method STGAssocMany::generatePrintCode {this block} {
  2718.     set name [$this variableName]
  2719.     $block addExpression "aStream cr; nextPutAll: \'$name:\' displayString"
  2720.     set printAll [$block addExpression "$name inject: 1 into:"]
  2721.     $printAll addArgument "count"
  2722.     $printAll addArgument "element"
  2723.     $printAll addExpression "aStream cr; tab; nextPutAll: count printString"
  2724.     $printAll addExpression "element printVars: aStream withIndent: 2"
  2725.     $printAll addExpression "count + 1"
  2726. }
  2727.  
  2728.  
  2729. # Returns 0.
  2730. #
  2731. method STGAssocMany::removeRequired {this} {
  2732.     return 0
  2733. }
  2734.  
  2735. # Do not delete this line -- regeneration end marker
  2736.  
  2737.  
  2738.  
  2739. #---------------------------------------------------------------------------
  2740. #      File:           @(#)stgassocon.tcl    /main/titanic/2
  2741.  
  2742.  
  2743. # This is the generator for normal associations with multiplicity one.
  2744.  
  2745. Class STGAssocOne : {STGAssocGen} {
  2746.     constructor
  2747.     method destructor
  2748.     method generateData
  2749.     method generateSet
  2750.     method generateGet
  2751.     method generateRemove
  2752.     method generateSetRef
  2753.     method generateRemoveRef
  2754.     method generateRemoveRefMessage
  2755.     method generateSetRefMessage
  2756.     method generateRemoveMessage
  2757.     method generateSetCode
  2758.     method generateRemoveCode
  2759.     method generateInitialize
  2760.     method generateInitializeCode
  2761.     method generateReleaseCode
  2762.     method generatePrintCode
  2763.     method removePermitted
  2764. }
  2765.  
  2766. constructor STGAssocOne {class this assocAttr} {
  2767.     set this [STGAssocGen::constructor $class $this $assocAttr]
  2768.     # Start constructor user section
  2769.     # End constructor user section
  2770.     return $this
  2771. }
  2772.  
  2773. method STGAssocOne::destructor {this} {
  2774.     # Start destructor user section
  2775.     # End destructor user section
  2776.     $this STGAssocGen::destructor
  2777. }
  2778.  
  2779.  
  2780. # Generates instance variable to implement this association 
  2781. # and sets variableName. The name of the instance
  2782. # variable is the roleName.
  2783. #
  2784. method STGAssocOne::generateData {this} {
  2785.     [$this classImplementation] addInstanceVariable [$this roleName]
  2786.     $this variableName [$this roleName]
  2787. }
  2788.  
  2789.  
  2790. # Generates the set method to set the association.
  2791. #
  2792. method STGAssocOne::generateSet {this} {
  2793.     set selector "set[cap [$this roleName]]:"
  2794.     set set [$this getModifyImplementation $selector]
  2795.     if { $set != "" } {
  2796.         $this generateSetCode $set [$this opposite]
  2797.     }
  2798. }
  2799.  
  2800.  
  2801. # Generates the get method which returns the associated object.
  2802. #
  2803. method STGAssocOne::generateGet {this} {
  2804.     set selector "get[cap [$this roleName]]"
  2805.     set get [$this getAccessImplementation $selector]
  2806.     if { $get != "" } {
  2807.         $get addExpression "\^[$this variableName]"
  2808.     }
  2809. }
  2810.  
  2811.  
  2812. # Generates the remove method to remove the association.
  2813. #
  2814. method STGAssocOne::generateRemove {this} {
  2815.     set selector "remove[cap [$this roleName]]"
  2816.     set remove [$this getRemoveImplementation $selector]
  2817.     if  { $remove != "" } {
  2818.         $this generateRemoveCode $remove [$this opposite]
  2819.     }
  2820. }
  2821.  
  2822.  
  2823. # Generates the implementation method to set the instance variable for the association.
  2824. #
  2825. method STGAssocOne::generateSetRef {this} {
  2826.     set selector "set[cap [$this roleName]]Ref:"
  2827.     set setRef [$this getPrivateImplementation $selector]
  2828.     $this generateSetCode $setRef ""
  2829. }
  2830.  
  2831.  
  2832. # Does nothing: this method is here to keep the interfaces of the association generators consistent.
  2833. #
  2834. method STGAssocOne::generateRemoveRef {this} {
  2835.     # Not needed for one association: bye
  2836. }
  2837.  
  2838.  
  2839. # Generates an expression in block that sends a SetRef message to object with parameter nil.
  2840. #
  2841. method STGAssocOne::generateRemoveRefMessage {this block object parameter args} {
  2842.     $this generateSetRefMessage $block $object nil
  2843. }
  2844.  
  2845.  
  2846. # Generates an expression in block that sends a SetRef message to object with argument parameter.
  2847. #
  2848. method STGAssocOne::generateSetRefMessage {this block object parameter args} {
  2849.     set setRefName "set[cap [$this roleName]]Ref:"
  2850.     $block addExpression "$object $setRefName $parameter"
  2851. }
  2852.  
  2853.  
  2854. # Generates an expression in block that sends a remove message to object.
  2855. #
  2856. method STGAssocOne::generateRemoveMessage {this block object args} {
  2857.     set removeName "remove[cap [$this roleName]]"
  2858.     $block addExpression "$object $removeName"
  2859. }
  2860.  
  2861.  
  2862. # Generates the expressions for a set method in block.
  2863. #
  2864. method STGAssocOne::generateSetCode {this block opposite} {
  2865.     set name [$this variableName]
  2866.     set parName [$this parameterName]
  2867.     $block addArgument $parName
  2868.  
  2869.     # if it is mandatory generate a nil check and an inequality check    
  2870.     if [[$this assocAttr] isMandatory] {
  2871.     $this generateNilCheck $block $parName
  2872.     }
  2873.  
  2874.     if { $opposite != "" } {
  2875.     if [[$this assocAttr] isMandatory] {
  2876.         set compare "$name ~~ $parName"
  2877.         set block [$block addExpression "($compare) ifTrue:"]
  2878.     }
  2879.     # remove old links
  2880.     $opposite generateRemoveMessage $block $parName
  2881.     set removeBlock $block
  2882.     if { ![[$this assocAttr] isMandatory]} {
  2883.         set removeBlock [$block addExpression "$name isNil ifFalse:"]
  2884.     }
  2885.     $opposite generateRemoveRefMessage $removeBlock $name self
  2886.     # set new link
  2887.     $opposite generateSetRefMessage $block $parName self
  2888.     }
  2889.  
  2890.     $block addExpression "$name := $parName"    
  2891. }
  2892.  
  2893.  
  2894. # Generates the expressions for the remove method in block.
  2895. #
  2896. method STGAssocOne::generateRemoveCode {this block opposite args} {
  2897.     set name [$this variableName]
  2898.     # if the association is not mandatory the instance var may be nil
  2899.     # generate remove for opposite if it exists
  2900.  
  2901.     if { $opposite != "" } {
  2902.     if { ![[$this assocAttr] isMandatory] } {
  2903.         set nilCheck "$name isNil ifFalse:"
  2904.         set block [$block addExpression $nilCheck]
  2905.     }
  2906.     $opposite generateRemoveRefMessage $block $name self $args
  2907.     }
  2908.  
  2909.     $block addExpression "$name := nil"
  2910. }
  2911.  
  2912.  
  2913. # Generates addition to initialize method (if it exists).
  2914. #
  2915. method STGAssocOne::generateInitialize {this} {
  2916.     set initialize [[$this classImplementation] initialize]
  2917.  
  2918.     # If there is no initialize method nothing can be generated
  2919.     if { $initialize == "" } { 
  2920.     return 
  2921.     }
  2922.    
  2923.     $this generateInitializeCode $initialize 
  2924. }
  2925.  
  2926.  
  2927. # Generates the expressions for the addition to initialize in block.
  2928. #
  2929. method STGAssocOne::generateInitializeCode {this block args} {
  2930.     set name [$this variableName]
  2931.     set parName [$this parameterName]
  2932.  
  2933.     if { [[$this assocAttr] hasInitializer] == 1 } {
  2934.     set parName [$block getUniqueArgumentName [$this roleName] $parName]    
  2935.     $this generateNilCheck $block $parName
  2936.     if { [$this opposite] != "" } {
  2937.         [$this opposite] generateRemoveMessage $block $parName $args
  2938.         [$this opposite] generateSetRefMessage $block $parName self $args
  2939.     }
  2940.     $block addExpression "$name := $parName"
  2941.     } else {
  2942.     $block addExpression "$name := nil"
  2943.     }    
  2944. }
  2945.  
  2946.  
  2947. # Generates additions to release in block.
  2948. #
  2949. method STGAssocOne::generateReleaseCode {this block} {
  2950.     $this generateRemoveCode $block [$this opposite]
  2951. }
  2952.  
  2953.  
  2954. # Generates expressions in block to print information about the association.
  2955. #
  2956. method STGAssocOne::generatePrintCode {this block} {
  2957.     set name [$this variableName]
  2958.     $block addExpression "aStream cr; nextPutAll: \'$name: \' displayString"
  2959.     set printOther [$block addExpression "$name isNil ifFalse:"]
  2960.     $printOther addExpression "$name printVars: aStream withIndent: 1"
  2961. }
  2962.  
  2963.  
  2964. # Returns 0 if this association is mandatory, else defaults to RemovePermitted
  2965. # in STGAssocGen.
  2966. #
  2967. method STGAssocOne::removePermitted {this} {
  2968.     if [[$this assocAttr] isMandatory] {
  2969.     return 0
  2970.     }
  2971.     return [$this STGAssocGen::removePermitted] 
  2972. }
  2973.  
  2974. # Do not delete this line -- regeneration end marker
  2975.  
  2976.  
  2977.  
  2978. #---------------------------------------------------------------------------
  2979. #      File:           @(#)stgmanyqua.tcl    /main/titanic/2
  2980.  
  2981.  
  2982. # This is the generator for qualified associations with multiplicity many.
  2983.  
  2984. Class STGManyQual : {STGAssocGen} {
  2985.     constructor
  2986.     method destructor
  2987.     method generateData
  2988.     method generateSet
  2989.     method generateGet
  2990.     method generateRemove
  2991.     method generateSetRef
  2992.     method generateRemoveRef
  2993.     method generateRemoveRefMessage
  2994.     method generateSetRefMessage
  2995.     method generateRemoveMessage
  2996.     method generateSetCode
  2997.     method generateRemoveCode
  2998.     method generateInitialize
  2999.     method generateReleaseCode
  3000.     method generatePrintCode
  3001.     method removeRequired
  3002. }
  3003.  
  3004. constructor STGManyQual {class this assocAttr} {
  3005.     set this [STGAssocGen::constructor $class $this $assocAttr]
  3006.     # Start constructor user section
  3007.     # End constructor user section
  3008.     return $this
  3009. }
  3010.  
  3011. method STGManyQual::destructor {this} {
  3012.     # Start destructor user section
  3013.     # End destructor user section
  3014.     $this STGAssocGen::destructor
  3015. }
  3016.  
  3017.  
  3018. # Generates instance variable to implement this association and sets
  3019. # variableName to <roleName>SetDict.
  3020. #
  3021. method STGManyQual::generateData {this} {
  3022.     set name "[$this roleName]SetDict"
  3023.     [$this classImplementation] addInstanceVariable $name
  3024.     $this variableName $name
  3025. }
  3026.  
  3027.  
  3028. # Generates the set method to set the association for a given qualifier.
  3029. #
  3030. method STGManyQual::generateSet {this} {
  3031.     set selector "add[cap [$this roleName]]:at:"
  3032.     set set [$this getModifyImplementation $selector]
  3033.     if { $set == "" } {
  3034.     return
  3035.     }
  3036.     $this generateSetCode $set [$this opposite]
  3037. }
  3038.  
  3039.  
  3040. # Generates the get methods:
  3041. # * One that executes a given block for each object associated for a given qualifier.
  3042. # * One that executes a given block for each qualifier.
  3043. #
  3044. method STGManyQual::generateGet {this} {
  3045.     set selector "[$this roleName]SetDo:at:"
  3046.     set name [$this variableName]
  3047.     set qualPar [$this qualifierParameter]
  3048.     set get [$this getAccessImplementation $selector]
  3049.     if { $get == "" } {
  3050.     return
  3051.     }
  3052.  
  3053.     $get getNewUniqueArgumentName aBlock
  3054.     $get getNewUniqueArgumentName $qualPar
  3055.     set setName "[$this roleName]s"
  3056.     $get addTemporary $setName
  3057.     set getSet [$get addExpression "$setName := $name at: $qualPar ifAbsent:"]
  3058.     $getSet addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  3059.     $get addExpression "$setName do: aBlock"
  3060.  
  3061.     set selector "[$this qualifierName]SetDo:"
  3062.     set getAll [$this getAccessImplementation $selector]
  3063.     $getAll addArgument aBlock
  3064.     $getAll addExpression "$name keysDo: aBlock"
  3065. }
  3066.  
  3067.  
  3068. # Generates the set method that removes an object from the association for a given qualifier.
  3069. #
  3070. method STGManyQual::generateRemove {this} {
  3071.     set selector "remove[cap [$this roleName]]:at:"
  3072.     set remove [$this getRemoveImplementation $selector]
  3073.     if { $remove != "" } {
  3074.         $this generateRemoveCode $remove [$this opposite]
  3075.     }
  3076. }
  3077.  
  3078.  
  3079. # Generates the implementation method to add to the instance variable for the association.
  3080. #
  3081. method STGManyQual::generateSetRef {this} {
  3082.     set selector "add[cap [$this roleName]]Ref:at:"
  3083.     set setRef [$this getPrivateImplementation $selector]
  3084.     $this generateSetCode $setRef ""
  3085. }
  3086.  
  3087.  
  3088. # Generates the implementation method to remove from the instance variable for the association.
  3089. #
  3090. method STGManyQual::generateRemoveRef {this} {
  3091.     set selector "remove[cap [$this roleName]]Ref:at:"
  3092.     set removeRef [$this getPrivateImplementation $selector]
  3093.     $this generateRemoveCode $removeRef ""
  3094. }
  3095.  
  3096.  
  3097. # Generates an expression in block that sends a message to object with
  3098. # parameters <parameter> and <qualifier>.
  3099. #
  3100. method STGManyQual::generateRemoveRefMessage {this block object parameter qualifier} {
  3101.     set removeRefName "remove[cap [$this roleName]]Ref:"
  3102.     $block addExpression "$object $removeRefName $parameter at: $qualifier"
  3103. }
  3104.  
  3105.  
  3106. # Generates an expression in block that sends a setRef message to object
  3107. # with parameters <parameter> and <qualifier>.
  3108. #
  3109. method STGManyQual::generateSetRefMessage {this block object parameter qualifier} {
  3110.     set setRefName "add[cap [$this roleName]]Ref:"
  3111.     $block addExpression "$object $setRefName $parameter at: $qualifier"
  3112. }
  3113.  
  3114.  
  3115. # Does nothing.
  3116. #
  3117. method STGManyQual::generateRemoveMessage {this block object qualifier} {
  3118.     # Do nothing for many associations
  3119. }
  3120.  
  3121.  
  3122. # Generates the expressions for the set method to add to the association
  3123. # in block.
  3124. #
  3125. method STGManyQual::generateSetCode {this block opposite} {
  3126.     set name [$this variableName]
  3127.     set parName [$this parameterName]    
  3128.     set qualName [$this qualifierName]    
  3129.     set qualPar [$this qualifierParameter]
  3130.     set selector [$block selector]
  3131.     $block addArgument $parName
  3132.     $block addArgument $qualPar
  3133.     set setName "[$this roleName]s"
  3134.     $block addTemporary $setName
  3135.     
  3136.     # do size check for constraint
  3137.     set upper [$this upperConstraint]
  3138.     if { $upper != "" } {
  3139.     set block [$this generateConstraintCheck $selector $block $name $upper upper]
  3140.     }
  3141.  
  3142.     if { $opposite != "" } {
  3143.     $opposite generateRemoveMessage $block $parName $qualPar
  3144.     $opposite generateSetRefMessage $block $parName self $qualPar
  3145.     }
  3146.  
  3147.     # Generate to get old set or make a new one
  3148.     set newSet [$block addExpression "$setName := $name at: $qualPar ifAbsent:"]
  3149.     $newSet addExpression "$setName := [$this setType] new"
  3150.     $newSet addExpression "$name at: $qualPar put: $setName"
  3151.  
  3152.     if { [$this setType] == "OrderedCollection"} {
  3153.     set block [$this generateIncludesCheck $block $setName $parName]
  3154.     }
  3155.  
  3156.     $block addExpression "$setName add: $parName"
  3157. }
  3158.  
  3159.  
  3160. # Generates the expressions to remove from the association in block.
  3161. #
  3162. method STGManyQual::generateRemoveCode {this block opposite} {
  3163.     set name [$this variableName]
  3164.     set parName [$this parameterName]
  3165.     set qualPar [$this qualifierParameter]
  3166.     set selector [$block selector]
  3167.     $block addArgument $parName
  3168.     $block addArgument $qualPar
  3169.  
  3170.     # get set from dictionary 
  3171.     set setName "[$this roleName]s"
  3172.     $block addTemporary $setName
  3173.     set getSet [$block addExpression "$setName := $name at: $qualPar ifAbsent:"]
  3174.     $getSet addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  3175.  
  3176.     # check for constraint
  3177.     set lower [$this lowerConstraint]
  3178.     if { $lower != "" } {
  3179.     $this generateExistenceCheck $selector $block $setName $parName
  3180.     set block [$this generateConstraintCheck $selector $block $setName $lower lower] 
  3181.     # generate remove without ifAbsent:
  3182.     $block addExpression "$setName remove: $parName"
  3183.     } else {
  3184.     # generate remove with existence check
  3185.     set remExp [$block addExpression "$setName remove: $parName ifAbsent:"]
  3186.     $remExp addExpression [$this getErrorMessage ASSOC_OBJ_NOT_FOUND $selector]
  3187.     }
  3188.  
  3189.     if { $opposite != "" } {
  3190.     $opposite generateRemoveRefMessage $block $parName self $qualPar
  3191.     }
  3192.  
  3193.     # generate to remove key from dictionary if set gets empty
  3194.     if { $lower != "0" } {
  3195.     set emptyExpr [$block addExpression "$setName isEmpty ifTrue:"]
  3196.     $emptyExpr addExpression "$name removeKey: $qualPar"
  3197.     }
  3198. }
  3199.  
  3200.  
  3201. # Generates the additions to initialize, if it exists.
  3202. #
  3203. method STGManyQual::generateInitialize {this} {
  3204.     set initialize [[$this classImplementation] initialize]
  3205.     if { $initialize != "" } {
  3206.         $initialize addExpression "[$this variableName] := Dictionary new"
  3207.     }
  3208.     if { [$this lowerConstraint] != "" } {
  3209.     set comment "Warning: put association [$this roleName] in consistent state"
  3210.     $initialize addCommentLine $comment
  3211.     }
  3212. }
  3213.  
  3214.  
  3215. # Generates the additions to release in block.
  3216. #
  3217. method STGManyQual::generateReleaseCode {this block} {
  3218.     set name [$this variableName]
  3219.     set qualPar [$this qualifierParameter]
  3220.     set parName [$this parameterName]
  3221.     if { [$this opposite] != "" } {
  3222.     set dictBlock [$block addExpression "$name keysDo:"]
  3223.     $dictBlock addArgument $qualPar
  3224.     set setBlock [$dictBlock addExpression "($name at: $qualPar) do:"]
  3225.     $setBlock addArgument $parName
  3226.     [$this opposite] generateRemoveRefMessage $setBlock $parName self $qualPar
  3227.     }
  3228.  
  3229.     $block addExpression "$name := nil" 
  3230. }
  3231.  
  3232.  
  3233. # Generates expressions in block to print information about the association.
  3234. #
  3235. method STGManyQual::generatePrintCode {this block} {
  3236.     set name [$this variableName]
  3237.     $block addExpression "aStream cr; nextPutAll: \'$name:\' displayString"
  3238.     set printKeys [$block addExpression "$name keysDo:"]
  3239.     $printKeys addArgument "key"
  3240.     $printKeys addExpression "aStream cr; tab"
  3241.     $printKeys addExpression "key printOn: aStream"
  3242.     set printAll [$printKeys addExpression "($name at: key) inject: 1 into:"]
  3243.     $printAll addArgument "count"
  3244.     $printAll addArgument "element"
  3245.     $printAll addExpression "aStream cr; tab: 2; nextPutAll: count printString"
  3246.     $printAll addExpression "element printVars: aStream withIndent: 3"
  3247.     $printAll addExpression "count + 1"
  3248. }
  3249.  
  3250.  
  3251. # Returns 0.
  3252. #
  3253. method STGManyQual::removeRequired {this} {
  3254.     return 0
  3255. }
  3256.  
  3257. # Do not delete this line -- regeneration end marker
  3258.  
  3259.  
  3260.  
  3261. #---------------------------------------------------------------------------
  3262. #      File:           @(#)stgonequal.tcl    /main/titanic/2
  3263.  
  3264.  
  3265. # This is the generator for qualified associations with multiplicity one.
  3266.  
  3267. Class STGOneQual : {STGAssocGen} {
  3268.     constructor
  3269.     method destructor
  3270.     method generateData
  3271.     method generateGet
  3272.     method generateSet
  3273.     method generateRemove
  3274.     method generateSetRef
  3275.     method generateRemoveRef
  3276.     method generateRemoveRefMessage
  3277.     method generateSetRefMessage
  3278.     method generateRemoveMessage
  3279.     method generateSetCode
  3280.     method generateRemoveCode
  3281.     method generateInitialize
  3282.     method generateReleaseCode
  3283.     method generatePrintCode
  3284.     method getQualifierSetRequired
  3285. }
  3286.  
  3287. constructor STGOneQual {class this assocAttr} {
  3288.     set this [STGAssocGen::constructor $class $this $assocAttr]
  3289.     # Start constructor user section
  3290.     # End constructor user section
  3291.     return $this
  3292. }
  3293.  
  3294. method STGOneQual::destructor {this} {
  3295.     # Start destructor user section
  3296.     # End destructor user section
  3297.     $this STGAssocGen::destructor
  3298. }
  3299.  
  3300.  
  3301. # Generates instance variable to implement the association and sets variableName
  3302. # to <roleName>Dict.
  3303. #
  3304. method STGOneQual::generateData {this} {
  3305.     set name "[$this roleName]Dict"
  3306.     [$this classImplementation] addInstanceVariable $name
  3307.     $this variableName $name
  3308. }
  3309.  
  3310.  
  3311. # Generates the get methods:
  3312. # * One to get the associated object for a given qualifier.
  3313. # * One to execute a given block for all qualifiers.
  3314. #
  3315. method STGOneQual::generateGet {this} {
  3316.     set selector "get[cap [$this roleName]]At:"
  3317.     set name [$this variableName]
  3318.     set qualPar [$this qualifierParameter]
  3319.     set get [$this getAccessImplementation $selector]
  3320.     if { $get != "" } {
  3321.     $get addArgument $qualPar
  3322.     set expr [$get addExpression "^$name at: $qualPar ifAbsent:"]
  3323.     $expr addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  3324.     }
  3325.  
  3326.     # Method to get all qualifiers
  3327.     set selector "[$this qualifierName]SetDo:"
  3328.     set getAll [$this getAccessImplementation $selector]
  3329.     if { $getAll == "" } {
  3330.     if [$this getQualifierSetRequired] {
  3331.         set getAll [$this getPrivateImplementation $selector]
  3332.     } else {
  3333.         return
  3334.     }        
  3335.     }
  3336.     $getAll addArgument aBlock
  3337.     $getAll addExpression "$name keysDo: aBlock"   
  3338. }
  3339.  
  3340.  
  3341. # Generates the set method to set the association for a given qualifier.
  3342. #
  3343. method STGOneQual::generateSet {this} {
  3344.     set selector "set[cap [$this roleName]]:at:"
  3345.     set set [$this getModifyImplementation $selector]
  3346.     if { $set != "" } {
  3347.     $this generateSetCode $set [$this opposite]
  3348.     }
  3349. }
  3350.  
  3351.  
  3352. # Generates the remove method to remove the association for a given qualifier.
  3353. #
  3354. method STGOneQual::generateRemove {this} {
  3355.     set selector "remove[cap [$this roleName]]At:"
  3356.     set remove [$this getRemoveImplementation $selector]
  3357.     if { $remove != "" } {
  3358.     $this generateRemoveCode $remove [$this opposite]
  3359.     }
  3360. }
  3361.  
  3362.  
  3363. # Generates the implementation method to set the instance variable for the association.
  3364. #
  3365. method STGOneQual::generateSetRef {this} {
  3366.     set selector "set[cap [$this roleName]]Ref:at:"
  3367.     set setRef [$this getPrivateImplementation $selector]
  3368.     $this generateSetCode $setRef ""
  3369. }
  3370.  
  3371.  
  3372. # Generates the implementation method to remove from the association.
  3373. #
  3374. method STGOneQual::generateRemoveRef {this} {
  3375.     set selector "remove[cap [$this roleName]]RefAt:"
  3376.     set removeRef [$this getPrivateImplementation $selector]
  3377.     $this generateRemoveCode $removeRef ""
  3378. }
  3379.  
  3380.  
  3381. # Generates an expression in block that sends a removeRef message to
  3382. # object with parameters <parameter> and <qualifier>.
  3383. #
  3384. method STGOneQual::generateRemoveRefMessage {this block object parameter qualifier} {
  3385.     set removeRefName "remove[cap [$this roleName]]RefAt:"
  3386.     $block addExpression "$object $removeRefName $qualifier"
  3387. }
  3388.  
  3389.  
  3390. # Generates an expression in block that sends a SetRef message to 
  3391. # object with parameters <qualifier> and <parameter>.
  3392. #
  3393. method STGOneQual::generateSetRefMessage {this block object parameter qualifier} {
  3394.     set setRefName "set[cap [$this roleName]]Ref:"
  3395.     $block addExpression "$object $setRefName $parameter at: $qualifier"
  3396. }
  3397.  
  3398.  
  3399. # Generates an expression in block that sends a remove message to object
  3400. # if there is an association with qualifier <qualifier>.
  3401. #
  3402. method STGOneQual::generateRemoveMessage {this block object qualifier} {
  3403.     set getAllName "[$this qualifierName]SetDo:"
  3404.     set block [$block addExpression "$object $getAllName"]
  3405.  
  3406.     # make name for block argument
  3407.     set blockArgument "some[cap [$this qualifierName]]"
  3408.     $block addArgument $blockArgument
  3409.  
  3410.     set block [$block addExpression "$blockArgument = $qualifier ifTrue:"]
  3411.     set removeName "remove[cap [$this roleName]]At:"
  3412.     $block addExpression "$object $removeName $qualifier" 
  3413. }
  3414.  
  3415.  
  3416. # Generates the expressions in block for the set method.
  3417. #
  3418. method STGOneQual::generateSetCode {this block opposite} {
  3419.     set name [$this variableName]
  3420.     set parName [$block getNewUniqueArgumentName [$this parameterName]]
  3421.     set qualPar [$block getNewUniqueArgumentName [$this qualifierParameter]]
  3422.  
  3423.     if [[$this assocAttr] isMandatory] {
  3424.     $this generateNilCheck $block $parName
  3425.     }
  3426.  
  3427.     if { $opposite != "" } {    
  3428.     # remove old links
  3429.     $opposite generateRemoveMessage $block $parName $qualPar
  3430.  
  3431.     # Temporary variable for old value in dictionary
  3432.     set oldName "old[cap [$this roleName]]"
  3433.     $block addTemporary $oldName
  3434.     $block addExpression "$oldName := $name at: $qualPar ifAbsent: \[nil\]"
  3435.     set subExpr [$block addExpression "$oldName isNil ifFalse:"]
  3436.     $opposite generateRemoveRefMessage $subExpr $oldName self $qualPar
  3437.     # set new one
  3438.     $opposite generateSetRefMessage $block $parName self $qualPar
  3439.     }
  3440.  
  3441.     $block addExpression "$name at: $qualPar put: $parName"
  3442. }
  3443.  
  3444.  
  3445. # Generates the expressions for the remove method in block.
  3446. #
  3447. method STGOneQual::generateRemoveCode {this block opposite} {
  3448.     set qualPar [$this qualifierParameter]
  3449.     set selector [$block selector]
  3450.     $block addArgument $qualPar
  3451.  
  3452.     set removeText "[$this variableName] removeKey: $qualPar ifAbsent:"
  3453.     if { $opposite != "" } {
  3454.     # generate temporary to hold old value
  3455.     set oldName "old[cap [$this roleName]]"
  3456.     $block addTemporary $oldName
  3457.     set removeText "$oldName := $removeText"
  3458.     $opposite generateRemoveRefMessage $block $oldName self $qualPar
  3459.     }
  3460.  
  3461.     set expr [$block insertExpression $removeText]
  3462.     $expr addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  3463. }
  3464.  
  3465.  
  3466. # Generates the additions to initialize, if it exists.
  3467. #
  3468. method STGOneQual::generateInitialize {this} {
  3469.     set initialize [[$this classImplementation] initialize]
  3470.     if { $initialize != "" } {
  3471.         $initialize addExpression "[$this variableName] := Dictionary new"
  3472.     }
  3473. }
  3474.  
  3475.  
  3476. # Generates the additions to release in block.
  3477. #
  3478. method STGOneQual::generateReleaseCode {this block} {
  3479.     set name [$this variableName]
  3480.     set qualPar [$this qualifierParameter]
  3481.     if { [$this opposite] != "" } {
  3482.     set dictBlock [$block addExpression "$name keysDo:"]
  3483.     $dictBlock addArgument $qualPar
  3484.     [$this opposite] generateRemoveRefMessage $dictBlock "($name at: $qualPar)" self $qualPar
  3485.     }
  3486.  
  3487.     $block addExpression "$name := nil"
  3488. }
  3489.  
  3490.  
  3491. # Generates methods to print information about the association in block.
  3492. #
  3493. method STGOneQual::generatePrintCode {this block} {
  3494.     set name [$this variableName]
  3495.     $block addExpression "aStream cr; nextPutAll: \'$name:\' displayString"
  3496.     set printKeys [$block addExpression "$name keysDo:"]
  3497.     $printKeys addArgument "key"
  3498.     $printKeys addExpression "aStream cr; tab"
  3499.     $printKeys addExpression "key printOn: aStream"
  3500.     set printOther [$printKeys addExpression "($name at: key) isNil ifFalse:"]
  3501.     $printOther addExpression "($name at: key)  printVars: aStream withIndent: 2"
  3502. }
  3503.  
  3504.  
  3505. # Returns whether the method to get all qualifiers is needed by other methods.
  3506. #
  3507. method STGOneQual::getQualifierSetRequired {this} {
  3508.     set oppAttr [[$this assocAttr] opposite]
  3509.     if { $oppAttr == "" } {
  3510.     return 0
  3511.     }
  3512.  
  3513.     if { [$oppAttr isMandatory] || ([$oppAttr writeAccess] != "None") } {
  3514.     return 1
  3515.     }
  3516.  
  3517.     return 0 
  3518. }
  3519.  
  3520. # Do not delete this line -- regeneration end marker
  3521.  
  3522.  
  3523.  
  3524. #---------------------------------------------------------------------------
  3525. #      File:           @(#)stgdataatt.tcl    /main/titanic/4
  3526.  
  3527.  
  3528. # This class is the data attribute generator.
  3529.  
  3530. Class STGDataAttr : {STGAttribute} {
  3531.     constructor
  3532.     method destructor
  3533.     method generate
  3534.     method generateDefinition
  3535.     method generateDescription
  3536.     method generateInitialValue
  3537.     method generateGetSet
  3538.     method generatePrint
  3539.     method argumentName
  3540.     method checkLocal
  3541.     method checkInitialValue
  3542.  
  3543.     # Used to store name, set in generateDefinition.
  3544.     # (This name may be different from STName due to 
  3545.     # capitalization of first characters).
  3546.     #
  3547.     attribute name
  3548. }
  3549.  
  3550. constructor STGDataAttr {class this name} {
  3551.     set this [STGAttribute::constructor $class $this $name]
  3552.     # Start constructor user section
  3553.     # End constructor user section
  3554.     return $this
  3555. }
  3556.  
  3557. method STGDataAttr::destructor {this} {
  3558.     # Start destructor user section
  3559.     # End destructor user section
  3560. }
  3561.  
  3562.  
  3563. # Generate for data attributes:
  3564. # generate definition and description in
  3565. # classImplementation, generate an initial value in
  3566. # the initialize method if needed,
  3567. # generate Get and Set methods and
  3568. # generate print methods if generatePrint in globals
  3569. # is set.
  3570. #
  3571. method STGDataAttr::generate {this} {
  3572.     # Call the methods
  3573.     $this generateDefinition
  3574.     $this generateDescription
  3575.     $this generateInitialValue
  3576.     
  3577.     # Only generate get and set for class and instance vars
  3578.     if { [$this getPropertyValue isPoolDict] != "1" } {
  3579.         $this generateGetSet
  3580.     }
  3581.     
  3582.     if [$globals generatePrint] {
  3583.         $this generatePrint
  3584.     }
  3585. }
  3586.  
  3587.  
  3588. # Generates the name of the attribute in the class implementation object.
  3589. # Sets the name attribute; capitalizes class variables and pool dictionaries.
  3590. #
  3591. method STGDataAttr::generateDefinition {this} {
  3592.     set classImpl [[$this ooplClass] classImplementation]
  3593.     
  3594.     set name [$this getSTName]
  3595.     if { [$this getPropertyValue isPoolDict] == "1" } {
  3596.         set name [cap $name]
  3597.         $classImpl addPoolDictionary $name
  3598.     } elseif [$this isClassFeature] {
  3599.         set name [cap $name]
  3600.         $classImpl addClassVariable $name
  3601.     } else {
  3602.         $classImpl addInstanceVariable $name
  3603.     }
  3604.     $this name $name
  3605. }
  3606.  
  3607.  
  3608. # Generates description of the attribute in the class implementation object.
  3609. #
  3610. method STGDataAttr::generateDescription {this} {
  3611.     if [regsub -all \' [$this getPropertyValue freeText] "" comment] {
  3612.         # '-s removed
  3613.     }
  3614.  
  3615.     set commentLine [$this name]
  3616.     
  3617.     # Add type if it exists
  3618.     set type [$this ooplType] 
  3619.     if { $type != "" } {
  3620.         if { [$type getName] != "" } {
  3621.             set commentLine "$commentLine ([$this asSTName [$type getName]])"
  3622.         }
  3623.     }
  3624.     
  3625.     # Add free text if is there
  3626.     if { $comment != "" } {    
  3627.         set commentLine "$commentLine: $comment"
  3628.         [[$this ooplClass] classImplementation] addCommentLine $commentLine
  3629.     }
  3630. }
  3631.  
  3632.  
  3633. # Generates initial value in initialize for instance variable
  3634. # or in an expression for class variable.
  3635. #
  3636. method STGDataAttr::generateInitialValue {this} {
  3637.     set initialValue [$this getPropertyValue initial_value]
  3638.     
  3639.     if { $initialValue != "" } {
  3640.         set classImpl [[$this ooplClass] classImplementation]
  3641.         
  3642.         if [$this isClassFeature] {
  3643.             # class variable: make expression to set it.
  3644.             set expression "[[$this ooplClass] getSTName] [$this name]"
  3645.             set expression "$expression: $initialValue"
  3646.             
  3647.             # If there is no write access we can't do it
  3648.              if { [$this writeAccess] == "None" } {
  3649.                 # warning also in checkInitialValue
  3650.                 # m4_warning $WST_NOGENINITVAL [$this name]
  3651.             } else {
  3652.                 $classImpl addExpression $expression
  3653.             }
  3654.         } else {
  3655.             # generate expression in initialize if it exists
  3656.             set initialize [$classImpl initialize]
  3657.             if { $initialize != "" } {
  3658.                 # Make it conditional if there is an initializer
  3659.                 # in that case it may already have a value
  3660.                 set block $initialize
  3661.                 
  3662.                 if { [$this hasInitializer] == 1} {
  3663.                     set block [$initialize addExpression "[$this name] isNil ifTrue:"]
  3664.                 }
  3665.                 $block addExpression "[$this name] := $initialValue"
  3666.             }
  3667.         }
  3668.     } 
  3669. }
  3670.  
  3671.  
  3672. # Generates get and set methods for the attribute if allowed by read and write access.
  3673. #
  3674. method STGDataAttr::generateGetSet {this} {
  3675.     set name [$this name]
  3676.     set argName [$this getArgumentName]
  3677.     set classImpl [[$this ooplClass] classImplementation]
  3678.     set isClassVar [$this isClassFeature]
  3679.     set readCategory [$this getReadCategory "accessing"]
  3680.     if { $readCategory != "" } {
  3681.         # generate Get
  3682.         if $isClassVar {
  3683.             set get [$classImpl getClassMethodImplementation "$name" $readCategory]
  3684.         } else {
  3685.             set get [$classImpl getInstanceMethodImplementation "$name" $readCategory]
  3686.         }
  3687.         $get addExpression "^$name"
  3688.     }
  3689.     set writeCategory [$this getWriteCategory "modifying"]
  3690.     if { $writeCategory != ""} {
  3691.         # generate Set
  3692.         if $isClassVar {
  3693.             set set [$classImpl getClassMethodImplementation "$name:" $writeCategory]
  3694.         } else {
  3695.             set set [$classImpl getInstanceMethodImplementation "$name:" $writeCategory]
  3696.         }
  3697.         $set addArgument $argName
  3698.         $set addExpression "$name := $argName"
  3699.     }
  3700. }
  3701.  
  3702.  
  3703. # Generates an expression in the printVars and printOn methods. to print it.
  3704. #
  3705. method STGDataAttr::generatePrint {this} {
  3706.     set printVars [[[$this ooplClass] classImplementation] printVars]
  3707.     set printOn [[[$this ooplClass] classImplementation] printOn]
  3708.     if { $printVars != "" } {
  3709.         $printVars addExpression \
  3710.             "aStream cr; tab: anInteger; nextPutAll: \'[$this name]: \' displayString"
  3711.         $printVars addExpression "[$this name] printOn: aStream"
  3712.     }
  3713.     if { $printOn != "" } {
  3714.         $printOn addExpression \
  3715.             "aStream cr; nextPutAll: \'[$this name]: \' displayString"
  3716.         $printOn addExpression "[$this name] printOn: aStream"
  3717.     }
  3718. }
  3719.  
  3720.  
  3721. # Return name for this attribute when it used as argument:
  3722. # base it on type if it exists and the name otherwise.
  3723. #
  3724. method STGDataAttr::argumentName {this} {
  3725.     set type [$this ooplType]
  3726.     if { $type != "" } {
  3727.         if { [$type getType3GL] != "" } {
  3728.             return [$this asSTName [$this asArgument [$type getType3GL]]]
  3729.         } elseif { [$type getName] != "" } {
  3730.             return [$this asSTName [$this asArgument [$type getName]]]
  3731.         }
  3732.     } 
  3733.     # It is safe to use getSTName because first char is always capitalized
  3734.     return [$this asArgument [$this getSTName]]
  3735. }
  3736.  
  3737. method STGDataAttr::checkLocal {this} {
  3738.     # message also present in STGDataAttr::generateInitialValue
  3739.     set errornr 0
  3740.     set warningnr 0
  3741.     
  3742.     incr errornr [$this checkSTName]
  3743.     incr warningnr [$this checkInitialValue]
  3744.     incr warningnr [$this checkFreeTextQuote]
  3745.  
  3746.     return $errornr
  3747. }
  3748.  
  3749. method STGDataAttr::checkInitialValue {this} {
  3750.     # message also present in STGDataAttr::generateInitialValue
  3751.     set warningnr 0
  3752.  
  3753.     set initialValue [$this getPropertyValue initial_value]
  3754.     # check presence of initial value
  3755.     if { $initialValue != "" } {
  3756.         if [$this isClassFeature] {
  3757.             # If there is no write access we can't do it
  3758.             if { [$this writeAccess] == "None" } {
  3759.                 # see generateDefinition() for capitalizing the name
  3760.                 set name [cap [$this getSTName]]
  3761.                 m4_warning $WST_NOGENINITVAL $name
  3762.                 set warningnr 1
  3763.             }
  3764.         }
  3765.     }
  3766.     return $warningnr
  3767. }
  3768.  
  3769. # Do not delete this line -- regeneration end marker
  3770.  
  3771. if [isCommand CMDataAttr] {
  3772.     Class  STGDataAttrD : {STGDataAttr CMDataAttr} {
  3773.     }
  3774. } else {
  3775.     Class STGDataAttrD : {STGDataAttr OPDataAttr} {    
  3776.     }
  3777. }
  3778.  
  3779. global mostDerivedOOPL ; set mostDerivedOOPL(OPDataAttr) STGDataAttrD
  3780.  
  3781. selfPromoter OPDataAttr {this} {
  3782.     STGDataAttrD promote $this
  3783. }
  3784.  
  3785.  
  3786. #---------------------------------------------------------------------------
  3787. #      File:           @(#)stggenasso.tcl    /main/titanic/2
  3788.  
  3789.  
  3790. # General association generator: contains methods that are 
  3791. # the same for all types of association.
  3792.  
  3793. Class STGGenAssocAttr : {STGAttribute} {
  3794.     constructor
  3795.     method destructor
  3796.     method generateAll
  3797.     method setNames
  3798.     method generate
  3799.     method generateDescription
  3800.     method argumentName
  3801.     method oppositeMandatoryOne
  3802.     method checkLocal
  3803.     method checkFreeText
  3804.     method generator
  3805.     attribute _generator
  3806. }
  3807.  
  3808. constructor STGGenAssocAttr {class this name} {
  3809.     set this [STGAttribute::constructor $class $this $name]
  3810.     # Start constructor user section
  3811.     # End constructor user section
  3812.     return $this
  3813. }
  3814.  
  3815. method STGGenAssocAttr::destructor {this} {
  3816.     set ref [$this _generator]
  3817.     if {$ref != ""} {
  3818.         $ref _assocAttr ""
  3819.     }
  3820.     # Start destructor user section
  3821.     $this _generator ""
  3822.     # End destructor user section
  3823.     $this STGAttribute::destructor
  3824. }
  3825.  
  3826.  
  3827. # Calls all methods in the generator.
  3828. #
  3829. method STGGenAssocAttr::generateAll {this} {
  3830.     set generator [$this generator]
  3831.     $generator generateData
  3832.     $generator generateSet
  3833.     $generator generateGet
  3834.     $generator generateRemove
  3835.     if { [$this opposite] != "" } {
  3836.         $generator generateSetRef
  3837.         $generator generateRemoveRef
  3838.     }
  3839.     $generator generateInitialize
  3840.     $generator generateRelease
  3841. }
  3842.  
  3843.  
  3844. # Sets the roleName to the ST name for this attribute and parameterName to the argument name 
  3845. # of this attribute in the association generator object.
  3846. #
  3847. method STGGenAssocAttr::setNames {this} {
  3848.     [$this generator] roleName [$this getSTName]
  3849.     [$this generator] parameterName [$this getArgumentName] 
  3850. }
  3851.  
  3852.  
  3853. # Generates for association attribute:
  3854. # sets up generator, sets up generator for opposite,
  3855. # generates a description,
  3856. # calls generateAll (defined in subclasses), and
  3857. # generates print methods for the attribute if
  3858. # generatePrint is set in STGGlobal.
  3859. #
  3860. method STGGenAssocAttr::generate {this} {
  3861.     # get generator if it didn't exist yet.
  3862.     if { [$this generator] == "" } {
  3863.         $this setGenerator
  3864.         $this setNames
  3865.     }
  3866.  
  3867.     # Now set class implementation object
  3868.     # assumption: generate is called just once
  3869.     # if not this code is a bit inefficient
  3870.     [$this generator] classImplementation [[$this ooplClass] classImplementation]
  3871.  
  3872.     # get a generator for opposite if it exists
  3873.     # needed to do generate*call
  3874.     set opposite [$this opposite]
  3875.     if { $opposite != "" } {
  3876.         if { [$opposite generator] == "" } {
  3877.             $opposite setGenerator
  3878.             $opposite setNames
  3879.             # make generators point to each other
  3880.             [$this generator] opposite [$opposite generator]
  3881.             [$opposite generator] opposite [$this generator]
  3882.         }
  3883.     }
  3884.  
  3885.     # Must first call generateAll because generateDescription needs
  3886.     # instance variable name
  3887.     $this generateAll
  3888.     $this generateDescription
  3889.  
  3890.     if [$globals generatePrint] {
  3891.         set printOn [[[$this ooplClass] classImplementation] printOn]
  3892.         if { $printOn != "" } { 
  3893.             [$this generator] generatePrintCode $printOn
  3894.         }
  3895.     }
  3896.     [$this generator] classImplementation ""
  3897. }
  3898.  
  3899.  
  3900. # Generate a description of the association attribute in the class comment,
  3901. # based on free text. If there is no free text generate nothing.
  3902. #
  3903. method STGGenAssocAttr::generateDescription {this} {
  3904.     set commentLine "[[$this generator] variableName]"
  3905.  
  3906.     if [regsub -all \' [$this getPropertyValue freeText] "" comment] {
  3907.         # removed '-s
  3908.     }
  3909.  
  3910.     # Add free text if is there
  3911.     if { $comment != "" } {
  3912.         set commentLine "$commentLine: $comment"
  3913.         [[$this ooplClass] classImplementation] addCommentLine $commentLine
  3914.     }
  3915. }
  3916.  
  3917.  
  3918. # Returns the name of this attribute when used as argument, based on the role name.
  3919. #
  3920. method STGGenAssocAttr::argumentName {this} {
  3921.     return [$this asArgument [$this getSTName]]
  3922. }
  3923.  
  3924.  
  3925. # Returns 1 if the opposite of this association attribute is mandatory, one and non-qualified.
  3926. #
  3927. method STGGenAssocAttr::oppositeMandatoryOne {this} {
  3928.     set opposite [$this opposite]
  3929.     if { $opposite == "" } {
  3930.         return 0
  3931.     }
  3932.     if  {[$opposite isMandatory] && \
  3933.              (![$opposite isQualified]) && \
  3934.              ([$opposite getMultiplicity] == "one") } {
  3935.         return 1
  3936.     }    
  3937.     return 0
  3938. }
  3939.  
  3940. method STGGenAssocAttr::checkLocal {this} {
  3941.     set errornr 0
  3942.     set warning 0
  3943.     incr errornr [$this checkSTName]
  3944.     # get generator if it didn't exist yet.
  3945.     if { [$this generator] == "" } {
  3946.         $this setGenerator
  3947.         $this setNames
  3948.     }
  3949.     # now check assoc
  3950.     incr errornr [[$this generator] check]
  3951.  
  3952.     # and its freeText
  3953.     incr warning [$this checkFreeText]
  3954.  
  3955.     return $errornr
  3956. }
  3957.  
  3958. method STGGenAssocAttr::checkFreeText {this} {
  3959.     set warningnr 0
  3960.     if [regexp \' [$this getPropertyValue freeText] comment] {
  3961.         m4_warning $WST_REMOVEQUOTEDESCR [$this getName]
  3962.         incr warningnr 1
  3963.     }
  3964.     return $warningnr
  3965. }
  3966.  
  3967. # Do not delete this line -- regeneration end marker
  3968.  
  3969. method STGGenAssocAttr::generator {this args} {
  3970.     if {$args == ""} {
  3971.         return [$this _generator]
  3972.     }
  3973.     set ref [$this _generator]
  3974.     if {$ref != ""} {
  3975.         $ref _assocAttr ""
  3976.     }
  3977.     set obj [lindex $args 0]
  3978.     if {$obj != ""} {
  3979.         $obj _assocAttr $this
  3980.     }
  3981.     $this _generator $obj
  3982. }
  3983.  
  3984.  
  3985.  
  3986. #---------------------------------------------------------------------------
  3987. #      File:           @(#)stgclassen.tcl    /main/titanic/3
  3988.  
  3989.  
  3990. # Generator for enum classes.
  3991.  
  3992. Class STGClassEnum : {STGClass} {
  3993.     constructor
  3994.     method destructor
  3995.     method generate
  3996.     method checkLocal
  3997. }
  3998.  
  3999. constructor STGClassEnum {class this name} {
  4000.     set this [STGClass::constructor $class $this $name]
  4001.     # Start constructor user section
  4002.     # End constructor user section
  4003.     return $this
  4004. }
  4005.  
  4006. method STGClassEnum::destructor {this} {
  4007.     # Start destructor user section
  4008.     # End destructor user section
  4009. }
  4010.  
  4011.  
  4012. # Prints a message that enums are not supported in Smalltalk.
  4013. #
  4014. method STGClassEnum::generate {this classImpl} {
  4015.     # message already generated by check.
  4016.     # enums not supported
  4017. }
  4018.  
  4019. method STGClassEnum::checkLocal {this} {
  4020.     set errornr 0
  4021.     incr errornr [$this checkSTName]
  4022.     m4_error $EST_ENUMSNOTSUP [$this getSTName]
  4023.     incr errornr 1
  4024.     return $errornr
  4025. }
  4026.  
  4027. # Do not delete this line -- regeneration end marker
  4028.  
  4029. if [isCommand CMClassEnum] {
  4030.     Class  STGClassEnumD : {STGClassEnum CMClassEnum} {
  4031.     }
  4032. } else {
  4033.     Class STGClassEnumD : {STGClassEnum OPClassEnum} {    
  4034.     }
  4035. }
  4036.  
  4037. global mostDerivedOOPL ; set mostDerivedOOPL(OPClassEnum) STGClassEnumD
  4038.  
  4039. selfPromoter OPClassEnum {this} {
  4040.     STGClassEnumD promote $this
  4041. }
  4042.  
  4043.  
  4044. #---------------------------------------------------------------------------
  4045. #      File:           @(#)stgclassge.tcl    /main/titanic/3
  4046.  
  4047.  
  4048. Class STGClassGenericTypeDef : {STGClass} {
  4049.     constructor
  4050.     method destructor
  4051. }
  4052.  
  4053. constructor STGClassGenericTypeDef {class this name} {
  4054.     set this [STGClass::constructor $class $this $name]
  4055.     # Start constructor user section
  4056.     # End constructor user section
  4057.     return $this
  4058. }
  4059.  
  4060. method STGClassGenericTypeDef::destructor {this} {
  4061.     # Start destructor user section
  4062.     # End destructor user section
  4063. }
  4064.  
  4065. # Do not delete this line -- regeneration end marker
  4066.  
  4067. if [isCommand CMClassGenericTypeDef] {
  4068.     Class  STGClassGenericTypeDefD : {STGClassGenericTypeDef CMClassGenericTypeDef} {
  4069.     }
  4070. } else {
  4071.     Class STGClassGenericTypeDefD : {STGClassGenericTypeDef OPClassGenericTypeDef} {    
  4072.     }
  4073. }
  4074.  
  4075. global mostDerivedOOPL ; set mostDerivedOOPL(OPClassGenericTypeDef) STGClassGenericTypeDefD
  4076.  
  4077. selfPromoter OPClassGenericTypeDef {this} {
  4078.     STGClassGenericTypeDefD promote $this
  4079. }
  4080.  
  4081.  
  4082. #---------------------------------------------------------------------------
  4083. #      File:           @(#)stgclasstd.tcl    /main/titanic/3
  4084.  
  4085.  
  4086. Class STGClassTDef : {STGClass} {
  4087.     constructor
  4088.     method destructor
  4089. }
  4090.  
  4091. constructor STGClassTDef {class this name} {
  4092.     set this [STGClass::constructor $class $this $name]
  4093.     # Start constructor user section
  4094.     # End constructor user section
  4095.     return $this
  4096. }
  4097.  
  4098. method STGClassTDef::destructor {this} {
  4099.     # Start destructor user section
  4100.     # End destructor user section
  4101. }
  4102.  
  4103. # Do not delete this line -- regeneration end marker
  4104.  
  4105. if [isCommand CMClassTDef] {
  4106.     Class  STGClassTDefD : {STGClassTDef CMClassTDef} {
  4107.     }
  4108. } else {
  4109.     Class STGClassTDefD : {STGClassTDef OPClassTDef} {    
  4110.     }
  4111. }
  4112.  
  4113. global mostDerivedOOPL ; set mostDerivedOOPL(OPClassTDef) STGClassTDefD
  4114.  
  4115. selfPromoter OPClassTDef {this} {
  4116.     STGClassTDefD promote $this
  4117. }
  4118.  
  4119.  
  4120. #---------------------------------------------------------------------------
  4121. #      File:           @(#)stglinkcla.tcl    /main/titanic/3
  4122.  
  4123.  
  4124. # This class is the top level class generator
  4125. # for link classes. 
  4126.  
  4127. Class STGLinkClass : {STGClass} {
  4128.     constructor
  4129.     method destructor
  4130.     method generate
  4131.     method printGeneratingMessage
  4132.     method printCheckingMessage
  4133.     method checkLocal
  4134.     method checkLinkClass
  4135. }
  4136.  
  4137. constructor STGLinkClass {class this name} {
  4138.     set this [STGClass::constructor $class $this $name]
  4139.     # Start constructor user section
  4140.     # End constructor user section
  4141.     return $this
  4142. }
  4143.  
  4144. method STGLinkClass::destructor {this} {
  4145.     # Start destructor user section
  4146.     # End destructor user section
  4147. }
  4148.  
  4149.  
  4150. # Check that this link class is named and generate
  4151. # as if it were a normal class.
  4152. #
  4153. method STGLinkClass::generate {this classImpl} {
  4154.     # skip if link class has no name (already checked, but...)
  4155.     if { [$this getSTName] != "" } {
  4156.         $this STGClass::generate $classImpl
  4157.     } 
  4158. }
  4159.  
  4160.  
  4161. # Print a message stating that generation for this link class is in progress.
  4162. #
  4163. method STGLinkClass::printGeneratingMessage {this} {
  4164.     m4_message $MST_GENERATELINK [$this getName]
  4165. }
  4166.  
  4167. method STGLinkClass::printCheckingMessage {this} {
  4168. }
  4169.  
  4170. method STGLinkClass::checkLocal {this} {
  4171.     set errornr 0
  4172.     if { [$this checkLinkClass] == 0 } {
  4173.         incr errornr [$this STGClass::checkLocal]
  4174.     }
  4175.     return $errornr
  4176. }
  4177.  
  4178. method STGLinkClass::checkLinkClass {this} {
  4179.     set warningnr 0
  4180.     if { [$this getSTName] == "" } {
  4181.         m4_warning $WST_LINKCLSSSKIPPED
  4182.         incr warningnr 1
  4183.     }
  4184.     return $warningnr
  4185. }
  4186.  
  4187. # Do not delete this line -- regeneration end marker
  4188.  
  4189. if [isCommand CMLinkClass] {
  4190.     Class  STGLinkClassD : {STGLinkClass CMLinkClass} {
  4191.     }
  4192. } else {
  4193.     Class STGLinkClassD : {STGLinkClass OPLinkClass} {    
  4194.     }
  4195. }
  4196.  
  4197. global mostDerivedOOPL ; set mostDerivedOOPL(OPLinkClass) STGLinkClassD
  4198.  
  4199. selfPromoter OPLinkClass {this} {
  4200.     STGLinkClassD promote $this
  4201. }
  4202.  
  4203.  
  4204. #---------------------------------------------------------------------------
  4205. #      File:           @(#)stgoneoppq.tcl    /main/titanic/2
  4206.  
  4207.  
  4208. # Generator for roles which are the opposite of qualified associations
  4209. # in which this opposite has multiplicity one.
  4210.  
  4211. Class STGOneOppQual : {STGAssocOne} {
  4212.     constructor
  4213.     method destructor
  4214.     method generateData
  4215.     method generateSet
  4216.     method generateRemove
  4217.     method generateInitialize
  4218.     method generateReleaseCode
  4219.     method generateSetRefMessage
  4220.     method generateRemoveRefMessage
  4221.     method generateRemoveMessage
  4222.     method generateQualifierSet
  4223.     method generateQualifierGet
  4224.     method generateQualifierSetRef
  4225.     method generateQualifierPrint
  4226.     method checkLocal
  4227.     method checkQualifier
  4228.  
  4229.     # Used to store the name of the qualifier on the other side.
  4230.     # It may be different from the qualifier on this side if 
  4231.     # the qualifierName property has been set.
  4232.     #
  4233.     attribute oppositeQualifierName
  4234. }
  4235.  
  4236. constructor STGOneOppQual {class this assocAttr} {
  4237.     set this [STGAssocOne::constructor $class $this $assocAttr]
  4238.     # Start constructor user section
  4239.     # End constructor user section
  4240.     return $this
  4241. }
  4242.  
  4243. method STGOneOppQual::destructor {this} {
  4244.     # Start destructor user section
  4245.     # End destructor user section
  4246.     $this STGAssocOne::destructor
  4247. }
  4248.  
  4249.  
  4250. # Generates instance variable to implement this
  4251. # association and sets variableName to <roleName>.
  4252. # Also generates the instance variable for the qualifier on this side
  4253. # if necessary and the methods for this qualifier.
  4254. #
  4255. method STGOneOppQual::generateData {this} {
  4256.     $this STGAssocOne::generateData
  4257.  
  4258.     set qualifier [$this qualifierName]
  4259.     $this oppositeQualifierName $qualifier
  4260.     # retrieve user specified qualifier
  4261.     set userQualifier [[$this assocAttr] getPropertyValue qualifierName]
  4262.     if { $userQualifier != "" } {
  4263.         set qualifier $userQualifier
  4264.     }
  4265.  
  4266.     # check if it exists
  4267.     set exists 0
  4268.     set className [[[$this assocAttr] ooplClass] getSTName]
  4269.     foreach attribute [[[$this assocAttr] ooplClass] dataAttrSet] {
  4270.         if { [$attribute getSTName] == $qualifier } {
  4271.             if { [$attribute isClassFeature] || \
  4272.                      ([$attribute getPropertyValue isPoolDict] == "1") } {
  4273.                 # m4_warning $WST_QUALNOINSTC $qualifier $className
  4274.             } else {
  4275.                 set exists 1
  4276.             }    
  4277.         }
  4278.     }
  4279.     if { (!$exists) && ($userQualifier != "") } {
  4280.         # m4_warning $WST_QUALNOTDEF $qualifier $className
  4281.     }
  4282.  
  4283.     $this qualifierName $qualifier
  4284.     if { !$exists } {
  4285.         [$this classImplementation] addInstanceVariable $qualifier
  4286.         [$this classImplementation] addCommentLine \
  4287.             "$qualifier: qualifier for [[$this assocAttr] getSTName]"
  4288.         $this generateQualifierPrint
  4289.     }
  4290.     if { ($userQualifier != "") || $exists } {
  4291.         $this generateQualifierSet
  4292.         $this generateQualifierGet
  4293.     }
  4294.     $this generateQualifierSetRef
  4295. }
  4296.  
  4297.  
  4298. # Generates the set method to set the association.
  4299. #
  4300. method STGOneOppQual::generateSet {this} {
  4301.     set name [$this variableName]
  4302.     set qualName [$this qualifierName]
  4303.     set selector "set[cap [$this roleName]]:at:"
  4304.     set set [$this getModifyImplementation $selector]
  4305.     if { $set == "" } {
  4306.         return
  4307.     }
  4308.  
  4309.     set parName [$set getNewUniqueArgumentName [$this parameterName]]
  4310.     set qualPar [$set getNewUniqueArgumentName [$this qualifierParameter]]
  4311.  
  4312.     # if it is mandatory generate a nil check and an inequality check
  4313.     if [[$this assocAttr] isMandatory] {
  4314.         $this generateNilCheck $set $parName
  4315.     }
  4316.     if { [$this opposite] != "" } {
  4317.         if [[$this assocAttr] isMandatory] {
  4318.             set compare "($name ~~ $parName | ($qualName ~= $qualPar))"
  4319.             set set [$set addExpression "$compare ifTrue:"]
  4320.         }
  4321.         # remove old links
  4322.         [$this opposite] generateRemoveMessage $set $parName $qualPar
  4323.         set removeBlock $set
  4324.         if { ![[$this assocAttr] isMandatory]} {
  4325.             set removeBlock [$set addExpression "$name isNil ifFalse:"]
  4326.         }
  4327.         [$this opposite] generateRemoveRefMessage $removeBlock $name self $qualName
  4328.         # set new link
  4329.         [$this opposite] generateSetRefMessage $set $parName self $qualPar
  4330.     }
  4331.     $set addExpression "$name := $parName"   
  4332.     $set addExpression "$qualName := $qualPar"   
  4333. }
  4334.  
  4335.  
  4336. # Generates the set method to remove the association.
  4337. #
  4338. method STGOneOppQual::generateRemove {this} {
  4339.     set selector "remove[cap [$this roleName]]"
  4340.     set remove [$this getRemoveImplementation $selector]
  4341.     if  { $remove != "" } {
  4342.         $this generateRemoveCode $remove [$this opposite] [$this qualifierName]
  4343.     }
  4344. }
  4345.  
  4346.  
  4347. # Generates the additions to initialize, if it exists.
  4348. #
  4349. method STGOneOppQual::generateInitialize {this} {
  4350.     set initialize [[$this classImplementation] initialize]
  4351.     if { $initialize == "" } {
  4352.         return
  4353.     }
  4354.     if { [[$this assocAttr] hasInitializer] == 1 } {
  4355.         set qualPar [$initialize getUniqueArgumentName \
  4356.                          [$this oppositeQualifierName] [$this qualifierParameter] ]
  4357.         $this generateInitializeCode $initialize $qualPar
  4358.         $initialize addExpression "[$this qualifierName] := $qualPar"
  4359.     } else {
  4360.         $this generateInitializeCode $initialize 
  4361.         $initialize addExpression "[$this qualifierName] := nil"
  4362.     }
  4363.  
  4364. }
  4365.  
  4366.  
  4367. # Generates the additions to release in block.
  4368. #
  4369. method STGOneOppQual::generateReleaseCode {this block} {
  4370.     $this generateRemoveCode $block [$this opposite] [$this qualifierName]
  4371. }
  4372.  
  4373.  
  4374. # Generates expressions in block to send setRef
  4375. # messages to object for <parameter> and for <qualifier>.
  4376. #
  4377. method STGOneOppQual::generateSetRefMessage {this block object parameter qualifier} {
  4378.     $this STGAssocOne::generateSetRefMessage $block $object $parameter
  4379.     set qualName [[$this assocAttr] getPropertyValue qualifierName]
  4380.     if { $qualName == "" } {
  4381.         set qualName [$this qualifierName]
  4382.     }
  4383.     set setQualRefName "set[cap $qualName]Ref:"
  4384.     $block addExpression "$object $setQualRefName $qualifier"
  4385. }
  4386.  
  4387.  
  4388. # Generates expressions in block to send a SetRef
  4389. # message to object with parameter nil.
  4390. #
  4391. method STGOneOppQual::generateRemoveRefMessage {this block object parameter qualifier} {
  4392.     $this STGAssocOne::generateSetRefMessage $block $object nil
  4393. }
  4394.  
  4395.  
  4396. # Generates an expression in block to send a remove
  4397. # message to object.
  4398. #
  4399. method STGOneOppQual::generateRemoveMessage {this block object qualifier} {
  4400.     $this STGAssocOne::generateRemoveMessage $block $object
  4401. }
  4402.  
  4403.  
  4404. # Generates the special method to set a qualifier and 
  4405. # update the association if necessary.
  4406. #
  4407. method STGOneOppQual::generateQualifierSet {this} {
  4408.     set selector "[$this qualifierName]:"
  4409.     set setQual [$this getModifyImplementation $selector]
  4410.     if { $setQual == "" } {
  4411.         return
  4412.     }
  4413.     set name [$this variableName]
  4414.     set qualName [$this qualifierName]
  4415.     set qualPar [$this qualifierParameter]
  4416.     $setQual addArgument $qualPar
  4417.  
  4418.     # if it's empty generate the set
  4419.     if [$setQual isEmpty] {
  4420.         $setQual addExpression "$qualName := $qualPar"
  4421.     }
  4422.  
  4423.     # generate check if update is needed
  4424.     set checkExpr "($name notNil & ($qualName ~= $qualPar)) ifTrue:"
  4425.     set block [$setQual insertExpression $checkExpr]
  4426.     set opposite [$this opposite]
  4427.  
  4428.     # remove and set on other side
  4429.     $opposite generateRemoveRefMessage $block $name self $qualName
  4430.     $opposite generateRemoveMessage $block $name $qualPar  
  4431.     $opposite generateSetRefMessage $block $name self $qualPar    
  4432. }
  4433.  
  4434.  
  4435. # Generates the method to get the qualifier.
  4436. #
  4437. method STGOneOppQual::generateQualifierGet {this} {
  4438.     set selector "[$this qualifierName]"
  4439.     set getQual [$this getAccessImplementation $selector]
  4440.     if { $getQual == "" } {
  4441.         set getQual [$this getPrivateImplementation $selector]
  4442.     }
  4443.     # if it's empty generate the get
  4444.     if [$getQual isEmpty] {
  4445.         $getQual addExpression "\^[$this qualifierName]"
  4446.     }
  4447. }
  4448.  
  4449.  
  4450. # Generates the implementation method to set the
  4451. # qualifier instance variable.
  4452. #
  4453. method STGOneOppQual::generateQualifierSetRef {this} {
  4454.     set selector "set[cap [$this qualifierName]]Ref:"
  4455.     set setQualRef [$this getPrivateImplementation $selector]
  4456.     $setQualRef addArgument [$this qualifierParameter]
  4457.     set assign "[$this qualifierName] := [$this qualifierParameter]"
  4458.     $setQualRef addExpression $assign
  4459. }
  4460.  
  4461.  
  4462. # Generates in the printVars method to print the qualifier instance variable.
  4463. #
  4464. method STGOneOppQual::generateQualifierPrint {this} {
  4465.     set printVars [[$this classImplementation] printVars]
  4466.     set qualName [$this qualifierName]
  4467.     if { $printVars != "" } {
  4468.         $printVars addExpression \
  4469.             "aStream cr; tab: anInteger; nextPutAll: \'$qualName: \' displayString"
  4470.         $printVars addExpression "$qualName printOn: aStream"
  4471.     }
  4472. }
  4473.  
  4474. method STGOneOppQual::checkLocal {this} {
  4475.     set errornr 0
  4476.     set warningnr 0
  4477.     incr warningnr [$this checkQualifier]
  4478.     return $errornr
  4479. }
  4480.  
  4481. method STGOneOppQual::checkQualifier {this} {
  4482.     set warningnr 0
  4483.  
  4484.     set qualifier [$this qualifierName]
  4485.     $this oppositeQualifierName $qualifier
  4486.     # retrieve user specified qualifier
  4487.     set userQualifier [[$this assocAttr] getPropertyValue qualifierName]
  4488.     if { $userQualifier != "" } {
  4489.         set qualifier $userQualifier
  4490.     }
  4491.     # check if it exists
  4492.     set exists 0
  4493.     set className [[[$this assocAttr] ooplClass] getSTName]
  4494.     foreach attribute [[[$this assocAttr] ooplClass] dataAttrSet] {
  4495.         if { [$attribute getSTName] == $qualifier } {
  4496.             if { [$attribute isClassFeature] || \
  4497.                  ([$attribute getPropertyValue isPoolDict] == "1") } {
  4498.                 m4_warning $WST_QUALNOINSTC $qualifier $className
  4499.                 incr warningnr 1
  4500.             } else {
  4501.                 set exists 1
  4502.             }    
  4503.         }
  4504.     }
  4505.     if { (!$exists) && ($userQualifier != "") } {
  4506.         m4_warning $WST_QUALNOTDEF $qualifier $className
  4507.         incr warningnr 1
  4508.     }
  4509.     return $warningnr
  4510. }
  4511.  
  4512. # Do not delete this line -- regeneration end marker
  4513.  
  4514.  
  4515.  
  4516. #---------------------------------------------------------------------------
  4517. #      File:           @(#)stgassocat.tcl    /main/titanic/3
  4518.  
  4519.  
  4520. # Generator class for normal association attributes.
  4521.  
  4522. Class STGAssocAttr : {STGGenAssocAttr} {
  4523.     constructor
  4524.     method destructor
  4525.     method setGenerator
  4526. }
  4527.  
  4528. constructor STGAssocAttr {class this name} {
  4529.     set this [STGGenAssocAttr::constructor $class $this $name]
  4530.     # Start constructor user section
  4531.     # End constructor user section
  4532.     return $this
  4533. }
  4534.  
  4535. method STGAssocAttr::destructor {this} {
  4536.     # Start destructor user section
  4537.     # End destructor user section
  4538. }
  4539.  
  4540.  
  4541. # Set generator to assocOne or assocMany
  4542. # exceptions:  
  4543. # * opposite of a qualified attribute with multiplicity one,
  4544. # where a oneoppqual generator is used.
  4545. # * opposite of a qualified attribute with multiplicity many, where a qualMany
  4546. # is used.
  4547. # In these two special cases set up the
  4548. # qualifierName and qualifierParameter 
  4549. # attributes in the generator.
  4550. #
  4551. method STGAssocAttr::setGenerator {this} {
  4552.     set opposite [$this opposite]
  4553.     if { $opposite != "" } {
  4554.     if [$opposite isQualified] {
  4555.         if { [$this getMultiplicity] == "one" } {
  4556.         $this generator [STGOneOppQual new $this]
  4557.         } else {
  4558.         $this generator [STGManyQual new $this]
  4559.         }
  4560.         set qualifier [$opposite qualifier]
  4561.         [$this generator] qualifierName [$qualifier getSTName]
  4562.         [$this generator] qualifierParameter [$qualifier getArgumentName]
  4563.         return
  4564.     }
  4565.     }
  4566.     
  4567.     if { [$this getMultiplicity] == "one" } {
  4568.     $this generator [STGAssocOne new $this]
  4569.     } else {
  4570.     $this generator [STGAssocMany new $this]
  4571.     }
  4572. }
  4573.  
  4574. # Do not delete this line -- regeneration end marker
  4575.  
  4576. if [isCommand CMAssocAttr] {
  4577.     Class  STGAssocAttrD : {STGAssocAttr CMAssocAttr} {
  4578.     }
  4579. } else {
  4580.     Class STGAssocAttrD : {STGAssocAttr OPAssocAttr} {    
  4581.     }
  4582. }
  4583.  
  4584. global mostDerivedOOPL ; set mostDerivedOOPL(OPAssocAttr) STGAssocAttrD
  4585.  
  4586. selfPromoter OPAssocAttr {this} {
  4587.     STGAssocAttrD promote $this
  4588. }
  4589.  
  4590.  
  4591. #---------------------------------------------------------------------------
  4592. #      File:           @(#)stglinkatt.tcl    /main/titanic/3
  4593.  
  4594.  
  4595. # Generates for link attributes.
  4596.  
  4597. Class STGLinkAttr : {STGGenAssocAttr} {
  4598.     constructor
  4599.     method destructor
  4600.     method setGenerator
  4601.     method setNames
  4602.     method argumentName
  4603. }
  4604.  
  4605. constructor STGLinkAttr {class this name} {
  4606.     set this [STGGenAssocAttr::constructor $class $this $name]
  4607.     # Start constructor user section
  4608.     # End constructor user section
  4609.     return $this
  4610. }
  4611.  
  4612. method STGLinkAttr::destructor {this} {
  4613.     # Start destructor user section
  4614.     # End destructor user section
  4615. }
  4616.  
  4617.  
  4618. # Initializes generator for link attribute: 
  4619. # * multiplicity one: uses assocOne
  4620. # * multiplicity many: uses assocMany
  4621. #
  4622. method STGLinkAttr::setGenerator {this} {
  4623.     if { [$this getMultiplicity] == "one" } {
  4624.     $this generator [STGAssocOne new $this]
  4625.     } else {
  4626.     $this generator [STGAssocMany new $this]
  4627.     }
  4628. }
  4629.  
  4630.  
  4631. # Set the roleName in the generator to <linkclass_name>Of<role_name> and parameterName accordingly.
  4632. #
  4633. method STGLinkAttr::setNames {this} {
  4634.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  4635.     set name "${linkClassName}Of[cap [$this getSTName]]"
  4636.     [$this generator] roleName $name
  4637.     [$this generator] parameterName [$this asArgument $name]
  4638. }
  4639.  
  4640.  
  4641. # Return name for this link when used as parameter.
  4642. #
  4643. method STGLinkAttr::argumentName {this} {
  4644.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  4645.     set name "${linkClassName}Of[cap [$this getSTName]]"
  4646.     return [$this asArgument $name]
  4647. }
  4648.  
  4649. # Do not delete this line -- regeneration end marker
  4650.  
  4651. if [isCommand CMLinkAttr] {
  4652.     Class  STGLinkAttrD : {STGLinkAttr CMLinkAttr} {
  4653.     }
  4654. } else {
  4655.     Class STGLinkAttrD : {STGLinkAttr OPLinkAttr} {    
  4656.     }
  4657. }
  4658.  
  4659. global mostDerivedOOPL ; set mostDerivedOOPL(OPLinkAttr) STGLinkAttrD
  4660.  
  4661. selfPromoter OPLinkAttr {this} {
  4662.     STGLinkAttrD promote $this
  4663. }
  4664.  
  4665.  
  4666. #---------------------------------------------------------------------------
  4667. #      File:           @(#)stgqualass.tcl    /main/titanic/3
  4668.  
  4669.  
  4670. # Generator for qualified associations.
  4671.  
  4672. Class STGQualAssocAttr : {STGGenAssocAttr} {
  4673.     constructor
  4674.     method destructor
  4675.     method setGenerator
  4676. }
  4677.  
  4678. constructor STGQualAssocAttr {class this name} {
  4679.     set this [STGGenAssocAttr::constructor $class $this $name]
  4680.     # Start constructor user section
  4681.     # End constructor user section
  4682.     return $this
  4683. }
  4684.  
  4685. method STGQualAssocAttr::destructor {this} {
  4686.     # Start destructor user section
  4687.     # End destructor user section
  4688. }
  4689.  
  4690.  
  4691. # Sets generator: oneQualified or manyQualified.
  4692. #
  4693. method STGQualAssocAttr::setGenerator {this} {
  4694.     if { [$this getMultiplicity] == "one" } {
  4695.         $this generator [STGOneQual new $this]
  4696.     } else {
  4697.         $this generator [STGManyQual new $this]
  4698.     }
  4699.     [$this generator] qualifierName [[$this qualifier] getSTName]
  4700.     [$this generator] qualifierParameter [[$this qualifier] getArgumentName]
  4701. }
  4702.  
  4703. # Do not delete this line -- regeneration end marker
  4704.  
  4705. if [isCommand CMQualAssocAttr] {
  4706.     Class  STGQualAssocAttrD : {STGQualAssocAttr CMQualAssocAttr} {
  4707.     }
  4708. } else {
  4709.     Class STGQualAssocAttrD : {STGQualAssocAttr OPQualAssocAttr} {    
  4710.     }
  4711. }
  4712.  
  4713. global mostDerivedOOPL ; set mostDerivedOOPL(OPQualAssocAttr) STGQualAssocAttrD
  4714.  
  4715. selfPromoter OPQualAssocAttr {this} {
  4716.     STGQualAssocAttrD promote $this
  4717. }
  4718.  
  4719.  
  4720. #---------------------------------------------------------------------------
  4721. #      File:           @(#)stgquallin.tcl    /main/titanic/3
  4722.  
  4723.  
  4724. # Generator class for qualified link attributes.
  4725.  
  4726. Class STGQualLinkAttr : {STGGenAssocAttr} {
  4727.     constructor
  4728.     method destructor
  4729.     method setGenerator
  4730.     method setNames
  4731.     method argumentName
  4732. }
  4733.  
  4734. constructor STGQualLinkAttr {class this name} {
  4735.     set this [STGGenAssocAttr::constructor $class $this $name]
  4736.     # Start constructor user section
  4737.     # End constructor user section
  4738.     return $this
  4739. }
  4740.  
  4741. method STGQualLinkAttr::destructor {this} {
  4742.     # Start destructor user section
  4743.     # End destructor user section
  4744. }
  4745.  
  4746.  
  4747. # Set the generator: use the generators for normal qualified associations.
  4748. #
  4749. method STGQualLinkAttr::setGenerator {this} {
  4750.     if { [$this getMultiplicity] == "one" } {
  4751.     $this generator [STGOneQual new $this]
  4752.     } else {
  4753.     $this generator [STGManyQual new $this]    
  4754.     }
  4755.     [$this generator] qualifierName [[$this qualifier] getSTName]
  4756.     [$this generator] qualifierParameter [[$this qualifier] getArgumentName]
  4757. }
  4758.  
  4759.  
  4760. # Set role name to <link_name>Of<role_name> style and parameterName accordingly.
  4761. #
  4762. method STGQualLinkAttr::setNames {this} {
  4763.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  4764.     set name "${linkClassName}Of[cap [$this getSTName]]"
  4765.     [$this generator] roleName $name
  4766.     [$this generator] parameterName [$this asArgument $name]
  4767. }
  4768.  
  4769.  
  4770. # Return name for this attribute when used as parameter.
  4771. #
  4772. method STGQualLinkAttr::argumentName {this} {
  4773.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  4774.     set name "${linkClassName}Of[cap [$this getSTName]]"
  4775.     return [$this asArgument $name]
  4776. }
  4777.  
  4778. # Do not delete this line -- regeneration end marker
  4779.  
  4780. if [isCommand CMQualLinkAttr] {
  4781.     Class  STGQualLinkAttrD : {STGQualLinkAttr CMQualLinkAttr} {
  4782.     }
  4783. } else {
  4784.     Class STGQualLinkAttrD : {STGQualLinkAttr OPQualLinkAttr} {    
  4785.     }
  4786. }
  4787.  
  4788. global mostDerivedOOPL ; set mostDerivedOOPL(OPQualLinkAttr) STGQualLinkAttrD
  4789.  
  4790. selfPromoter OPQualLinkAttr {this} {
  4791.     STGQualLinkAttrD promote $this
  4792. }
  4793.  
  4794.  
  4795. #---------------------------------------------------------------------------
  4796. #      File:           @(#)stgreverse.tcl    /main/titanic/3
  4797.  
  4798.  
  4799. # Generator class for reverse link attributes.
  4800.  
  4801. Class STGReverseLinkAttr : {STGGenAssocAttr} {
  4802.     constructor
  4803.     method destructor
  4804.     method setGenerator
  4805. }
  4806.  
  4807. constructor STGReverseLinkAttr {class this name} {
  4808.     set this [STGGenAssocAttr::constructor $class $this $name]
  4809.     # Start constructor user section
  4810.     # End constructor user section
  4811.     return $this
  4812. }
  4813.  
  4814. method STGReverseLinkAttr::destructor {this} {
  4815.     # Start destructor user section
  4816.     # End destructor user section
  4817. }
  4818.  
  4819.  
  4820. # Sets the generator: an assocOne for a reverse link in a normal link association or a 
  4821. # oneOppQual for the opposite of a qualified  association.
  4822. #
  4823. method STGReverseLinkAttr::setGenerator {this} {
  4824.     set opposite [$this opposite]
  4825.     set qualifier ""
  4826.     if { $opposite != "" } {
  4827.     if [$opposite isQualified] {
  4828.         set qualifier [$opposite qualifier]
  4829.     }
  4830.     }
  4831.     if { $qualifier != "" } {
  4832.     $this generator [STGOneOppQual new $this]
  4833.     [$this generator] qualifierName [$qualifier getSTName]
  4834.     [$this generator] qualifierParameter [$qualifier getArgumentName]
  4835.     } else {
  4836.     $this generator [STGAssocOne new $this] 
  4837.     }
  4838. }
  4839.  
  4840. # Do not delete this line -- regeneration end marker
  4841.  
  4842. if [isCommand CMReverseLinkAttr] {
  4843.     Class  STGReverseLinkAttrD : {STGReverseLinkAttr CMReverseLinkAttr} {
  4844.     }
  4845. } else {
  4846.     Class STGReverseLinkAttrD : {STGReverseLinkAttr OPReverseLinkAttr} {    
  4847.     }
  4848. }
  4849.  
  4850. global mostDerivedOOPL ; set mostDerivedOOPL(OPReverseLinkAttr) STGReverseLinkAttrD
  4851.  
  4852. selfPromoter OPReverseLinkAttr {this} {
  4853.     STGReverseLinkAttrD promote $this
  4854. }
  4855.