home *** CD-ROM | disk | FTP | other *** search
/ PC World 1997 November / PCWorld_1997-11_cd.bin / software / programy / komix / DATA.Z / stgclasses.tcl < prev    next >
Text File  |  1997-04-18  |  108KB  |  3,753 lines

  1. #--------------------------------------------------------------------------
  2. #
  3. #      (c)     Cayenne Software Inc.    1997
  4. #
  5. #      File:           %W%
  6. #      Author:         <generated>
  7. #
  8. #--------------------------------------------------------------------------
  9.  
  10. #      File:           @(#)stgobject.tcl    /main/1
  11.  
  12.  
  13. # This class contains generic Smalltalk code
  14. # generation object methods.
  15.  
  16. Class STGObject : {Object} {
  17.     constructor
  18.     method destructor
  19.     method asSTName
  20.     method asArgument
  21.     method getSTName
  22.     method getArgumentName
  23.  
  24.     # Stores name of this object in Smalltalk compliant format
  25.     # e.g. with illegal characters filtered out.
  26.     #
  27.     attribute stName
  28.  
  29.     # Used to store the argument name of this object.
  30.     #
  31.     attribute argName
  32. }
  33.  
  34. constructor STGObject {class this name} {
  35.     set this [Object::constructor $class $this $name]
  36.     # Start constructor user section
  37.     # End constructor user section
  38.     return $this
  39. }
  40.  
  41. method STGObject::destructor {this} {
  42.     # Start destructor user section
  43.     # End destructor user section
  44. }
  45.  
  46.  
  47. # Makes name an ST compliant name by filtering out
  48. # illegal characters and returns it.
  49. #
  50. method STGObject::asSTName {this name} {
  51.     # remove illegal characters from name
  52.     # Illegal characters are all characters except a-z, A-Z, 0-9 and _
  53.     if [regsub -all {[^a-zA-Z0-9_]} $name "" newName ] {
  54.     puts "WARNING: Removed illegal characters from $name"
  55.     }
  56.     return $newName
  57. }
  58.  
  59.  
  60. # Transforms <name> into argument name prepending a or an and returns it.
  61. #
  62. method STGObject::asArgument {this name} {
  63.     if { [string first [cap [string index $name 0]] "AEIOU"] > -1 } {
  64.     return "an[cap $name]"
  65.     }
  66.     return "a[cap $name]"
  67. }
  68.  
  69.  
  70. # Gets name for object, issues error if it is object without getName method.
  71. # Returns stName if it was set already, otherwise compute Smalltalk compliant
  72. # name, store in stName and return it.
  73. # Issues warning when illegal characters get filtered out.
  74. #
  75. method STGObject::getSTName {this} {
  76.     if { [$this stName] != "" } {
  77.     return [$this stName]
  78.     }
  79.     
  80.     if [catch { set oldName [$this getName] } ] {
  81.     puts "FAILURE HELP ALARM: getSTName called for object without name"
  82.     return "error"
  83.     }
  84.  
  85.     set newName [$this asSTName $oldName]
  86.     $this stName $newName
  87.     return $newName 
  88. }
  89.  
  90.  
  91. # If argName is already set, return it.
  92. # Otherwise determine argument name, set
  93. # argName and return it.
  94. #
  95. method STGObject::getArgumentName {this} {
  96.     if { [$this argName] != "" } {
  97.     return [$this argName]
  98.     }
  99.     
  100.     if [catch { $this argName [$this argumentName] } ] {
  101.     puts "FAILURE ALARM: getArgumentName called for object without argument name"
  102.     return "error"
  103.     }
  104.  
  105.     return [$this argName]  
  106. }
  107.  
  108. # Do not delete this line -- regeneration end marker
  109.  
  110.  
  111. #      File:           @(#)stgassocge.tcl    /main/1
  112.  
  113.  
  114. # Generic base class for association generators.
  115.  
  116. Class STGAssocGen : {GCObject} {
  117.     method destructor
  118.     constructor
  119.     method getPrivateImplementation
  120.     method getAccessImplementation
  121.     method getModifyImplementation
  122.     method getRemoveImplementation
  123.     method getErrorMessage
  124.     method generateNilCheck
  125.     method generateConstraintCheck
  126.     method generateIncludesCheck
  127.     method generateExistenceCheck
  128.     method generateRelease
  129.     method removePermitted
  130.     method removeRequired
  131.     method upperConstraint
  132.     method lowerConstraint
  133.     method setType
  134.     method assocAttr
  135.  
  136.     # Used to store the instance variable name used for this association attribute.
  137.     # Set in getData.
  138.     #
  139.     attribute variableName
  140.  
  141.     # Used to hold name of this association attribute in parameter format.
  142.     #
  143.     attribute parameterName
  144.  
  145.     # Used to store role name for this association attribute.
  146.     #
  147.     attribute roleName
  148.  
  149.     # Implementation object for the class; used to speed up things.
  150.     #
  151.     attribute classImplementation
  152.  
  153.     # Holds the qualifier name for qualified associations.
  154.     #
  155.     attribute qualifierName
  156.  
  157.     # Holds the argument name of the qualifier for qualified associations.
  158.     #
  159.     attribute qualifierParameter
  160.  
  161.     # The generator of the opposite of the association
  162.     # attribute of this generator.
  163.     #
  164.     attribute opposite
  165.     attribute _assocAttr
  166. }
  167.  
  168. method STGAssocGen::destructor {this} {
  169.     # Start destructor user section
  170.     $this opposite ""
  171.     $this classImplementation ""
  172.     $this _assocAttr ""
  173.     # End destructor user section
  174. }
  175.  
  176.  
  177. # Sets the assocAttr association to <assocAttr>.
  178. #
  179. constructor STGAssocGen {class this assocAttr} {
  180.     set this [GCObject::constructor $class $this]
  181.     $this _assocAttr $assocAttr
  182.     $this opposite ""
  183.     return $this
  184. }
  185.  
  186.  
  187. # Gets an implementation object for this selector in the instance private category.
  188. #
  189. method STGAssocGen::getPrivateImplementation {this selector} {
  190.     return [[$this classImplementation] getInstanceMethodImplementation $selector "private"]
  191. }
  192.  
  193.  
  194. # Gets an implementation object for this selector in the instance access associations category.
  195. #
  196. method STGAssocGen::getAccessImplementation {this selector} {
  197.     set category [[$this assocAttr] getReadCategory "association access"]
  198.     if { $category == "" } {
  199.     return ""
  200.     }
  201.     return [[$this classImplementation] getInstanceMethodImplementation $selector $category]
  202. }
  203.  
  204.  
  205. # Gets an implementation for this selector in the instance modify association category.
  206. #
  207. method STGAssocGen::getModifyImplementation {this selector} {
  208.     set category [[$this assocAttr] getWriteCategory "association modification"]
  209.     if { $category == "" } {
  210.     return ""
  211.     }
  212.     return [[$this classImplementation] getInstanceMethodImplementation $selector $category]
  213. }
  214.  
  215.  
  216. # Gets an implementation object for a remove method.
  217. #
  218. method STGAssocGen::getRemoveImplementation {this selector} {
  219.     set category [[$this assocAttr] getWriteCategory "association modification"]
  220.     if { ![$this removePermitted] } {
  221.     set category ""
  222.     }
  223.  
  224.     if { $category == "" } {
  225.     if [$this removeRequired] {
  226.         set category "private"
  227.     } else {
  228.         return ""
  229.     }
  230.     }
  231.     
  232.     return [[$this classImplementation] getInstanceMethodImplementation $selector $category]
  233. }
  234.  
  235.  
  236. # Returns error call string based on error type and selector.
  237. #
  238. method STGAssocGen::getErrorMessage {this errorType selector} {
  239.     set errorMessage [[$globals errorDictionary] set $errorType]
  240.     if { $errorMessage == "" } {
  241.     puts "ERROR: Unknown error $errorType"
  242.     set errorMessage "Unknown error"
  243.     }
  244.     set errorMessage "$errorMessage in $selector in [[[$this assocAttr] ooplClass] getSTName]"    
  245.     return "self error: \'$errorMessage\'"
  246. }
  247.  
  248.  
  249. # Generate nil check for name in block:
  250. # if name is nil generate an error call.
  251. #
  252. method STGAssocGen::generateNilCheck {this block name} {
  253.     set expr [$block addExpression "$name isNil ifTrue:"]
  254.     set selector [$block selector]
  255.     $expr addExpression [$this getErrorMessage PARAMETER_NIL $selector]
  256. }
  257.  
  258.  
  259. # Generates a constraint check in block, this expressions
  260. # check whether the size of <name> is greater than/smaller than bound,
  261. # depending on type. Returns the expression.
  262. #
  263. method STGAssocGen::generateConstraintCheck {this selector block name bound type} {
  264.     if { $type == "upper" } {
  265.     set sizeCheck "$name size < $bound"
  266.     } else {
  267.     set sizeCheck "$name size > $bound"
  268.     }
  269.     set block [$block addExpression "$sizeCheck ifTrue:"]
  270.     set errorPart [$block addExpressionPart "ifFalse:"]
  271.     $errorPart addExpression [$this getErrorMessage CONSTRAINT $selector]
  272.     return $block
  273. }
  274.  
  275.  
  276. # Generates an include check for element in name, adds it to block and returns the new expression.
  277. #
  278. method STGAssocGen::generateIncludesCheck {this block name element} {
  279.     set block [$block addExpression "($name includes: $element) ifFalse:"]
  280.     return $block
  281. }
  282.  
  283.  
  284. # Generates a check expression that checks whether element is
  285. # in name and generates an error if this is not the case.
  286. #
  287. method STGAssocGen::generateExistenceCheck {this selector block name element} {
  288.     set block [$this generateIncludesCheck $block $name $element] 
  289.     $block addExpression [$this getErrorMessage ASSOC_OBJ_NOT_FOUND $selector]
  290. }
  291.  
  292.  
  293. # Generates additions to release to release the association
  294. # to which this association attribute belongs.
  295. #
  296. method STGAssocGen::generateRelease {this} {
  297.     set release [[$this classImplementation] release]
  298.     if [[$this assocAttr] oppositeMandatoryOne] {
  299.     $release insertExpression [$this getErrorMessage CANNOT_RELEASE release]
  300.     } else {
  301.     $this generateReleaseCode $release
  302.     }    
  303. }
  304.  
  305.  
  306. # Returns 1 if generation of a public remove is permitted.
  307. #
  308. method STGAssocGen::removePermitted {this} {
  309.     if [[$this assocAttr] oppositeMandatoryOne]  {
  310.     return 0
  311.     }
  312.  
  313.     return 1
  314. }
  315.  
  316.  
  317. # Returns 1 if generation of remove method is required for the generation
  318. # of other methods.
  319. #
  320. method STGAssocGen::removeRequired {this} {
  321.     set opposite [[$this assocAttr] opposite]
  322.     if { $opposite == "" } {
  323.     return 0
  324.     }
  325.  
  326.     if { [$opposite isMandatory] || ([$opposite writeAccess] != "None") } {
  327.     return 1
  328.     }
  329.     return 0
  330. }
  331.  
  332.  
  333. # Gets upper bound of constraint for this association.
  334. #
  335. method STGAssocGen::upperConstraint {this} {
  336.     set constraint [[$this assocAttr] getConstraint]
  337.     if { $constraint == "" } {
  338.     return ""
  339.     }
  340.     if { [string first "\{" $constraint] != -1 } {
  341.     return ""
  342.     }
  343.  
  344.     set dashIndex [string first "-" $constraint]
  345.     if { $dashIndex == -1 } {
  346.     set plusIndex [string first "+" $constraint]
  347.     if { $plusIndex == -1 } {
  348.         return $constraint
  349.     } else {
  350.         return "" 
  351.     }
  352.     } else {
  353.     return [string range $constraint [expr $dashIndex+1] end]
  354.     } 
  355. }
  356.  
  357.  
  358. # Get lower bound of constraint for this association.
  359. #
  360. method STGAssocGen::lowerConstraint {this} {
  361.     set constraint [[$this assocAttr] getConstraint]
  362.     if { $constraint == "" } {
  363.     return ""
  364.     }
  365.     if { [string first "\{" $constraint] != -1 } {
  366.     return ""
  367.     }
  368.  
  369.     set dashIndex [string first "-" $constraint]
  370.     if { $dashIndex == -1 } {
  371.     set plusIndex [string first "+" $constraint]
  372.     if { $plusIndex == -1 } {
  373.         return $constraint
  374.     } else {
  375.         return [string range $constraint 0 [expr $plusIndex-1]]
  376.     }
  377.     } else {
  378.     return [string range $constraint 0 [expr $dashIndex-1]]
  379.     } 
  380. }
  381.  
  382.  
  383. # Returns set type to be used to implement this
  384. # association.
  385. #
  386. method STGAssocGen::setType {this} {
  387.     if [[$this assocAttr] isOrdered] {
  388.     return "OrderedCollection"
  389.     }
  390.     return "Set"
  391. }
  392.  
  393. # Do not delete this line -- regeneration end marker
  394.  
  395. method STGAssocGen::assocAttr {this args} {
  396.     if {$args == ""} {
  397.         return [$this _assocAttr]
  398.     }
  399.     set ref [$this _assocAttr]
  400.     if {$ref != ""} {
  401.         $ref _generator ""
  402.     }
  403.     set obj [lindex $args 0]
  404.     if {$obj != ""} {
  405.         $obj _generator $this
  406.     }
  407.     $this _assocAttr $obj
  408. }
  409.  
  410.  
  411. #      File:           @(#)stgassocin.tcl    /main/1
  412.  
  413.  
  414. # Generator class for association initializers.
  415.  
  416. Class STGAssocInitializer : {STGObject OPAssocInitializer} {
  417.     constructor
  418.     method destructor
  419.     method generate
  420. }
  421.  
  422. constructor STGAssocInitializer {class this name} {
  423.     set this [STGObject::constructor $class $this $name]
  424.     # Start constructor user section
  425.     # End constructor user section
  426.     return $this
  427. }
  428.  
  429. method STGAssocInitializer::destructor {this} {
  430.     # Start destructor user section
  431.     # End destructor user section
  432. }
  433.  
  434.  
  435. # Get argument name for initializer and add it to
  436. # the constructor argument list.
  437. #
  438. method STGAssocInitializer::generate {this} {
  439.     # set hasInitializer attribute in association attribute
  440.     [$this assoc] hasInitializer 1
  441.  
  442.     set constructor [[$this constructor] methodImplementation]
  443.     set argName [[$this assoc] getArgumentName]
  444.     $constructor getUniqueArgumentName [$this getSTName] $argName
  445. }
  446.  
  447. # Do not delete this line -- regeneration end marker
  448.  
  449. selfPromoter OPAssocInitializer {this} {
  450.     STGAssocInitializer promote $this
  451. }
  452.  
  453. #      File:           @(#)stgattribi.tcl    /main/1
  454.  
  455.  
  456. # Attribute initializer generator.
  457.  
  458. Class STGAttribInitializer : {STGObject OPAttribInitializer} {
  459.     constructor
  460.     method destructor
  461.     method generate
  462. }
  463.  
  464. constructor STGAttribInitializer {class this name} {
  465.     set this [STGObject::constructor $class $this $name]
  466.     # Start constructor user section
  467.     # End constructor user section
  468.     return $this
  469. }
  470.  
  471. method STGAttribInitializer::destructor {this} {
  472.     # Start destructor user section
  473.     # End destructor user section
  474. }
  475.  
  476.  
  477. # Determines the argument name and adds it to constructor parameters.
  478. # Generates an expression in the constructor to set the attribute
  479. # to the value supplied by the parameter.
  480. #
  481. method STGAttribInitializer::generate {this} {
  482.     set attrib [$this attrib]
  483.     # set hasInitializer in data attribute
  484.     $attrib hasInitializer 1
  485.  
  486.     set constructor [[$this constructor] methodImplementation]
  487.     set argName [$attrib getArgumentName]
  488.  
  489.     # Use original attrib name to avoid i_ 's
  490.     set name [$attrib getSTName]
  491.     if [$attrib isClassFeature] {
  492.     set name [cap $name]
  493.     }
  494.  
  495.     set uniqueName [$constructor getUniqueArgumentName $name $argName]
  496.     $constructor addExpression "$name := $uniqueName"
  497. }
  498.  
  499. # Do not delete this line -- regeneration end marker
  500.  
  501. selfPromoter OPAttribInitializer {this} {
  502.     STGAttribInitializer promote $this
  503. }
  504.  
  505. #      File:           @(#)stgattribu.tcl    /main/1
  506.  
  507.  
  508. # This class contains generic attribute generation methods.
  509.  
  510. Class STGAttribute : {STGObject} {
  511.     constructor
  512.     method destructor
  513.     method getReadCategory
  514.     method getWriteCategory
  515.     method readAccess
  516.     method writeAccess
  517.  
  518.     # This attribute is set during generation and indicates whether there is an
  519.     # initializer for this attribute.
  520.     # Note: this can only work if generation for initializers is done before generation for attributes.
  521.     #
  522.     attribute hasInitializer
  523. }
  524.  
  525. constructor STGAttribute {class this name} {
  526.     set this [STGObject::constructor $class $this $name]
  527.     # Start constructor user section
  528.     # End constructor user section
  529.     return $this
  530. }
  531.  
  532. method STGAttribute::destructor {this} {
  533.     # Start destructor user section
  534.     # End destructor user section
  535.     $this STGObject::destructor
  536. }
  537.  
  538.  
  539. # Returns category name based on read access:
  540. # * return empty string if None
  541. # * return private if Private
  542. # * return <name> if Public
  543. #
  544. method STGAttribute::getReadCategory {this name} {
  545.     set readAccess [$this readAccess]
  546.     if { $readAccess == "None" } {
  547.     return ""
  548.     }
  549.     if { $readAccess == "Private" } {
  550.     return "private"
  551.     } else {
  552.     return $name
  553.     }
  554. }
  555.  
  556.  
  557. # Returns category name based on write access specification:
  558. # as in getReadCategory.
  559. #
  560. method STGAttribute::getWriteCategory {this name} {
  561.     set writeAccess [$this writeAccess]
  562.     if { $writeAccess == "None" } {
  563.     return ""
  564.     }
  565.     if { $writeAccess == "Private" } {
  566.     return "private"
  567.     } else {
  568.     return $name
  569.     }
  570. }
  571.  
  572.  
  573. # Returns read access specification.
  574. #
  575. method STGAttribute::readAccess {this} {
  576.     set accessList [split [$this getPropertyValue attribAccess] '-']
  577.     return [lindex $accessList 0] 
  578. }
  579.  
  580.  
  581. # Returns write access specification.
  582. #
  583. method STGAttribute::writeAccess {this} {
  584.     set accessList [split [$this getPropertyValue attribAccess] '-']
  585.     return [lindex $accessList 1] 
  586. }
  587.  
  588. # Do not delete this line -- regeneration end marker
  589.  
  590.  
  591. #      File:           @(#)stgclass.tcl    /main/1
  592.  
  593.  
  594. # This class is the top level class generator.
  595. # It generates the entire class implementation.
  596.  
  597. Class STGClass : {STGObject} {
  598.     constructor
  599.     method destructor
  600.     method generate
  601.     method generateRelease
  602.     method generatePrint
  603.     method generateComment
  604.     method generateDefinition
  605.     method generateInheritanceType
  606.     method printGeneratingMessage
  607.     method getSTName
  608.  
  609.     # Set if this class is abstract e.g. has an abstract method.
  610.     # It is set by operation generators and used by the constructor generator.
  611.     # Correct operation assumes that operations are generated before the constructor!
  612.     #
  613.     attribute isAbstract
  614.     attribute classImplementation
  615.     attribute super
  616. }
  617.  
  618. constructor STGClass {class this name} {
  619.     set this [STGObject::constructor $class $this $name]
  620.     # Start constructor user section
  621.     # End constructor user section
  622.     return $this
  623. }
  624.  
  625. method STGClass::destructor {this} {
  626.     # Start destructor user section
  627.     # End destructor user section
  628. }
  629.  
  630.  
  631. # Generate the implementation of this class in grammar
  632. # object classImpl.
  633. #
  634. method STGClass::generate {this classImpl} {
  635.     # cache the implementation object
  636.     $this classImplementation $classImpl
  637.  
  638.     # just call the methods in the right order
  639.     $this printGeneratingMessage
  640.     $this generateDefinition
  641.     $this generateComment
  642.  
  643.     # Generate for all the features
  644.     
  645.     foreach method [$this operationSet] {
  646.     $method generate
  647.     }
  648.  
  649.     $this generateRelease
  650.  
  651.     set constructor [$this constructor]
  652.     if { $constructor != "" } {
  653.     $constructor generate
  654.     }
  655.  
  656.     if [$globals generatePrint] {
  657.     $this generatePrint
  658.     }
  659.  
  660.     foreach attribute [$this dataAttrSet] {
  661.     $attribute generate
  662.     }
  663.     
  664.     foreach attribute [$this genAssocAttrSet] {
  665.     $attribute generate
  666.     }
  667.  
  668.     $this classImplementation ""
  669. }
  670.  
  671.  
  672. # Generates the release method and part of it's
  673. # implementation.
  674. #
  675. method STGClass::generateRelease {this} {
  676.     set classImpl [$this classImplementation]
  677.     set release [$classImpl getInstanceMethodImplementation "release" "initialize-release"]
  678.     $release addExpression "super release"
  679.     $release hasUserCodePart 1
  680.     $classImpl release $release
  681. }
  682.  
  683.  
  684. # Generates the printing methods and part of
  685. # their implementation. If there is a user defined method
  686. # with the same selector don't generate.
  687. #
  688. method STGClass::generatePrint {this} {
  689.     set classImpl [$this classImplementation]
  690.     
  691.     # check if one of them or both  existed already
  692.     if { [$classImpl methodExists "printOn:"] || [$classImpl methodExists "printVars:withIndent:"] } {
  693.     puts "WARNING: Not generating printOn and printVars: already defined by user"
  694.     set printOn ""
  695.     set printVars ""
  696.     } else {
  697.     set printOn [$classImpl getInstanceMethodImplementation "printOn:" "printing"]
  698.     set printVars [$classImpl getInstanceMethodImplementation "printVars:withIndent:" "printing"]
  699.  
  700.     $printOn addArgument aStream
  701.     $printVars addArgument aStream
  702.     $printVars addArgument anInteger
  703.  
  704.     # generate start of printOn implementation
  705.     $printOn addExpression "super printOn: aStream"
  706.  
  707.     # if super class is in this system call it's printVars
  708.     if { [$this super] != "" } {
  709.         if { ![[$this super] isExternal] } {
  710.         $printVars addExpression "super printVars: aStream withIndent: anInteger"
  711.         }
  712.     } 
  713.     }
  714.  
  715.     # cache the methods
  716.     $classImpl printOn $printOn
  717.     $classImpl printVars $printVars    
  718. }
  719.  
  720.  
  721. # Generate the FreeText property in the class comment.
  722. #
  723. method STGClass::generateComment {this} {
  724.     if [regsub -all {'} [$this getPropertyValue freeText] "" comment] {
  725.     puts "WARNING: Removed \' from comment for [$this getSTName]"
  726.     }
  727.     [$this classImplementation]  addCommentLine $comment 
  728. }
  729.  
  730.  
  731. # Generate superclass, inheritance type and category
  732. # in the classImplementation object. Sets the super
  733. # association.
  734. #
  735. method STGClass::generateDefinition {this} {
  736.     set classImpl [$this classImplementation]
  737.  
  738.     # get superclass
  739.     set gnodeSet [$this genNodeSet]
  740.  
  741.     if { [llength $gnodeSet] > 1 } {
  742.     puts "ERROR: [$this getSTName]: Multiple inheritance not supported; discarding additional superclasses"
  743.     }
  744.  
  745.     if { [llength $gnodeSet] == 0 } {
  746.     puts "WARNING: Class [$this getSTName] has no superclasses, defaulting to Object"
  747.     $this super ""
  748.     $classImpl super "Object"
  749.     } else {
  750.     $this super [[lindex $gnodeSet 0] superClass]
  751.     $classImpl super [[$this super] getSTName]
  752.     }
  753.  
  754.     $this generateInheritanceType
  755.  
  756.     # get category
  757.  
  758.     set category [$this getPropertyValue classCategory]
  759.  
  760.     if { $category == "" } {
  761.     # not set, use default: diagram or system name
  762.     if { [$globals defaultCategory] == "System" } {
  763.         set cc [ClientContext::global]
  764.         set category [[[$cc currentSystem] system] name]
  765.     } else {
  766.         # more complicated: get all components and find first
  767.         # diagram 
  768.         set smNode [$this smNode]
  769.         set component [lindex [$smNode getComponents] 0]
  770.         set category [[[$component diagram] file] name]
  771.     }
  772.     }
  773.     $classImpl category $category
  774. }
  775.  
  776.  
  777. # Generates inheritance type from the property inheritanceType.
  778. # Perfroms checks on this type and issues warnings or errors if it
  779. # is likely to give problems in Smalltalk.
  780. #
  781. method STGClass::generateInheritanceType {this} {
  782.     set inheritanceType [$this getPropertyValue inheritanceType]
  783.  
  784.     if { ($inheritanceType == "regular") || ($inheritanceType == "") } {
  785.     [$this classImplementation] inheritanceType ""
  786.     set inheritanceType "regular"
  787.     } else {
  788.     [$this classImplementation]  inheritanceType $inheritanceType
  789.     }
  790.  
  791.     if { [$this super] != "" } {
  792.     set superInheritanceType [[$this super] getPropertyValue inheritanceType]
  793.     if { $superInheritanceType == "" } {
  794.         set superInheritanceType "regular"
  795.     }
  796.  
  797.     # different inheritance types with superclass inheritance other
  798.     # than regular may cause trouble. Print cautious warning as we don't
  799.     # know for sure Smalltalk will reject it.
  800.     if { ($superInheritanceType != $inheritanceType) && \
  801.         ($superInheritanceType != "regular") } {
  802.         puts "WARNING: Class [$this getSTName] with $inheritanceType inheritance and superclass [[$this super] getSTName] with $superInheritanceType inheritance may not be accepted by Smalltalk"
  803.     }
  804.     }
  805.  
  806.     if { $inheritanceType != "variableByte" } {
  807.     return
  808.     }
  809.     
  810.     # If this class has instance variables (possibly by
  811.     # inheritance it may not be accepted by Smalltalk
  812.     # So scan superclasses. This may be slow but variableByte inheritance
  813.     # will not be used very often (?)
  814.  
  815.     set checkClass $this
  816.     set hasInstanceVariables 0
  817.     while { $checkClass != "" } {
  818.     # associations cause instance variables
  819.     if { [$checkClass genAssocAttrSet] != "" } {
  820.         set hasInstanceVariables 1
  821.         break
  822.     }
  823.     # data attributes cause instance variables if the isPoolDict
  824.     # property is not set and isClassFeature returns 0
  825.     foreach dataAttr [$checkClass dataAttrSet] {
  826.         if { (![$dataAttr isClassFeature]) && ([$dataAttr getPropertyValue isPoolDict] != "1") } {
  827.         set hasInstanceVariables 1
  828.         break
  829.         }
  830.     }
  831.     # find superclass
  832.     set gnodeSet [$checkClass genNodeSet]
  833.  
  834.     if { [llength $gnodeSet] == 0 } {
  835.         set checkClass ""
  836.     } else {
  837.         set checkClass [[lindex $gnodeSet 0] superClass]
  838.     }
  839.     }
  840.  
  841.     if $hasInstanceVariables {
  842.     puts "WARNING: class [$this getSTName] with variableByte inheritance and instance variables may not be accepted by Smalltalk"
  843.     }
  844. }
  845.  
  846.  
  847. # Print a message stating that generation for this class is in progress.
  848. #
  849. method STGClass::printGeneratingMessage {this} {
  850.     puts "Generating for class [$this getSTName]"
  851. }
  852.  
  853.  
  854. # Redefines getSTName to make sure the class name starts with an uppercase charcter.
  855. #
  856. method STGClass::getSTName {this} {
  857.     if { [$this stName] == "" } {
  858.     $this stName [cap [$this asSTName [$this getName]]]
  859.     }
  860.     return [$this stName]
  861. }
  862.  
  863. # Do not delete this line -- regeneration end marker
  864.  
  865. Class STGClassD : {STGClass OPClass} {
  866. }
  867.  
  868. selfPromoter OPClass {this} {
  869.     STGClassD promote $this
  870. }
  871.  
  872. #      File:           @(#)stgconstru.tcl    /main/1
  873.  
  874.  
  875. # Constructor generator class.
  876.  
  877. Class STGConstructor : {STGObject OPConstructor} {
  878.     constructor
  879.     method destructor
  880.     method generate
  881.     method getMethodImplementation
  882.     method generateDescription
  883.     method generateNew
  884.     method generateRestrictedNew
  885.     method getSelector
  886.     method getMessage
  887.  
  888.     # Indicates whether the instance creation method must be generated.
  889.     # Set by super class initializer.
  890.     #
  891.     attribute newRequired
  892.  
  893.     # Used to store the selector for the instance creation method. Set in getMethodImplementation.
  894.     #
  895.     attribute newSelector
  896.     attribute methodImplementation
  897. }
  898.  
  899. constructor STGConstructor {class this name} {
  900.     set this [STGObject::constructor $class $this $name]
  901.     # Start constructor user section
  902.     # End constructor user section
  903.     return $this
  904. }
  905.  
  906. method STGConstructor::destructor {this} {
  907.     # Start destructor user section
  908.     # End destructor user section
  909. }
  910.  
  911.  
  912. # Generates the equivalent of a constructor:
  913. # * determines message selector and gets implementation object.
  914. # * Generates a description
  915. # * generates for the initializers
  916. # * generates a redefined new if required.
  917. # * generates a new if indicated by newRequired.
  918. #
  919. method STGConstructor::generate {this} {
  920.     $this getMethodImplementation
  921.     $this generateDescription
  922.  
  923.     # default for newRequired is 1
  924.     $this newRequired 1
  925.  
  926.     foreach initializer [$this initializerSet] {
  927.     $initializer generate
  928.     }
  929.  
  930.     # Generate restricted new if another instance creation method is generated
  931.     if { ([$this newSelector] != "new") && [$this newRequired] } {
  932.     $this generateRestrictedNew    
  933.     }
  934.  
  935.     if [$this newRequired] {
  936.     $this generateNew
  937.     }
  938.  
  939.     $this methodImplementation ""
  940. }
  941.  
  942.  
  943. # Determines the message selector for the initialize method and gets
  944. # an implementation object. Sets the 'initialize' association of
  945. # the class implementation object.
  946. #
  947. method STGConstructor::getMethodImplementation {this} {
  948.     set parList [List new]
  949.     foreach parameter [[$this ooplClass] creationParamSet] {
  950.     $parList append [$this asSTName [$parameter getOriginalName]]
  951.     }
  952.  
  953.     set selector [$this getSelector initialize $parList]
  954.     $this newSelector [$this getSelector new $parList]
  955.  
  956.     # Now get the implementation object
  957.     set classImpl [[$this ooplClass] classImplementation]
  958.     set initialize [$classImpl getInstanceMethodImplementation $selector "initialize-release"] 
  959.  
  960.     # Store in generators
  961.     $classImpl initialize $initialize
  962.     $this methodImplementation $initialize
  963.     
  964.     $initialize hasUserCodePart 1
  965. }
  966.  
  967.  
  968. # Generates the freetext comment.
  969. #
  970. method STGConstructor::generateDescription {this} {
  971.     if [regsub -all {"} [$this getPropertyValue freeText] "" comment] {
  972.     puts "WARNING: Removed \" from constructor comment"
  973.     }
  974.     [$this methodImplementation] comment $comment
  975. }
  976.  
  977.  
  978. # Generates the instance creation method which
  979. # calls initialize. If the class is abstract generate 
  980. # expressions to check if this class can be instantiated.
  981. #
  982. method STGConstructor::generateNew {this} {
  983.     set selector [$this newSelector]
  984.  
  985.     # get implementation object
  986.     set classImpl [[$this ooplClass] classImplementation]
  987.     set new [$classImpl getClassMethodImplementation $selector "instance creation"]
  988.  
  989.     if [$new isUserDefined] {
  990.     puts "WARNING: Default constructor overrides user defined constructor"
  991.     $new isUserDefined 0
  992.     }
  993.     
  994.     # Create the initialize message
  995.     set initSelector [[$this methodImplementation] selector]
  996.     set argNames [List new]
  997.     [[$this methodImplementation] getArguments] foreach argName {
  998.     $argNames append [$new getNewUniqueArgumentName $argName]
  999.     }
  1000.     set initMessage [$this getMessage $initSelector $argNames]
  1001.  
  1002.     # Make the new or basicNew message
  1003.     if { ($selector != "new") && ([$this superClassInitializerSet] != "") } {
  1004.     set newMessage "self basicNew"
  1005.     } else {
  1006.     set newMessage "super new"
  1007.     } 
  1008.  
  1009.     # Add to implementation
  1010.     # Make it conditional for abstract classes
  1011.     set block $new
  1012.     if { [[$this ooplClass] isAbstract] == 1} {
  1013.     set className [[$this ooplClass] getSTName]
  1014.     set block [$new addExpression "(self class = $className) ifTrue:"] 
  1015.     $block addExpression "\^self error: \'Cannot instantiate abstract class\'"
  1016.     set block [$block addExpressionPart "ifFalse:"]
  1017.     }
  1018.     $block addExpression "^$newMessage $initMessage"
  1019. }
  1020.  
  1021.  
  1022. # Generate a new that forbids use of new.
  1023. #
  1024. method STGConstructor::generateRestrictedNew {this} {
  1025.     set classImpl [[$this ooplClass] classImplementation]
  1026.     set new [$classImpl getClassMethodImplementation "new" "instance creation"]
  1027.  
  1028.     if [$new isUserDefined] {
  1029.     puts "WARNING: user defined constructor overridden by automatically generated new"
  1030.     $new isUserDefined 0 
  1031.     }
  1032.     
  1033.     $new addExpression "self error: \'Cannot use new, use [$this newSelector]\'"
  1034. }
  1035.  
  1036.  
  1037. # Returns selector for initialize or new.
  1038. # Base it on the <firstPart> of the selector
  1039. # and the <parameterNames>.
  1040. #
  1041. method STGConstructor::getSelector {this firstPart parameterNames} {
  1042.     set first 1
  1043.     set selector $firstPart
  1044.     $parameterNames foreach parName {
  1045.     if $first {
  1046.         if { $selector == "new" } {
  1047.         set selector "$parName:"
  1048.         } else {
  1049.         set selector "$selector[cap $parName]:"
  1050.         }
  1051.         set first 0
  1052.     } else {
  1053.         set selector "$selector$parName:"
  1054.     }
  1055.     }
  1056.     return $selector
  1057. }
  1058.  
  1059.  
  1060. # Makes a message with selector and the arguments of argList.
  1061. #
  1062. method STGConstructor::getMessage {this selector argList} {
  1063.     set selectorPartList [split $selector ':']
  1064.     set message [lindex $selectorPartList 0]
  1065.     set index 0
  1066.     $argList foreach argName {
  1067.     if { $index > 0 } {
  1068.         set message "$message [lindex $selectorPartList $index]: $argName"
  1069.     } else {
  1070.         set message "$message: $argName"
  1071.     }
  1072.     set index [expr $index+1]
  1073.     }
  1074.     return $message
  1075. }
  1076.  
  1077. # Do not delete this line -- regeneration end marker
  1078.  
  1079. selfPromoter OPConstructor {this} {
  1080.     STGConstructor promote $this
  1081. }
  1082.  
  1083. #      File:           @(#)stgctorpar.tcl    /main/1
  1084.  
  1085.  
  1086. # Generator class for constructor parameters.
  1087.  
  1088. Class STGCtorParameter : {STGObject OPCtorParameter} {
  1089.     constructor
  1090.     method destructor
  1091.     method argumentName
  1092. }
  1093.  
  1094. constructor STGCtorParameter {class this name} {
  1095.     set this [STGObject::constructor $class $this $name]
  1096.     # Start constructor user section
  1097.     # End constructor user section
  1098.     return $this
  1099. }
  1100.  
  1101. method STGCtorParameter::destructor {this} {
  1102.     # Start destructor user section
  1103.     # End destructor user section
  1104. }
  1105.  
  1106.  
  1107. # Determine the name of the parameter when used as argument:
  1108. # base it on the name for an association attribute, or the type or name for another type
  1109. # of attribute.
  1110. #
  1111. method STGCtorParameter::argumentName {this} {
  1112.     set attrib [$this attrib]
  1113.     if { $attrib != "" } {        
  1114.     return [$attrib getArgumentName]
  1115.     } else {
  1116.     return [$this asArgument [$this getSTName]]
  1117.     }
  1118. }
  1119.  
  1120. # Do not delete this line -- regeneration end marker
  1121.  
  1122. selfPromoter OPCtorParameter {this} {
  1123.     STGCtorParameter promote $this
  1124. }
  1125.  
  1126. #      File:           @(#)stgoperati.tcl    /main/1
  1127.  
  1128.  
  1129. # This class is the generator for user defined operations.
  1130.  
  1131. Class STGOperation : {STGObject OPOperation} {
  1132.     constructor
  1133.     method destructor
  1134.     method generate
  1135.     method getMethodImplementation
  1136.     method generateAbstractMethod
  1137.     method generateDescription
  1138.     method doTclCall
  1139.     method getCategory
  1140.     method getSelector
  1141.     method getOperatorSelector
  1142.     method getSpecialCharacter
  1143.     attribute methodImplementation
  1144. }
  1145.  
  1146. constructor STGOperation {class this name} {
  1147.     set this [STGObject::constructor $class $this $name]
  1148.     # Start constructor user section
  1149.     # End constructor user section
  1150.     return $this
  1151. }
  1152.  
  1153. method STGOperation::destructor {this} {
  1154.     # Start destructor user section
  1155.     # End destructor user section
  1156. }
  1157.  
  1158.  
  1159. # Generates for user defined operation:
  1160. # * determines category and type (instance or class or user defined constructor).
  1161. # * determines message selector.
  1162. # * Gets a method implementation object.
  1163. # * Generates comment
  1164. # * Generates for the parameters
  1165. # * Generates for abstract methods.
  1166. # * Calls Tcl method if required.
  1167. #
  1168. method STGOperation::generate {this} {
  1169.     $this getMethodImplementation
  1170.     $this generateDescription
  1171.     
  1172.     foreach parameter [$this parameterSet] {
  1173.     $parameter generate [$this methodImplementation]
  1174.     }
  1175.     
  1176.     if [$this isAbstract] {
  1177.     $this generateAbstractMethod
  1178.     [$this methodImplementation] isUserDefined 0
  1179.     return
  1180.     }
  1181.  
  1182.     set tclGenerator [$this getPropertyValue method_impl]
  1183.     if { $tclGenerator != "" } {
  1184.     [$this methodImplementation] isUserDefined 0
  1185.     if { ![$this doTclCall $tclGenerator] } {
  1186.         [$this methodImplementation] isUserDefined 1
  1187.     }
  1188.     }
  1189.  
  1190.     $this methodImplementation ""
  1191. }
  1192.  
  1193.  
  1194. # Determines category, type and message selector and gets
  1195. # a method implementation object.
  1196. # Sets the methodImplementation association.
  1197. # If the operator name starts with operator,
  1198. # a redefined operator is assumed and translation is done.
  1199. #
  1200. method STGOperation::getMethodImplementation {this} {
  1201.     set category [$this getCategory]
  1202.     # If name starts with operator call operator naming. If this does not
  1203.     # work use normal naming
  1204.     if [string match operator* [$this getName]] {
  1205.     set selector [$this getOperatorSelector]
  1206.     if { $selector == "" } { 
  1207.         set selector [$this getSelector]
  1208.     }
  1209.     } else {
  1210.     set selector [$this getSelector]
  1211.     }
  1212.     
  1213.     # Now get the implementation object through the class implementation
  1214.     set classImpl [[$this ooplClass] classImplementation]
  1215.     if [$this isClassFeature] {
  1216.     set operation [$classImpl getClassMethodImplementation $selector $category]
  1217.     } else {
  1218.     set operation [$classImpl getInstanceMethodImplementation $selector $category]
  1219.     }
  1220.  
  1221.     # Now store implementation in this generator
  1222.     $this methodImplementation $operation
  1223.  
  1224.     [$this methodImplementation] isUserDefined 1
  1225. }
  1226.  
  1227.  
  1228. # Generates for an abstract method.
  1229. # Sets isAbstract attribute of corresponding class.
  1230. #
  1231. method STGOperation::generateAbstractMethod {this} {
  1232.     [$this methodImplementation] addExpression "self subclassResponsibility"
  1233.     [$this ooplClass] isAbstract 1
  1234. }
  1235.  
  1236.  
  1237. # Generates comment based on free text property.
  1238. #
  1239. method STGOperation::generateDescription {this} {
  1240.     if [regsub -all {"} [$this getPropertyValue freeText] "" comment] {
  1241.     puts "WARNING: Removed \" from comment of method [$this getSTName]"
  1242.     }
  1243.     [$this methodImplementation] comment $comment
  1244. }
  1245.  
  1246.  
  1247. # Calls Tcl Implementation Method if it 
  1248. # has been defined. Checks that it exists first.
  1249. #
  1250. method STGOperation::doTclCall {this generatorMethod} {
  1251.     set index [string first "::" $generatorMethod]
  1252.     if { $index > 0 } {
  1253.     set className [string range $generatorMethod 0 [expr $index-1]]
  1254.     set generatorMethod [string range $generatorMethod [expr $index+2] end]
  1255.     } else {
  1256.     set className STGCustom
  1257.     }
  1258.  
  1259.     if { [info commands $className] == "" } {
  1260.     puts "ERROR: Tcl Method defined but class $className not found for operation [$this getSTName]"
  1261.     return 0
  1262.     }
  1263.  
  1264.     if { [$className info supers] != "STGOperation" } {
  1265.     puts "ERROR: Tcl generator class $className must be derived from STGOperation"
  1266.     return 0
  1267.     }
  1268.  
  1269.     if { [lsearch [$className info methods] $generatorMethod] == -1 } {
  1270.     puts "ERROR: Tcl method $generatorMethod not found for operation [$this getSTName]"
  1271.     return 0
  1272.     }
  1273.  
  1274.     # Found : promote to custom class and execute method
  1275.     $className promote $this
  1276.     if [catch {    
  1277.     $this $generatorMethod [$this methodImplementation]
  1278.     } error] {
  1279.     puts "ERROR: when calling $generatorMethod: $error"
  1280.     return 0
  1281.     }
  1282.     return 1
  1283. }
  1284.  
  1285.  
  1286. # Returns category for this operation.
  1287. #
  1288. method STGOperation::getCategory {this} {
  1289.     # special naming for used defined constructor
  1290.     if { [$this getName] == "create" } {
  1291.     set category "instance creation"
  1292.     } else {
  1293.     set category "misc"
  1294.     }
  1295.  
  1296.     # Override default category if another one is specified
  1297.     set userCategory [$this getPropertyValue methodCategory]
  1298.     if { $userCategory != "" } {
  1299.     set category $userCategory
  1300.     }
  1301.     return $category    
  1302. }
  1303.  
  1304.  
  1305. # Returns selector for this operation.
  1306. #
  1307. method STGOperation::getSelector {this} {
  1308.     if { [$this getSTName] == "create" } {
  1309.     set selector "new"
  1310.     } else {
  1311.     set selector [$this getSTName]
  1312.     }
  1313.  
  1314.     set first 1
  1315.     foreach parameter [$this parameterSet] {
  1316.     set parName [$parameter getSTName]
  1317.     if $first {
  1318.         set first 0
  1319.         if { $selector == "new" } {
  1320.         set selector "$parName:"
  1321.         } else {
  1322.         set selector "$selector:"
  1323.         } 
  1324.     } else {
  1325.         set selector "$selector$parName:"
  1326.     }
  1327.     }
  1328.     return $selector
  1329. }
  1330.  
  1331.  
  1332. # Returns a Smalltalk compliant operator selector for this operation.
  1333. # It assumes that the name starts with 'operator'.
  1334. # Perform check on number of arguments.
  1335. #
  1336. method STGOperation::getOperatorSelector {this} {
  1337.     # Assume name starts with operator and strip it
  1338.     set operatorChars [string range [$this getName] 8 end]
  1339.  
  1340.     # Now check if it really is a special operator
  1341.     # if not return empty string
  1342.     if { $operatorChars == "" } {
  1343.     return ""
  1344.     }
  1345.  
  1346.     # - workaround
  1347.     if { $operatorChars == "-"} {
  1348.     if { [llength [$this parameterSet]] != 1 } {
  1349.         puts "ERROR: special operator operator- must have exactly one argument; special characters ignored"
  1350.         return ""
  1351.     } 
  1352.         return "operator-"
  1353.     }
  1354.  
  1355.     # If the first character is not a special character we assume that
  1356.     # this is not a special operator
  1357.     set firstSpecialCharacter [$this getSpecialCharacter operatorChars]
  1358.     if { $firstSpecialCharacter == "" } {
  1359.     return ""
  1360.     }
  1361.  
  1362.     set secondSpecialCharacter ""
  1363.     if { $operatorChars != "" } {
  1364.     set secondSpecialCharacter [$this getSpecialCharacter operatorChars]
  1365.     if { $secondSpecialCharacter == "" } {
  1366.         puts "ERROR: Invalid syntax for special operator [$this getName]; special characters ignored"
  1367.         return ""
  1368.     }
  1369.     }
  1370.  
  1371.     # More characters?? Not syntax compliant so ignore it.    
  1372.     if { $operatorChars != "" } {
  1373.     puts "ERROR: Invalid syntax for special operator [$this getName]; special characters ignored"
  1374.     return ""
  1375.     }
  1376.  
  1377.     # Now check if there is exactly one argument
  1378.     if { [llength [$this parameterSet]] != 1 } {
  1379.     puts "ERROR: special operator [$this getName] must have exactly one argument; special characters ignored"
  1380.     return ""
  1381.     } 
  1382.     return "$firstSpecialCharacter$secondSpecialCharacter"
  1383. }
  1384.  
  1385.  
  1386. # If <chars> starts with a special character, strip it from chars
  1387. # and return it.
  1388. #
  1389. method STGOperation::getSpecialCharacter {this chars} {
  1390.     upvar $chars characters 
  1391.     # Implementation comment: the - as selector name gives problems.
  1392.     # Workaround: do nothing with - here but just leave it as operator-
  1393.     # and convert in language model. Dirty, but it works
  1394.     if [string match "\[\+\\\*\~\<\>\@\%\|\&\?\!\]*" $characters] {
  1395.     set result [string index $characters 0]
  1396.     set characters [string range $characters 1 end]
  1397.     return $result
  1398.     }
  1399.     foreach name "DIV EQ COMMA" {
  1400.     if [string match $name* $characters] {
  1401.         set characters [string range $characters [string length $name] end]
  1402.         if { $name == "DIV" } {
  1403.         return "\/"
  1404.         }
  1405.         if { $name == "EQ" } {
  1406.         return "\="
  1407.         }
  1408.         return ","
  1409.     }
  1410.     }
  1411.     return ""
  1412. }
  1413.  
  1414. # Do not delete this line -- regeneration end marker
  1415.  
  1416. selfPromoter OPOperation {this} {
  1417.     STGOperation promote $this
  1418. }
  1419.  
  1420. #      File:           @(#)stgoperpar.tcl    /main/hindenburg/2
  1421.  
  1422.  
  1423. # Generator for operation parameters.
  1424.  
  1425. Class STGOperParameter : {STGObject OPOperParameter} {
  1426.     constructor
  1427.     method destructor
  1428.     method generate
  1429.     method argumentName
  1430. }
  1431.  
  1432. constructor STGOperParameter {class this name} {
  1433.     set this [STGObject::constructor $class $this $name]
  1434.     # Start constructor user section
  1435.     # End constructor user section
  1436.     return $this
  1437. }
  1438.  
  1439. method STGOperParameter::destructor {this} {
  1440.     # Start destructor user section
  1441.     # End destructor user section
  1442. }
  1443.  
  1444.  
  1445. # Generates argument name in method implementation and
  1446. # default value if required.
  1447. #
  1448. method STGOperParameter::generate {this methodImplementation} {
  1449.     set argName [$this getArgumentName]
  1450.     set argName [$methodImplementation getNewUniqueArgumentName $argName]
  1451.     set defaultValue [$this getPropertyValue default_value]
  1452.  
  1453.     # If there is a default value add a conditional assignment
  1454.     if { $defaultValue!= "" } {
  1455.     set assign [$methodImplementation addExpression "$argName isNil ifTrue:"]
  1456.     $assign addExpression "$argName := $defaultValue"
  1457.     }
  1458. }
  1459.  
  1460.  
  1461. # Determine the name of the parameter when used as argument:
  1462. # base it on the type if it exists and the name otherwise.
  1463. #
  1464. method STGOperParameter::argumentName {this} {
  1465.     set type [$this ooplType]
  1466.     if { $type != "" } {
  1467.     if { [$type getType3GL] != "" } {
  1468.         return [$this asSTName [$this asArgument [$type getType3GL]]]
  1469.     } elseif { [$type getName] != "" } {
  1470.         return [$this asSTName [$this asArgument [$type getName]]]
  1471.     }
  1472.     }
  1473.     return [$this asArgument [$this getSTName]]
  1474. }
  1475.  
  1476. # Do not delete this line -- regeneration end marker
  1477.  
  1478. selfPromoter OPOperParameter {this} {
  1479.     STGOperParameter promote $this
  1480. }
  1481.  
  1482. #      File:           @(#)stgqualifi.tcl    /main/hindenburg/2
  1483.  
  1484.  
  1485. # Qualifier generator class, only used for generating argument names.
  1486.  
  1487. Class STGQualifier : {STGObject OPQualifier} {
  1488.     constructor
  1489.     method destructor
  1490.     method argumentName
  1491. }
  1492.  
  1493. constructor STGQualifier {class this name} {
  1494.     set this [STGObject::constructor $class $this $name]
  1495.     # Start constructor user section
  1496.     # End constructor user section
  1497.     return $this
  1498. }
  1499.  
  1500. method STGQualifier::destructor {this} {
  1501.     # Start destructor user section
  1502.     # End destructor user section
  1503. }
  1504.  
  1505.  
  1506. # Returns name for this qualifier when used as an argument.
  1507. # base it on the type if it exists
  1508. # or the name otherwise.
  1509. #
  1510. method STGQualifier::argumentName {this} {
  1511.     set type [$this ooplType]
  1512.     if { $type != "" } {
  1513.     if { [$type getType3GL] != "" } {
  1514.         return [$this asSTName [$this asArgument [$type getType3GL]]]
  1515.     }  elseif { [$type getName] != "" } {
  1516.         return [$this asSTName [$this asArgument [$type getName]]]
  1517.     }
  1518.     }
  1519.     return [$this asArgument [$this getSTName]]
  1520. }
  1521.  
  1522. # Do not delete this line -- regeneration end marker
  1523.  
  1524. selfPromoter OPQualifier {this} {
  1525.     STGQualifier promote $this
  1526. }
  1527.  
  1528. #      File:           @(#)stgqualini.tcl    /main/1
  1529.  
  1530.  
  1531. # Generator for qualifier initializers. 
  1532. # Qualifier initializers are generated in qualified link
  1533. # associations.
  1534.  
  1535. Class STGQualInitializer : {STGObject OPQualInitializer} {
  1536.     constructor
  1537.     method destructor
  1538.     method generate
  1539. }
  1540.  
  1541. constructor STGQualInitializer {class this name} {
  1542.     set this [STGObject::constructor $class $this $name]
  1543.     # Start constructor user section
  1544.     # End constructor user section
  1545.     return $this
  1546. }
  1547.  
  1548. method STGQualInitializer::destructor {this} {
  1549.     # Start destructor user section
  1550.     # End destructor user section
  1551. }
  1552.  
  1553.  
  1554. # Get argument name for initializer and add it to constructor parameters.
  1555. #
  1556. method STGQualInitializer::generate {this} {
  1557.     set constructor [[$this constructor] methodImplementation]
  1558.     set argName [[$this qualifier] getArgumentName]
  1559.     $constructor getUniqueArgumentName [$this getSTName] $argName
  1560. }
  1561.  
  1562. # Do not delete this line -- regeneration end marker
  1563.  
  1564. selfPromoter OPQualInitializer {this} {
  1565.     STGQualInitializer promote $this
  1566. }
  1567.  
  1568. #      File:           @(#)stgsupercl.tcl    /main/1
  1569.  
  1570.  
  1571. # This is the generator for super class initializers.
  1572.  
  1573. Class STGSuperClassInitializer : {STGObject OPSuperClassInitializer} {
  1574.     constructor
  1575.     method destructor
  1576.     method generate
  1577. }
  1578.  
  1579. constructor STGSuperClassInitializer {class this name} {
  1580.     set this [STGObject::constructor $class $this $name]
  1581.     # Start constructor user section
  1582.     # End constructor user section
  1583.     return $this
  1584. }
  1585.  
  1586. method STGSuperClassInitializer::destructor {this} {
  1587.     # Start destructor user section
  1588.     # End destructor user section
  1589. }
  1590.  
  1591.  
  1592. # Determines parameter names for super call.
  1593. # Generates the call of the initialize method in the super class and
  1594. # inserts it as first constructor statement.
  1595. # Sets newRequired in the constructor generator:
  1596. # 0 if the class to which this initializer
  1597. # belongs has the same constructor parameters
  1598. # as the superclass, 1 otherwise.
  1599. #
  1600. method STGSuperClassInitializer::generate {this} {
  1601.     if [[$this ooplClass] isExternal] {
  1602.     return
  1603.     }
  1604.  
  1605.     set constructor [$this constructor]
  1606.     set initialize [$constructor methodImplementation]
  1607.  
  1608.     set parList [List new]
  1609.     set argList [List new]
  1610.     # get parameter and argument list for super class constructor
  1611.     foreach parameter [$this parameterSet] {
  1612.     set parName [$this asSTName [$parameter getOriginalName]]
  1613.     $parList append $parName
  1614.     set argName [$parameter getArgumentName]
  1615.     $argList append [$initialize getUniqueArgumentName $parName $argName]
  1616.     }
  1617.  
  1618.     set superNewSelector [$constructor getSelector new $parList]
  1619.     set superInitSelector [$constructor getSelector initialize $parList]
  1620.     set superInitMessage [$constructor getMessage $superInitSelector $argList]
  1621.  
  1622.     # Insert message to initialize in super as first expression
  1623.     $initialize insertExpression "super $superInitMessage"
  1624.  
  1625.     # Now compute newRequired
  1626.     # needed if difference in constructor parameters or abstract property 
  1627.     set thisAbstract [[$constructor ooplClass] isAbstract]
  1628.     set superAbstract [[$this ooplClass] isAbstract]
  1629.     if { ([$constructor newSelector] == $superNewSelector) && ($thisAbstract == $superAbstract) } {
  1630.     $constructor newRequired 0
  1631.     }
  1632. }
  1633.  
  1634. # Do not delete this line -- regeneration end marker
  1635.  
  1636. selfPromoter OPSuperClassInitializer {this} {
  1637.     STGSuperClassInitializer promote $this
  1638. }
  1639.  
  1640. #      File:           @(#)stgassocma.tcl    /main/1
  1641.  
  1642.  
  1643. # This is the generator for normal associations with multiplicity many.
  1644.  
  1645. Class STGAssocMany : {STGAssocGen} {
  1646.     constructor
  1647.     method destructor
  1648.     method generateData
  1649.     method generateSet
  1650.     method generateGet
  1651.     method generateRemove
  1652.     method generateSetRef
  1653.     method generateRemoveRef
  1654.     method generateRemoveRefMessage
  1655.     method generateSetRefMessage
  1656.     method generateRemoveMessage
  1657.     method generateSetCode
  1658.     method generateRemoveCode
  1659.     method generateInitialize
  1660.     method generateReleaseCode
  1661.     method generatePrintCode
  1662.     method removeRequired
  1663. }
  1664.  
  1665. constructor STGAssocMany {class this assocAttr} {
  1666.     set this [STGAssocGen::constructor $class $this $assocAttr]
  1667.     # Start constructor user section
  1668.     # End constructor user section
  1669.     return $this
  1670. }
  1671.  
  1672. method STGAssocMany::destructor {this} {
  1673.     # Start destructor user section
  1674.     # End destructor user section
  1675.     $this STGAssocGen::destructor
  1676. }
  1677.  
  1678.  
  1679. # Generates instance variable to implement this association
  1680. # an sets variableName. The name of the instance
  1681. # variable is <roleName>Set.
  1682. #
  1683. method STGAssocMany::generateData {this} {
  1684.     set name "[$this roleName]Set"
  1685.     [$this classImplementation] addInstanceVariable $name
  1686.     $this variableName $name
  1687. }
  1688.  
  1689.  
  1690. # Generates the set method that adds to the association.
  1691. #
  1692. method STGAssocMany::generateSet {this} {
  1693.     set selector "add[cap [$this roleName]]:"
  1694.     set set [$this getModifyImplementation $selector]
  1695.     if { $set == "" } {
  1696.     return
  1697.     }
  1698.     $this generateSetCode $set [$this opposite]
  1699. }
  1700.  
  1701.  
  1702. # Generates the get method which executes a block for all associated objects.
  1703. #
  1704. method STGAssocMany::generateGet {this} {
  1705.     set selector "[$this roleName]SetDo:"
  1706.     set get [$this getAccessImplementation $selector]
  1707.     if { $get == "" } {
  1708.     return
  1709.     }
  1710.  
  1711.     $get addArgument aBlock
  1712.     $get addExpression "[$this variableName] do: aBlock"
  1713. }
  1714.  
  1715.  
  1716. # Generate the set method remove which removes an element from the association.
  1717. #
  1718. method STGAssocMany::generateRemove {this} {
  1719.     set selector "remove[cap [$this roleName]]:"
  1720.     set remove [$this getRemoveImplementation $selector]    
  1721.     if { $remove == "" } {
  1722.     return
  1723.     }
  1724.     $this generateRemoveCode $remove [$this opposite]
  1725. }
  1726.  
  1727.  
  1728. # Generates the implementation method to add to the instance variable for the association.
  1729. #
  1730. method STGAssocMany::generateSetRef {this} {
  1731.     set selector "add[cap [$this roleName]]Ref:"
  1732.     set setRef [$this getPrivateImplementation $selector]
  1733.     $this generateSetCode $setRef ""
  1734. }
  1735.  
  1736.  
  1737. # Generates the implementation method to remove an element from the
  1738. # instance variable for the association.
  1739. #
  1740. method STGAssocMany::generateRemoveRef {this} {
  1741.     set selector "remove[cap [$this roleName]]Ref:"
  1742.     set removeRef [$this getPrivateImplementation $selector]    
  1743.     $this generateRemoveCode $removeRef ""
  1744. }
  1745.  
  1746.  
  1747. # Generates an expression in block that sends a removeRef message to
  1748. # object with parameter <parameter>.
  1749. #
  1750. method STGAssocMany::generateRemoveRefMessage {this block object parameter args} {
  1751.     set removeRefName "remove[cap [$this roleName]]Ref:"
  1752.     $block addExpression "$object $removeRefName $parameter"
  1753. }
  1754.  
  1755.  
  1756. # Generates an expression in block that sends a SetRef message to object
  1757. # with parameter <parameter>.
  1758. #
  1759. method STGAssocMany::generateSetRefMessage {this block object parameter args} {
  1760.     set setRefName "add[cap [$this roleName]]Ref:"
  1761.     $block addExpression "$object $setRefName $parameter"
  1762. }
  1763.  
  1764.  
  1765. # Does nothing: present for interface consistency.
  1766. #
  1767. method STGAssocMany::generateRemoveMessage {this block object args} {
  1768.     # Do nothing: remove must not be called for many associations
  1769. }
  1770.  
  1771.  
  1772. # Generates the expressions for a set method in block.
  1773. #
  1774. method STGAssocMany::generateSetCode {this block opposite} {
  1775.     set name [$this variableName]
  1776.     set parName [$this parameterName]
  1777.     set selector [$block selector]
  1778.  
  1779.     $block addArgument $parName
  1780.  
  1781.     set upper [$this upperConstraint]
  1782.     if { $upper != "" } {
  1783.     set block [$this generateConstraintCheck $selector $block $name $upper upper]
  1784.     }
  1785.  
  1786.     if { $opposite != "" } {
  1787.     $opposite generateRemoveMessage $block $parName
  1788.     $opposite generateSetRefMessage $block $parName self
  1789.     }
  1790.  
  1791.     # add to Set. If it is an orderedCollection check for no duplicates
  1792.     if { [$this setType] == "OrderedCollection" } {
  1793.     set block [$this generateIncludesCheck $block $name $parName]
  1794.     }
  1795.     $block addExpression "$name add: $parName"
  1796. }
  1797.  
  1798.  
  1799. # Generates the expressions for the remove method in block.
  1800. #
  1801. method STGAssocMany::generateRemoveCode {this block opposite} {
  1802.     set name [$this variableName]
  1803.     set parName [$this parameterName]    
  1804.     set selector [$block selector]
  1805.     $block addArgument $parName
  1806.  
  1807.     # existence check must be done separately with includes:
  1808.     set lower [$this lowerConstraint]
  1809.     if { $lower != "" } {
  1810.     $this generateExistenceCheck $selector $block $name $parName
  1811.     set block [$this generateConstraintCheck $selector $block $name $lower lower]
  1812.     }
  1813.  
  1814.     if { $opposite != "" } {
  1815.     $opposite generateRemoveRefMessage $block $parName self
  1816.     }
  1817.  
  1818.     # Remove it. Different for constraint and no constraint:
  1819.     # in the constraint ifAbsent: is not needed because an includes:
  1820.     # test was already generated
  1821.     set removeText "$name remove: $parName"
  1822.     if { $lower == "" } {
  1823.     set  removeExpr [$block addExpression "$removeText ifAbsent:"]
  1824.     $removeExpr addExpression [$this getErrorMessage ASSOC_OBJ_NOT_FOUND $selector]
  1825.     } else { 
  1826.     $block addExpression $removeText
  1827.     }
  1828. }
  1829.  
  1830.  
  1831. # Generates additions to initialize method, if it exists.
  1832. #
  1833. method STGAssocMany::generateInitialize {this} {
  1834.     set initialize [[$this classImplementation] initialize]
  1835.     if { $initialize == "" } {
  1836.     return
  1837.     }
  1838.  
  1839.     $initialize addExpression "[$this variableName] := [$this setType] new"
  1840.     if { [$this lowerConstraint] != "" } {
  1841.     set comment "Warning: put association [$this roleName] in consistent state"
  1842.     $initialize addCommentLine $comment
  1843.     }
  1844. }
  1845.  
  1846.  
  1847. # Generates expressions for addition to release in block.
  1848. #
  1849. method STGAssocMany::generateReleaseCode {this block} {
  1850.     set name [$this variableName]
  1851.     set parName [$this parameterName]
  1852.     if { [$this opposite] != "" } {
  1853.     set setBlock [$block addExpression "$name do:"]
  1854.     $setBlock addArgument $parName
  1855.     [$this opposite] generateRemoveRefMessage $setBlock $parName self
  1856.     }
  1857.     $block addExpression "$name := nil"
  1858. }
  1859.  
  1860.  
  1861. # Generates expressions in block to print information about the association.
  1862. #
  1863. method STGAssocMany::generatePrintCode {this block} {
  1864.     set name [$this variableName]
  1865.     $block addExpression "aStream cr; nextPutAll: \'$name:\' displayString"
  1866.     set printAll [$block addExpression "$name inject: 1 into:"]
  1867.     $printAll addArgument "count"
  1868.     $printAll addArgument "element"
  1869.     $printAll addExpression "aStream cr; tab; nextPutAll: count printString"
  1870.     $printAll addExpression "element printVars: aStream withIndent: 2"
  1871.     $printAll addExpression "count + 1"
  1872. }
  1873.  
  1874.  
  1875. # Returns 0.
  1876. #
  1877. method STGAssocMany::removeRequired {this} {
  1878.     return 0
  1879. }
  1880.  
  1881. # Do not delete this line -- regeneration end marker
  1882.  
  1883.  
  1884. #      File:           @(#)stgassocon.tcl    /main/1
  1885.  
  1886.  
  1887. # This is the generator for normal associations with multiplicity one.
  1888.  
  1889. Class STGAssocOne : {STGAssocGen} {
  1890.     constructor
  1891.     method destructor
  1892.     method generateData
  1893.     method generateSet
  1894.     method generateGet
  1895.     method generateRemove
  1896.     method generateSetRef
  1897.     method generateRemoveRef
  1898.     method generateRemoveRefMessage
  1899.     method generateSetRefMessage
  1900.     method generateRemoveMessage
  1901.     method generateSetCode
  1902.     method generateRemoveCode
  1903.     method generateInitialize
  1904.     method generateInitializeCode
  1905.     method generateReleaseCode
  1906.     method generatePrintCode
  1907.     method removePermitted
  1908. }
  1909.  
  1910. constructor STGAssocOne {class this assocAttr} {
  1911.     set this [STGAssocGen::constructor $class $this $assocAttr]
  1912.     # Start constructor user section
  1913.     # End constructor user section
  1914.     return $this
  1915. }
  1916.  
  1917. method STGAssocOne::destructor {this} {
  1918.     # Start destructor user section
  1919.     # End destructor user section
  1920.     $this STGAssocGen::destructor
  1921. }
  1922.  
  1923.  
  1924. # Generates instance variable to implement this association 
  1925. # and sets variableName. The name of the instance
  1926. # variable is the roleName.
  1927. #
  1928. method STGAssocOne::generateData {this} {
  1929.     [$this classImplementation] addInstanceVariable [$this roleName]
  1930.     $this variableName [$this roleName]
  1931. }
  1932.  
  1933.  
  1934. # Generates the set method to set the association.
  1935. #
  1936. method STGAssocOne::generateSet {this} {
  1937.     set selector "set[cap [$this roleName]]:"
  1938.     set set [$this getModifyImplementation $selector]
  1939.     if { $set != "" } {
  1940.         $this generateSetCode $set [$this opposite]
  1941.     }
  1942. }
  1943.  
  1944.  
  1945. # Generates the get method which returns the associated object.
  1946. #
  1947. method STGAssocOne::generateGet {this} {
  1948.     set selector "get[cap [$this roleName]]"
  1949.     set get [$this getAccessImplementation $selector]
  1950.     if { $get != "" } {
  1951.         $get addExpression "\^[$this variableName]"
  1952.     }
  1953. }
  1954.  
  1955.  
  1956. # Generates the remove method to remove the association.
  1957. #
  1958. method STGAssocOne::generateRemove {this} {
  1959.     set selector "remove[cap [$this roleName]]"
  1960.     set remove [$this getRemoveImplementation $selector]
  1961.     if  { $remove != "" } {
  1962.         $this generateRemoveCode $remove [$this opposite]
  1963.     }
  1964. }
  1965.  
  1966.  
  1967. # Generates the implementation method to set the instance variable for the association.
  1968. #
  1969. method STGAssocOne::generateSetRef {this} {
  1970.     set selector "set[cap [$this roleName]]Ref:"
  1971.     set setRef [$this getPrivateImplementation $selector]
  1972.     $this generateSetCode $setRef ""
  1973. }
  1974.  
  1975.  
  1976. # Does nothing: this method is here to keep the interfaces of the association generators consistent.
  1977. #
  1978. method STGAssocOne::generateRemoveRef {this} {
  1979.     # Not needed for one association: bye
  1980. }
  1981.  
  1982.  
  1983. # Generates an expression in block that sends a SetRef message to object with parameter nil.
  1984. #
  1985. method STGAssocOne::generateRemoveRefMessage {this block object parameter args} {
  1986.     $this generateSetRefMessage $block $object nil
  1987. }
  1988.  
  1989.  
  1990. # Generates an expression in block that sends a SetRef message to object with argument parameter.
  1991. #
  1992. method STGAssocOne::generateSetRefMessage {this block object parameter args} {
  1993.     set setRefName "set[cap [$this roleName]]Ref:"
  1994.     $block addExpression "$object $setRefName $parameter"
  1995. }
  1996.  
  1997.  
  1998. # Generates an expression in block that sends a remove message to object.
  1999. #
  2000. method STGAssocOne::generateRemoveMessage {this block object args} {
  2001.     set removeName "remove[cap [$this roleName]]"
  2002.     $block addExpression "$object $removeName"
  2003. }
  2004.  
  2005.  
  2006. # Generates the expressions for a set method in block.
  2007. #
  2008. method STGAssocOne::generateSetCode {this block opposite} {
  2009.     set name [$this variableName]
  2010.     set parName [$this parameterName]
  2011.     $block addArgument $parName
  2012.  
  2013.     # if it is mandatory generate a nil check and an inequality check    
  2014.     if [[$this assocAttr] isMandatory] {
  2015.     $this generateNilCheck $block $parName
  2016.     }
  2017.  
  2018.     if { $opposite != "" } {
  2019.     if [[$this assocAttr] isMandatory] {
  2020.         set compare "$name ~~ $parName"
  2021.         set block [$block addExpression "($compare) ifTrue:"]
  2022.     }
  2023.     # remove old links
  2024.     $opposite generateRemoveMessage $block $parName
  2025.     set removeBlock $block
  2026.     if { ![[$this assocAttr] isMandatory]} {
  2027.         set removeBlock [$block addExpression "$name isNil ifFalse:"]
  2028.     }
  2029.     $opposite generateRemoveRefMessage $removeBlock $name self
  2030.     # set new link
  2031.     $opposite generateSetRefMessage $block $parName self
  2032.     }
  2033.  
  2034.     $block addExpression "$name := $parName"    
  2035. }
  2036.  
  2037.  
  2038. # Generates the expressions for the remove method in block.
  2039. #
  2040. method STGAssocOne::generateRemoveCode {this block opposite args} {
  2041.     set name [$this variableName]
  2042.     # if the association is not mandatory the instance var may be nil
  2043.     # generate remove for opposite if it exists
  2044.  
  2045.     if { $opposite != "" } {
  2046.     if { ![[$this assocAttr] isMandatory] } {
  2047.         set nilCheck "$name isNil ifFalse:"
  2048.         set block [$block addExpression $nilCheck]
  2049.     }
  2050.     $opposite generateRemoveRefMessage $block $name self $args
  2051.     }
  2052.  
  2053.     $block addExpression "$name := nil"
  2054. }
  2055.  
  2056.  
  2057. # Generates addition to initialize method (if it exists).
  2058. #
  2059. method STGAssocOne::generateInitialize {this} {
  2060.     set initialize [[$this classImplementation] initialize]
  2061.  
  2062.     # If there is no initialize method nothing can be generated
  2063.     if { $initialize == "" } { 
  2064.     return 
  2065.     }
  2066.    
  2067.     $this generateInitializeCode $initialize 
  2068. }
  2069.  
  2070.  
  2071. # Generates the expressions for the addition to initialize in block.
  2072. #
  2073. method STGAssocOne::generateInitializeCode {this block args} {
  2074.     set name [$this variableName]
  2075.     set parName [$this parameterName]
  2076.  
  2077.     if { [[$this assocAttr] hasInitializer] == 1 } {
  2078.     set parName [$block getUniqueArgumentName [$this roleName] $parName]    
  2079.     $this generateNilCheck $block $parName
  2080.     if { [$this opposite] != "" } {
  2081.         [$this opposite] generateRemoveMessage $block $parName $args
  2082.         [$this opposite] generateSetRefMessage $block $parName self $args
  2083.     }
  2084.     $block addExpression "$name := $parName"
  2085.     } else {
  2086.     $block addExpression "$name := nil"
  2087.     }    
  2088. }
  2089.  
  2090.  
  2091. # Generates additions to release in block.
  2092. #
  2093. method STGAssocOne::generateReleaseCode {this block} {
  2094.     $this generateRemoveCode $block [$this opposite]
  2095. }
  2096.  
  2097.  
  2098. # Generates expressions in block to print information about the association.
  2099. #
  2100. method STGAssocOne::generatePrintCode {this block} {
  2101.     set name [$this variableName]
  2102.     $block addExpression "aStream cr; nextPutAll: \'$name: \' displayString"
  2103.     set printOther [$block addExpression "$name isNil ifFalse:"]
  2104.     $printOther addExpression "$name printVars: aStream withIndent: 1"
  2105. }
  2106.  
  2107.  
  2108. # Returns 0 if this association is mandatory, else defaults to RemovePermitted
  2109. # in STGAssocGen.
  2110. #
  2111. method STGAssocOne::removePermitted {this} {
  2112.     if [[$this assocAttr] isMandatory] {
  2113.     return 0
  2114.     }
  2115.     return [$this STGAssocGen::removePermitted] 
  2116. }
  2117.  
  2118. # Do not delete this line -- regeneration end marker
  2119.  
  2120.  
  2121. #      File:           @(#)stgmanyqua.tcl    /main/1
  2122.  
  2123.  
  2124. # This is the generator for qualified associations with multiplicity many.
  2125.  
  2126. Class STGManyQual : {STGAssocGen} {
  2127.     constructor
  2128.     method destructor
  2129.     method generateData
  2130.     method generateSet
  2131.     method generateGet
  2132.     method generateRemove
  2133.     method generateSetRef
  2134.     method generateRemoveRef
  2135.     method generateRemoveRefMessage
  2136.     method generateSetRefMessage
  2137.     method generateRemoveMessage
  2138.     method generateSetCode
  2139.     method generateRemoveCode
  2140.     method generateInitialize
  2141.     method generateReleaseCode
  2142.     method generatePrintCode
  2143.     method removeRequired
  2144. }
  2145.  
  2146. constructor STGManyQual {class this assocAttr} {
  2147.     set this [STGAssocGen::constructor $class $this $assocAttr]
  2148.     # Start constructor user section
  2149.     # End constructor user section
  2150.     return $this
  2151. }
  2152.  
  2153. method STGManyQual::destructor {this} {
  2154.     # Start destructor user section
  2155.     # End destructor user section
  2156.     $this STGAssocGen::destructor
  2157. }
  2158.  
  2159.  
  2160. # Generates instance variable to implement this association and sets
  2161. # variableName to <roleName>SetDict.
  2162. #
  2163. method STGManyQual::generateData {this} {
  2164.     set name "[$this roleName]SetDict"
  2165.     [$this classImplementation] addInstanceVariable $name
  2166.     $this variableName $name
  2167. }
  2168.  
  2169.  
  2170. # Generates the set method to set the association for a given qualifier.
  2171. #
  2172. method STGManyQual::generateSet {this} {
  2173.     set selector "add[cap [$this roleName]]:at:"
  2174.     set set [$this getModifyImplementation $selector]
  2175.     if { $set == "" } {
  2176.     return
  2177.     }
  2178.     $this generateSetCode $set [$this opposite]
  2179. }
  2180.  
  2181.  
  2182. # Generates the get methods:
  2183. # * One that executes a given block for each object associated for a given qualifier.
  2184. # * One that executes a given block for each qualifier.
  2185. #
  2186. method STGManyQual::generateGet {this} {
  2187.     set selector "[$this roleName]SetDo:at:"
  2188.     set name [$this variableName]
  2189.     set qualPar [$this qualifierParameter]
  2190.     set get [$this getAccessImplementation $selector]
  2191.     if { $get == "" } {
  2192.     return
  2193.     }
  2194.  
  2195.     $get getNewUniqueArgumentName aBlock
  2196.     $get getNewUniqueArgumentName $qualPar
  2197.     set setName "[$this roleName]s"
  2198.     $get addTemporary $setName
  2199.     set getSet [$get addExpression "$setName := $name at: $qualPar ifAbsent:"]
  2200.     $getSet addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  2201.     $get addExpression "$setName do: aBlock"
  2202.  
  2203.     set selector "[$this qualifierName]SetDo:"
  2204.     set getAll [$this getAccessImplementation $selector]
  2205.     $getAll addArgument aBlock
  2206.     $getAll addExpression "$name keysDo: aBlock"
  2207. }
  2208.  
  2209.  
  2210. # Generates the set method that removes an object from the association for a given qualifier.
  2211. #
  2212. method STGManyQual::generateRemove {this} {
  2213.     set selector "remove[cap [$this roleName]]:at:"
  2214.     set remove [$this getRemoveImplementation $selector]
  2215.     if { $remove != "" } {
  2216.         $this generateRemoveCode $remove [$this opposite]
  2217.     }
  2218. }
  2219.  
  2220.  
  2221. # Generates the implementation method to add to the instance variable for the association.
  2222. #
  2223. method STGManyQual::generateSetRef {this} {
  2224.     set selector "add[cap [$this roleName]]Ref:at:"
  2225.     set setRef [$this getPrivateImplementation $selector]
  2226.     $this generateSetCode $setRef ""
  2227. }
  2228.  
  2229.  
  2230. # Generates the implementation method to remove from the instance variable for the association.
  2231. #
  2232. method STGManyQual::generateRemoveRef {this} {
  2233.     set selector "remove[cap [$this roleName]]Ref:at:"
  2234.     set removeRef [$this getPrivateImplementation $selector]
  2235.     $this generateRemoveCode $removeRef ""
  2236. }
  2237.  
  2238.  
  2239. # Generates an expression in block that sends a message to object with
  2240. # parameters <parameter> and <qualifier>.
  2241. #
  2242. method STGManyQual::generateRemoveRefMessage {this block object parameter qualifier} {
  2243.     set removeRefName "remove[cap [$this roleName]]Ref:"
  2244.     $block addExpression "$object $removeRefName $parameter at: $qualifier"
  2245. }
  2246.  
  2247.  
  2248. # Generates an expression in block that sends a setRef message to object
  2249. # with parameters <parameter> and <qualifier>.
  2250. #
  2251. method STGManyQual::generateSetRefMessage {this block object parameter qualifier} {
  2252.     set setRefName "add[cap [$this roleName]]Ref:"
  2253.     $block addExpression "$object $setRefName $parameter at: $qualifier"
  2254. }
  2255.  
  2256.  
  2257. # Does nothing.
  2258. #
  2259. method STGManyQual::generateRemoveMessage {this block object qualifier} {
  2260.     # Do nothing for many associations
  2261. }
  2262.  
  2263.  
  2264. # Generates the expressions for the set method to add to the association
  2265. # in block.
  2266. #
  2267. method STGManyQual::generateSetCode {this block opposite} {
  2268.     set name [$this variableName]
  2269.     set parName [$this parameterName]    
  2270.     set qualName [$this qualifierName]    
  2271.     set qualPar [$this qualifierParameter]
  2272.     set selector [$block selector]
  2273.     $block addArgument $parName
  2274.     $block addArgument $qualPar
  2275.     set setName "[$this roleName]s"
  2276.     $block addTemporary $setName
  2277.     
  2278.     # do size check for constraint
  2279.     set upper [$this upperConstraint]
  2280.     if { $upper != "" } {
  2281.     set block [$this generateConstraintCheck $selector $block $name $upper upper]
  2282.     }
  2283.  
  2284.     if { $opposite != "" } {
  2285.     $opposite generateRemoveMessage $block $parName $qualPar
  2286.     $opposite generateSetRefMessage $block $parName self $qualPar
  2287.     }
  2288.  
  2289.     # Generate to get old set or make a new one
  2290.     set newSet [$block addExpression "$setName := $name at: $qualPar ifAbsent:"]
  2291.     $newSet addExpression "$setName := [$this setType] new"
  2292.     $newSet addExpression "$name at: $qualPar put: $setName"
  2293.  
  2294.     if { [$this setType] == "OrderedCollection"} {
  2295.     set block [$this generateIncludesCheck $block $setName $parName]
  2296.     }
  2297.  
  2298.     $block addExpression "$setName add: $parName"
  2299. }
  2300.  
  2301.  
  2302. # Generates the expressions to remove from the association in block.
  2303. #
  2304. method STGManyQual::generateRemoveCode {this block opposite} {
  2305.     set name [$this variableName]
  2306.     set parName [$this parameterName]
  2307.     set qualPar [$this qualifierParameter]
  2308.     set selector [$block selector]
  2309.     $block addArgument $parName
  2310.     $block addArgument $qualPar
  2311.  
  2312.     # get set from dictionary 
  2313.     set setName "[$this roleName]s"
  2314.     $block addTemporary $setName
  2315.     set getSet [$block addExpression "$setName := $name at: $qualPar ifAbsent:"]
  2316.     $getSet addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  2317.  
  2318.     # check for constraint
  2319.     set lower [$this lowerConstraint]
  2320.     if { $lower != "" } {
  2321.     $this generateExistenceCheck $selector $block $setName $parName
  2322.     set block [$this generateConstraintCheck $selector $block $setName $lower lower] 
  2323.     # generate remove without ifAbsent:
  2324.     $block addExpression "$setName remove: $parName"
  2325.     } else {
  2326.     # generate remove with existence check
  2327.     set remExp [$block addExpression "$setName remove: $parName ifAbsent:"]
  2328.     $remExp addExpression [$this getErrorMessage ASSOC_OBJ_NOT_FOUND $selector]
  2329.     }
  2330.  
  2331.     if { $opposite != "" } {
  2332.     $opposite generateRemoveRefMessage $block $parName self $qualPar
  2333.     }
  2334.  
  2335.     # generate to remove key from dictionary if set gets empty
  2336.     if { $lower != "0" } {
  2337.     set emptyExpr [$block addExpression "$setName isEmpty ifTrue:"]
  2338.     $emptyExpr addExpression "$name removeKey: $qualPar"
  2339.     }
  2340. }
  2341.  
  2342.  
  2343. # Generates the additions to initialize, if it exists.
  2344. #
  2345. method STGManyQual::generateInitialize {this} {
  2346.     set initialize [[$this classImplementation] initialize]
  2347.     if { $initialize != "" } {
  2348.         $initialize addExpression "[$this variableName] := Dictionary new"
  2349.     }
  2350.     if { [$this lowerConstraint] != "" } {
  2351.     set comment "Warning: put association [$this roleName] in consistent state"
  2352.     $initialize addCommentLine $comment
  2353.     }
  2354. }
  2355.  
  2356.  
  2357. # Generates the additions to release in block.
  2358. #
  2359. method STGManyQual::generateReleaseCode {this block} {
  2360.     set name [$this variableName]
  2361.     set qualPar [$this qualifierParameter]
  2362.     set parName [$this parameterName]
  2363.     if { [$this opposite] != "" } {
  2364.     set dictBlock [$block addExpression "$name keysDo:"]
  2365.     $dictBlock addArgument $qualPar
  2366.     set setBlock [$dictBlock addExpression "($name at: $qualPar) do:"]
  2367.     $setBlock addArgument $parName
  2368.     [$this opposite] generateRemoveRefMessage $setBlock $parName self $qualPar
  2369.     }
  2370.  
  2371.     $block addExpression "$name := nil" 
  2372. }
  2373.  
  2374.  
  2375. # Generates expressions in block to print information about the association.
  2376. #
  2377. method STGManyQual::generatePrintCode {this block} {
  2378.     set name [$this variableName]
  2379.     $block addExpression "aStream cr; nextPutAll: \'$name:\' displayString"
  2380.     set printKeys [$block addExpression "$name keysDo:"]
  2381.     $printKeys addArgument "key"
  2382.     $printKeys addExpression "aStream cr; tab"
  2383.     $printKeys addExpression "key printOn: aStream"
  2384.     set printAll [$printKeys addExpression "($name at: key) inject: 1 into:"]
  2385.     $printAll addArgument "count"
  2386.     $printAll addArgument "element"
  2387.     $printAll addExpression "aStream cr; tab: 2; nextPutAll: count printString"
  2388.     $printAll addExpression "element printVars: aStream withIndent: 3"
  2389.     $printAll addExpression "count + 1"
  2390. }
  2391.  
  2392.  
  2393. # Returns 0.
  2394. #
  2395. method STGManyQual::removeRequired {this} {
  2396.     return 0
  2397. }
  2398.  
  2399. # Do not delete this line -- regeneration end marker
  2400.  
  2401.  
  2402. #      File:           @(#)stgonequal.tcl    /main/1
  2403.  
  2404.  
  2405. # This is the generator for qualified associations with multiplicity one.
  2406.  
  2407. Class STGOneQual : {STGAssocGen} {
  2408.     constructor
  2409.     method destructor
  2410.     method generateData
  2411.     method generateGet
  2412.     method generateSet
  2413.     method generateRemove
  2414.     method generateSetRef
  2415.     method generateRemoveRef
  2416.     method generateRemoveRefMessage
  2417.     method generateSetRefMessage
  2418.     method generateRemoveMessage
  2419.     method generateSetCode
  2420.     method generateRemoveCode
  2421.     method generateInitialize
  2422.     method generateReleaseCode
  2423.     method generatePrintCode
  2424.     method getQualifierSetRequired
  2425. }
  2426.  
  2427. constructor STGOneQual {class this assocAttr} {
  2428.     set this [STGAssocGen::constructor $class $this $assocAttr]
  2429.     # Start constructor user section
  2430.     # End constructor user section
  2431.     return $this
  2432. }
  2433.  
  2434. method STGOneQual::destructor {this} {
  2435.     # Start destructor user section
  2436.     # End destructor user section
  2437.     $this STGAssocGen::destructor
  2438. }
  2439.  
  2440.  
  2441. # Generates instance variable to implement the association and sets variableName
  2442. # to <roleName>Dict.
  2443. #
  2444. method STGOneQual::generateData {this} {
  2445.     set name "[$this roleName]Dict"
  2446.     [$this classImplementation] addInstanceVariable $name
  2447.     $this variableName $name
  2448. }
  2449.  
  2450.  
  2451. # Generates the get methods:
  2452. # * One to get the associated object for a given qualifier.
  2453. # * One to execute a given block for all qualifiers.
  2454. #
  2455. method STGOneQual::generateGet {this} {
  2456.     set selector "get[cap [$this roleName]]At:"
  2457.     set name [$this variableName]
  2458.     set qualPar [$this qualifierParameter]
  2459.     set get [$this getAccessImplementation $selector]
  2460.     if { $get != "" } {
  2461.     $get addArgument $qualPar
  2462.     set expr [$get addExpression "^$name at: $qualPar ifAbsent:"]
  2463.     $expr addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  2464.     }
  2465.  
  2466.     # Method to get all qualifiers
  2467.     set selector "[$this qualifierName]SetDo:"
  2468.     set getAll [$this getAccessImplementation $selector]
  2469.     if { $getAll == "" } {
  2470.     if [$this getQualifierSetRequired] {
  2471.         set getAll [$this getPrivateImplementation $selector]
  2472.     } else {
  2473.         return
  2474.     }        
  2475.     }
  2476.     $getAll addArgument aBlock
  2477.     $getAll addExpression "$name keysDo: aBlock"   
  2478. }
  2479.  
  2480.  
  2481. # Generates the set method to set the association for a given qualifier.
  2482. #
  2483. method STGOneQual::generateSet {this} {
  2484.     set selector "set[cap [$this roleName]]:at:"
  2485.     set set [$this getModifyImplementation $selector]
  2486.     if { $set != "" } {
  2487.     $this generateSetCode $set [$this opposite]
  2488.     }
  2489. }
  2490.  
  2491.  
  2492. # Generates the remove method to remove the association for a given qualifier.
  2493. #
  2494. method STGOneQual::generateRemove {this} {
  2495.     set selector "remove[cap [$this roleName]]At:"
  2496.     set remove [$this getRemoveImplementation $selector]
  2497.     if { $remove != "" } {
  2498.     $this generateRemoveCode $remove [$this opposite]
  2499.     }
  2500. }
  2501.  
  2502.  
  2503. # Generates the implementation method to set the instance variable for the association.
  2504. #
  2505. method STGOneQual::generateSetRef {this} {
  2506.     set selector "set[cap [$this roleName]]Ref:at:"
  2507.     set setRef [$this getPrivateImplementation $selector]
  2508.     $this generateSetCode $setRef ""
  2509. }
  2510.  
  2511.  
  2512. # Generates the implementation method to remove from the association.
  2513. #
  2514. method STGOneQual::generateRemoveRef {this} {
  2515.     set selector "remove[cap [$this roleName]]RefAt:"
  2516.     set removeRef [$this getPrivateImplementation $selector]
  2517.     $this generateRemoveCode $removeRef ""
  2518. }
  2519.  
  2520.  
  2521. # Generates an expression in block that sends a removeRef message to
  2522. # object with parameters <parameter> and <qualifier>.
  2523. #
  2524. method STGOneQual::generateRemoveRefMessage {this block object parameter qualifier} {
  2525.     set removeRefName "remove[cap [$this roleName]]RefAt:"
  2526.     $block addExpression "$object $removeRefName $qualifier"
  2527. }
  2528.  
  2529.  
  2530. # Generates an expression in block that sends a SetRef message to 
  2531. # object with parameters <qualifier> and <parameter>.
  2532. #
  2533. method STGOneQual::generateSetRefMessage {this block object parameter qualifier} {
  2534.     set setRefName "set[cap [$this roleName]]Ref:"
  2535.     $block addExpression "$object $setRefName $parameter at: $qualifier"
  2536. }
  2537.  
  2538.  
  2539. # Generates an expression in block that sends a remove message to object
  2540. # if there is an association with qualifier <qualifier>.
  2541. #
  2542. method STGOneQual::generateRemoveMessage {this block object qualifier} {
  2543.     set getAllName "[$this qualifierName]SetDo:"
  2544.     set block [$block addExpression "$object $getAllName"]
  2545.  
  2546.     # make name for block argument
  2547.     set blockArgument "some[cap [$this qualifierName]]"
  2548.     $block addArgument $blockArgument
  2549.  
  2550.     set block [$block addExpression "$blockArgument = $qualifier ifTrue:"]
  2551.     set removeName "remove[cap [$this roleName]]At:"
  2552.     $block addExpression "$object $removeName $qualifier" 
  2553. }
  2554.  
  2555.  
  2556. # Generates the expressions in block for the set method.
  2557. #
  2558. method STGOneQual::generateSetCode {this block opposite} {
  2559.     set name [$this variableName]
  2560.     set parName [$block getNewUniqueArgumentName [$this parameterName]]
  2561.     set qualPar [$block getNewUniqueArgumentName [$this qualifierParameter]]
  2562.  
  2563.     if [[$this assocAttr] isMandatory] {
  2564.     $this generateNilCheck $block $parName
  2565.     }
  2566.  
  2567.     if { $opposite != "" } {    
  2568.     # remove old links
  2569.     $opposite generateRemoveMessage $block $parName $qualPar
  2570.  
  2571.     # Temporary variable for old value in dictionary
  2572.     set oldName "old[cap [$this roleName]]"
  2573.     $block addTemporary $oldName
  2574.     $block addExpression "$oldName := $name at: $qualPar ifAbsent: \[nil\]"
  2575.     set subExpr [$block addExpression "$oldName isNil ifFalse:"]
  2576.     $opposite generateRemoveRefMessage $subExpr $oldName self $qualPar
  2577.     # set new one
  2578.     $opposite generateSetRefMessage $block $parName self $qualPar
  2579.     }
  2580.  
  2581.     $block addExpression "$name at: $qualPar put: $parName"
  2582. }
  2583.  
  2584.  
  2585. # Generates the expressions for the remove method in block.
  2586. #
  2587. method STGOneQual::generateRemoveCode {this block opposite} {
  2588.     set qualPar [$this qualifierParameter]
  2589.     set selector [$block selector]
  2590.     $block addArgument $qualPar
  2591.  
  2592.     set removeText "[$this variableName] removeKey: $qualPar ifAbsent:"
  2593.     if { $opposite != "" } {
  2594.     # generate temporary to hold old value
  2595.     set oldName "old[cap [$this roleName]]"
  2596.     $block addTemporary $oldName
  2597.     set removeText "$oldName := $removeText"
  2598.     $opposite generateRemoveRefMessage $block $oldName self $qualPar
  2599.     }
  2600.  
  2601.     set expr [$block insertExpression $removeText]
  2602.     $expr addExpression [$this getErrorMessage QUAL_NOT_FOUND $selector]
  2603. }
  2604.  
  2605.  
  2606. # Generates the additions to initialize, if it exists.
  2607. #
  2608. method STGOneQual::generateInitialize {this} {
  2609.     set initialize [[$this classImplementation] initialize]
  2610.     if { $initialize != "" } {
  2611.         $initialize addExpression "[$this variableName] := Dictionary new"
  2612.     }
  2613. }
  2614.  
  2615.  
  2616. # Generates the additions to release in block.
  2617. #
  2618. method STGOneQual::generateReleaseCode {this block} {
  2619.     set name [$this variableName]
  2620.     set qualPar [$this qualifierParameter]
  2621.     if { [$this opposite] != "" } {
  2622.     set dictBlock [$block addExpression "$name keysDo:"]
  2623.     $dictBlock addArgument $qualPar
  2624.     [$this opposite] generateRemoveRefMessage $dictBlock "($name at: $qualPar)" self $qualPar
  2625.     }
  2626.  
  2627.     $block addExpression "$name := nil"
  2628. }
  2629.  
  2630.  
  2631. # Generates methods to print information about the association in block.
  2632. #
  2633. method STGOneQual::generatePrintCode {this block} {
  2634.     set name [$this variableName]
  2635.     $block addExpression "aStream cr; nextPutAll: \'$name:\' displayString"
  2636.     set printKeys [$block addExpression "$name keysDo:"]
  2637.     $printKeys addArgument "key"
  2638.     $printKeys addExpression "aStream cr; tab"
  2639.     $printKeys addExpression "key printOn: aStream"
  2640.     set printOther [$printKeys addExpression "($name at: key) isNil ifFalse:"]
  2641.     $printOther addExpression "($name at: key)  printVars: aStream withIndent: 2"
  2642. }
  2643.  
  2644.  
  2645. # Returns whether the method to get all qualifiers is needed by other methods.
  2646. #
  2647. method STGOneQual::getQualifierSetRequired {this} {
  2648.     set oppAttr [[$this assocAttr] opposite]
  2649.     if { $oppAttr == "" } {
  2650.     return 0
  2651.     }
  2652.  
  2653.     if { [$oppAttr isMandatory] || ([$oppAttr writeAccess] != "None") } {
  2654.     return 1
  2655.     }
  2656.  
  2657.     return 0 
  2658. }
  2659.  
  2660. # Do not delete this line -- regeneration end marker
  2661.  
  2662.  
  2663. #      File:           @(#)stgdataatt.tcl    /main/hindenburg/2
  2664.  
  2665.  
  2666. # This class is the data attribute generator.
  2667.  
  2668. Class STGDataAttr : {STGAttribute OPDataAttr} {
  2669.     constructor
  2670.     method destructor
  2671.     method generate
  2672.     method generateDefinition
  2673.     method generateDescription
  2674.     method generateInitialValue
  2675.     method generateGetSet
  2676.     method generatePrint
  2677.     method argumentName
  2678.  
  2679.     # Used to store name, set in generateDefinition.
  2680.     # (This name may be different from STName due to 
  2681.     # capitalization of first characters).
  2682.     #
  2683.     attribute name
  2684. }
  2685.  
  2686. constructor STGDataAttr {class this name} {
  2687.     set this [STGAttribute::constructor $class $this $name]
  2688.     # Start constructor user section
  2689.     # End constructor user section
  2690.     return $this
  2691. }
  2692.  
  2693. method STGDataAttr::destructor {this} {
  2694.     # Start destructor user section
  2695.     # End destructor user section
  2696. }
  2697.  
  2698.  
  2699. # Generate for data attributes:
  2700. # generate definition and description in
  2701. # classImplementation, generate an initial value in
  2702. # the initialize method if needed,
  2703. # generate Get and Set methods and
  2704. # generate print methods if generatePrint in globals
  2705. # is set.
  2706. #
  2707. method STGDataAttr::generate {this} {
  2708.     # Call the methods
  2709.     $this generateDefinition
  2710.     $this generateDescription
  2711.     $this generateInitialValue
  2712.  
  2713.     # Only generate get and set for class and instance vars
  2714.     if { [$this getPropertyValue isPoolDict] != "1" } {
  2715.     $this generateGetSet
  2716.     }
  2717.  
  2718.     if [$globals generatePrint] {
  2719.     $this generatePrint
  2720.     }
  2721. }
  2722.  
  2723.  
  2724. # Generates the name of the attribute in the class implementation object.
  2725. # Sets the name attribute; capitalizes class variables and pool dictionaries.
  2726. #
  2727. method STGDataAttr::generateDefinition {this} {
  2728.     set classImpl [[$this ooplClass] classImplementation]
  2729.  
  2730.     set name [$this getSTName]
  2731.     if { [$this getPropertyValue isPoolDict] == "1" } {
  2732.     set name [cap $name]
  2733.     $classImpl addPoolDictionary $name
  2734.     } elseif [$this isClassFeature] {
  2735.     set name [cap $name]
  2736.     $classImpl addClassVariable $name
  2737.     } else {
  2738.     $classImpl addInstanceVariable $name
  2739.     }
  2740.     $this name $name
  2741. }
  2742.  
  2743.  
  2744. # Generates description of the attribute in the class implementation object.
  2745. #
  2746. method STGDataAttr::generateDescription {this} {
  2747.     if [regsub -all {'} [$this getPropertyValue freeText] "" comment] {
  2748.     puts "WARNING: Removed \' from description of [$this getSTName]"
  2749.     }
  2750.     set commentLine [$this name]
  2751.     
  2752.     # Add type if it exists
  2753.     set type [$this ooplType] 
  2754.     if { $type != "" } {
  2755.     if { [$type getName] != "" } {
  2756.         set commentLine "$commentLine ([$this asSTName [$type getName]])"
  2757.     }
  2758.     }
  2759.  
  2760.     # Add free text if is there
  2761.     if { $comment != "" } {    
  2762.     set commentLine "$commentLine: $comment"
  2763.     [[$this ooplClass] classImplementation] addCommentLine $commentLine
  2764.     }
  2765. }
  2766.  
  2767.  
  2768. # Generates initial value in initialize for instance variable
  2769. # or in an expression for class variable.
  2770. #
  2771. method STGDataAttr::generateInitialValue {this} {
  2772.     set initialValue [$this getPropertyValue initial_value]
  2773.  
  2774.     if { $initialValue != "" } {
  2775.     set classImpl [[$this ooplClass] classImplementation]
  2776.  
  2777.     if [$this isClassFeature] {
  2778.         # class variable: make expression to set it.
  2779.         set expression "[[$this ooplClass] getSTName] [$this name]"
  2780.         set expression "$expression: $initialValue"
  2781.  
  2782.         # If there is no write access we can't do it
  2783.         if { [$this writeAccess] == "None" } {
  2784.         puts "WARNING: Cannot generate initial value expression for class variable [$this name]: no write access"
  2785.         } else {
  2786.         $classImpl addExpression $expression
  2787.         }
  2788.  
  2789.     } else {
  2790.         # generate expression in initialize if it exists
  2791.         set initialize [$classImpl initialize]
  2792.  
  2793.         if { $initialize != "" } {
  2794.         # Make it conditional if there is an initializer
  2795.         # in that case it may already have a value
  2796.         set block $initialize
  2797.  
  2798.         if { [$this hasInitializer] == 1} {
  2799.             set block [$initialize addExpression "[$this name] isNil ifTrue:"]
  2800.         }
  2801.         $block addExpression "[$this name] := $initialValue"
  2802.         }
  2803.     }
  2804.     } 
  2805. }
  2806.  
  2807.  
  2808. # Generates get and set methods for the attribute if allowed by read and write access.
  2809. #
  2810. method STGDataAttr::generateGetSet {this} {
  2811.     set name [$this name]
  2812.     set argName [$this getArgumentName]
  2813.     set classImpl [[$this ooplClass] classImplementation]
  2814.     set isClassVar [$this isClassFeature]
  2815.  
  2816.     set readCategory [$this getReadCategory "accessing"]
  2817.     if { $readCategory != "" } {
  2818.     # generate Get
  2819.     if $isClassVar {
  2820.         set get [$classImpl getClassMethodImplementation "$name" $readCategory]
  2821.     } else {
  2822.         set get [$classImpl getInstanceMethodImplementation "$name" $readCategory]
  2823.     }
  2824.     $get addExpression "^$name"
  2825.     }
  2826.     
  2827.     set writeCategory [$this getWriteCategory "modifying"]
  2828.     if { $writeCategory != ""} {
  2829.     # generate Set
  2830.     if $isClassVar {
  2831.         set set [$classImpl getClassMethodImplementation "$name:" $writeCategory]
  2832.     } else {
  2833.         set set [$classImpl getInstanceMethodImplementation "$name:" $writeCategory]
  2834.     }
  2835.     $set addArgument $argName
  2836.     $set addExpression "$name := $argName"
  2837.     }
  2838. }
  2839.  
  2840.  
  2841. # Generates an expression in the printVars and printOn methods. to print it.
  2842. #
  2843. method STGDataAttr::generatePrint {this} {
  2844.     set printVars [[[$this ooplClass] classImplementation] printVars]
  2845.     set printOn [[[$this ooplClass] classImplementation] printOn]
  2846.     if { $printVars != "" } {
  2847.     $printVars addExpression "aStream cr; tab: anInteger; nextPutAll: \'[$this name]: \' displayString"
  2848.     $printVars addExpression "[$this name] printOn: aStream"
  2849.     }
  2850.     if { $printOn != "" } {
  2851.     $printOn addExpression "aStream cr; nextPutAll: \'[$this name]: \' displayString"
  2852.     $printOn addExpression "[$this name] printOn: aStream"
  2853.     }
  2854. }
  2855.  
  2856.  
  2857. # Return name for this attribute when it used as argument:
  2858. # base it on type if it exists and the name otherwise.
  2859. #
  2860. method STGDataAttr::argumentName {this} {
  2861.     set type [$this ooplType]
  2862.     if { $type != "" } {
  2863.     if { [$type getType3GL] != "" } {
  2864.         return [$this asSTName [$this asArgument [$type getType3GL]]]
  2865.     }  elseif { [$type getName] != "" } {
  2866.         return [$this asSTName [$this asArgument [$type getName]]]
  2867.     }
  2868.     } 
  2869.     # It is safe to use getSTName because first char is always capitalized
  2870.     return [$this asArgument [$this getSTName]]
  2871. }
  2872.  
  2873. # Do not delete this line -- regeneration end marker
  2874.  
  2875. selfPromoter OPDataAttr {this} {
  2876.     STGDataAttr promote $this
  2877. }
  2878.  
  2879. #      File:           @(#)stggenasso.tcl    /main/1
  2880.  
  2881.  
  2882. # General association generator: contains methods that are 
  2883. # the same for all types of association.
  2884.  
  2885. Class STGGenAssocAttr : {STGAttribute} {
  2886.     constructor
  2887.     method destructor
  2888.     method generateAll
  2889.     method setNames
  2890.     method generate
  2891.     method generateDescription
  2892.     method argumentName
  2893.     method oppositeMandatoryOne
  2894.     method generator
  2895.     attribute _generator
  2896. }
  2897.  
  2898. constructor STGGenAssocAttr {class this name} {
  2899.     set this [STGAttribute::constructor $class $this $name]
  2900.     # Start constructor user section
  2901.     # End constructor user section
  2902.     return $this
  2903. }
  2904.  
  2905. method STGGenAssocAttr::destructor {this} {
  2906.     set ref [$this _generator]
  2907.     if {$ref != ""} {
  2908.         $ref _assocAttr ""
  2909.     }
  2910.     # Start destructor user section
  2911.     $this _generator ""
  2912.     # End destructor user section
  2913.     $this STGAttribute::destructor
  2914. }
  2915.  
  2916.  
  2917. # Calls all methods in the generator.
  2918. #
  2919. method STGGenAssocAttr::generateAll {this} {
  2920.     set generator [$this generator]
  2921.     $generator generateData
  2922.     $generator generateSet
  2923.     $generator generateGet
  2924.     $generator generateRemove
  2925.     if { [$this opposite] != "" } {
  2926.     $generator generateSetRef
  2927.     $generator generateRemoveRef
  2928.     }
  2929.     $generator generateInitialize
  2930.     $generator generateRelease
  2931. }
  2932.  
  2933.  
  2934. # Sets the roleName to the ST name for this attribute and parameterName to the argument name 
  2935. # of this attribute in the association generator object.
  2936. #
  2937. method STGGenAssocAttr::setNames {this} {
  2938.     [$this generator] roleName [$this getSTName]
  2939.     [$this generator] parameterName [$this getArgumentName] 
  2940. }
  2941.  
  2942.  
  2943. # Generates for association attribute:
  2944. # sets up generator, sets up generator for opposite,
  2945. # generates a description,
  2946. # calls generateAll (defined in subclasses), and
  2947. # generates print methods for the attribute if
  2948. # generatePrint is set in STGGlobal.
  2949. #
  2950. method STGGenAssocAttr::generate {this} {
  2951.     # get generator if it didn't exist yet.
  2952.     if { [$this generator] == "" } {
  2953.     $this setGenerator
  2954.     $this setNames
  2955.     }
  2956.  
  2957.     # Now set class implementation object
  2958.     # assumption: generate is called just once
  2959.     # if not this code is a bit inefficient
  2960.     [$this generator] classImplementation [[$this ooplClass] classImplementation]
  2961.  
  2962.     # get a generator for opposite if it exists
  2963.     # needed to do generate*call
  2964.     set opposite [$this opposite]
  2965.     if { $opposite != "" } {
  2966.     if { [$opposite generator] == "" } {
  2967.         $opposite setGenerator
  2968.         $opposite setNames
  2969.         # make generators point to each other
  2970.         [$this generator] opposite [$opposite generator]
  2971.         [$opposite generator] opposite [$this generator]
  2972.     }
  2973.     }
  2974.  
  2975.     # Must first call generateAll because generateDescription needs
  2976.     # instance variable name
  2977.     $this generateAll
  2978.     $this generateDescription
  2979.  
  2980.     if [$globals generatePrint] {
  2981.     set printOn [[[$this ooplClass] classImplementation] printOn]
  2982.     if { $printOn != "" } { 
  2983.         [$this generator] generatePrintCode $printOn
  2984.     }
  2985.     }
  2986.     [$this generator] classImplementation ""
  2987. }
  2988.  
  2989.  
  2990. # Generate a description of the association attribute in the class comment,
  2991. # based on free text. If there is no free text generate nothing.
  2992. #
  2993. method STGGenAssocAttr::generateDescription {this} {
  2994.     set commentLine "[[$this generator] variableName]"
  2995.  
  2996.     if [regsub -all {'} [$this getPropertyValue freeText] "" comment] {
  2997.     puts "WARNING: Removed \' from description of [$this getSTName]"
  2998.     }
  2999.  
  3000.     # Add free text if is there
  3001.     if { $comment != "" } {
  3002.     set commentLine "$commentLine: $comment"
  3003.     [[$this ooplClass] classImplementation] addCommentLine $commentLine
  3004.     }
  3005. }
  3006.  
  3007.  
  3008. # Returns the name of this attribute when used as argument, based on the role name.
  3009. #
  3010. method STGGenAssocAttr::argumentName {this} {
  3011.     return [$this asArgument [$this getSTName]]
  3012. }
  3013.  
  3014.  
  3015. # Returns 1 if the opposite of this association attribute is mandatory, one and non-qualified.
  3016. #
  3017. method STGGenAssocAttr::oppositeMandatoryOne {this} {
  3018.     set opposite [$this opposite]
  3019.     if { $opposite == "" } {
  3020.     return 0
  3021.     }
  3022.  
  3023.     if  {[$opposite isMandatory] && (![$opposite isQualified]) && ([$opposite getMultiplicity] == "one") } {
  3024.     return 1
  3025.     }
  3026.     
  3027.     return 0
  3028. }
  3029.  
  3030. # Do not delete this line -- regeneration end marker
  3031.  
  3032. method STGGenAssocAttr::generator {this args} {
  3033.     if {$args == ""} {
  3034.         return [$this _generator]
  3035.     }
  3036.     set ref [$this _generator]
  3037.     if {$ref != ""} {
  3038.         $ref _assocAttr ""
  3039.     }
  3040.     set obj [lindex $args 0]
  3041.     if {$obj != ""} {
  3042.         $obj _assocAttr $this
  3043.     }
  3044.     $this _generator $obj
  3045. }
  3046.  
  3047.  
  3048. #      File:           @(#)stgclassen.tcl    /main/1
  3049.  
  3050.  
  3051. # Generator for enum classes.
  3052.  
  3053. Class STGClassEnum : {STGClass} {
  3054.     constructor
  3055.     method destructor
  3056.     method generate
  3057. }
  3058.  
  3059. constructor STGClassEnum {class this name} {
  3060.     set this [STGClass::constructor $class $this $name]
  3061.     # Start constructor user section
  3062.     # End constructor user section
  3063.     return $this
  3064. }
  3065.  
  3066. method STGClassEnum::destructor {this} {
  3067.     # Start destructor user section
  3068.     # End destructor user section
  3069. }
  3070.  
  3071.  
  3072. # Prints a message that enums are not supported in Smalltalk.
  3073. #
  3074. method STGClassEnum::generate {this classImpl} {
  3075.     puts "ERROR: enums not supported by Smalltalk, not generating for [$this getSTName]"
  3076. }
  3077.  
  3078. # Do not delete this line -- regeneration end marker
  3079.  
  3080. Class STGClassEnumD : {STGClassEnum OPClassEnum} {
  3081. }
  3082.  
  3083. selfPromoter OPClassEnum {this} {
  3084.     STGClassEnumD promote $this
  3085. }
  3086.  
  3087. #      File:           @(#)stgclassge.tcl    /main/1
  3088.  
  3089.  
  3090. Class STGClassGenericTypeDef : {STGClass} {
  3091.     constructor
  3092.     method destructor
  3093. }
  3094.  
  3095. constructor STGClassGenericTypeDef {class this name} {
  3096.     set this [STGClass::constructor $class $this $name]
  3097.     # Start constructor user section
  3098.     # End constructor user section
  3099.     return $this
  3100. }
  3101.  
  3102. method STGClassGenericTypeDef::destructor {this} {
  3103.     # Start destructor user section
  3104.     # End destructor user section
  3105. }
  3106.  
  3107. # Do not delete this line -- regeneration end marker
  3108.  
  3109. Class STGClassGenericTypeDefD : {STGClassGenericTypeDef OPClassGenericTypeDef} {
  3110. }
  3111.  
  3112. selfPromoter OPClassGenericTypeDef {this} {
  3113.     STGClassGenericTypeDefD promote $this
  3114. }
  3115.  
  3116. #      File:           @(#)stgclasstd.tcl    /main/1
  3117.  
  3118.  
  3119. Class STGClassTDef : {STGClass} {
  3120.     constructor
  3121.     method destructor
  3122. }
  3123.  
  3124. constructor STGClassTDef {class this name} {
  3125.     set this [STGClass::constructor $class $this $name]
  3126.     # Start constructor user section
  3127.     # End constructor user section
  3128.     return $this
  3129. }
  3130.  
  3131. method STGClassTDef::destructor {this} {
  3132.     # Start destructor user section
  3133.     # End destructor user section
  3134. }
  3135.  
  3136. # Do not delete this line -- regeneration end marker
  3137.  
  3138. Class STGClassTDefD : {STGClassTDef OPClassTDef} {
  3139. }
  3140.  
  3141. selfPromoter OPClassTDef {this} {
  3142.     STGClassTDefD promote $this
  3143. }
  3144.  
  3145. #      File:           @(#)stglinkcla.tcl    /main/1
  3146.  
  3147.  
  3148. # This class is the top level class generator
  3149. # for link classes. 
  3150.  
  3151. Class STGLinkClass : {STGClass} {
  3152.     constructor
  3153.     method destructor
  3154.     method generate
  3155.     method printGeneratingMessage
  3156. }
  3157.  
  3158. constructor STGLinkClass {class this name} {
  3159.     set this [STGClass::constructor $class $this $name]
  3160.     # Start constructor user section
  3161.     # End constructor user section
  3162.     return $this
  3163. }
  3164.  
  3165. method STGLinkClass::destructor {this} {
  3166.     # Start destructor user section
  3167.     # End destructor user section
  3168. }
  3169.  
  3170.  
  3171. # Check that this link class is named and generate
  3172. # as if it were a normal class.
  3173. #
  3174. method STGLinkClass::generate {this classImpl} {
  3175.     if { [$this getSTName] == "" } {
  3176.     puts "WARNING: Link class without name skipped"
  3177.     } else {
  3178.     $this STGClass::generate $classImpl
  3179.     } 
  3180. }
  3181.  
  3182.  
  3183. # Print a message stating that generation for this link class is in progress.
  3184. #
  3185. method STGLinkClass::printGeneratingMessage {this} {
  3186.     puts "Generating for link class [$this getSTName]"
  3187. }
  3188.  
  3189. # Do not delete this line -- regeneration end marker
  3190.  
  3191. Class STGLinkClassD : {STGLinkClass OPLinkClass} {
  3192. }
  3193.  
  3194. selfPromoter OPLinkClass {this} {
  3195.     STGLinkClassD promote $this
  3196. }
  3197.  
  3198. #      File:           @(#)stgoneoppq.tcl    /main/1
  3199.  
  3200.  
  3201. # Generator for roles which are the opposite of qualified associations
  3202. # in which this opposite has multiplicity one.
  3203.  
  3204. Class STGOneOppQual : {STGAssocOne} {
  3205.     constructor
  3206.     method destructor
  3207.     method generateData
  3208.     method generateSet
  3209.     method generateRemove
  3210.     method generateInitialize
  3211.     method generateReleaseCode
  3212.     method generateSetRefMessage
  3213.     method generateRemoveRefMessage
  3214.     method generateRemoveMessage
  3215.     method generateQualifierSet
  3216.     method generateQualifierGet
  3217.     method generateQualifierSetRef
  3218.     method generateQualifierPrint
  3219.  
  3220.     # Used to store the name of the qualifier on the other side.
  3221.     # It may be different from the qualifier on this side if 
  3222.     # the qualifierName property has been set.
  3223.     #
  3224.     attribute oppositeQualifierName
  3225. }
  3226.  
  3227. constructor STGOneOppQual {class this assocAttr} {
  3228.     set this [STGAssocOne::constructor $class $this $assocAttr]
  3229.     # Start constructor user section
  3230.     # End constructor user section
  3231.     return $this
  3232. }
  3233.  
  3234. method STGOneOppQual::destructor {this} {
  3235.     # Start destructor user section
  3236.     # End destructor user section
  3237.     $this STGAssocOne::destructor
  3238. }
  3239.  
  3240.  
  3241. # Generates instance variable to implement this
  3242. # association and sets variableName to <roleName>.
  3243. # Also generates the instance variable for the qualifier on this side
  3244. # if necessary and the methods for this qualifier.
  3245. #
  3246. method STGOneOppQual::generateData {this} {
  3247.     $this STGAssocOne::generateData
  3248.  
  3249.     set qualifier [$this qualifierName]
  3250.     $this oppositeQualifierName $qualifier
  3251.     # retrieve user specified qualifier
  3252.     set userQualifier [[$this assocAttr] getPropertyValue qualifierName]
  3253.     if { $userQualifier != "" } {
  3254.     set qualifier $userQualifier
  3255.     }
  3256.  
  3257.     # check if it exists
  3258.     set exists 0
  3259.     set className [[[$this assocAttr] ooplClass] getSTName]
  3260.     foreach attribute [[[$this assocAttr] ooplClass] dataAttrSet] {
  3261.     if { [$attribute getSTName] == $qualifier } {
  3262.         if { [$attribute isClassFeature] || ([$attribute getPropertyValue isPoolDict] == "1") } {
  3263.         puts "WARNING: qualifier $qualifier is defined in $className, but not as instance variable"
  3264.         } else {
  3265.         set exists 1
  3266.         }    
  3267.     }
  3268.     }
  3269.  
  3270.     if { (!$exists) && ($userQualifier != "") } {
  3271.     puts "WARNING: user defined qualifier $qualifier not defined in $className, creating it"
  3272.     }
  3273.  
  3274.     $this qualifierName $qualifier
  3275.  
  3276.     if { !$exists } {
  3277.     [$this classImplementation] addInstanceVariable $qualifier
  3278.     [$this classImplementation] addCommentLine "$qualifier: qualifier for [[$this assocAttr] getSTName]"
  3279.     $this generateQualifierPrint
  3280.     }
  3281.  
  3282.     if { ($userQualifier != "") || $exists } {
  3283.     $this generateQualifierSet
  3284.     $this generateQualifierGet
  3285.     }
  3286.     $this generateQualifierSetRef
  3287. }
  3288.  
  3289.  
  3290. # Generates the set method to set the association.
  3291. #
  3292. method STGOneOppQual::generateSet {this} {
  3293.     set name [$this variableName]
  3294.     set qualName [$this qualifierName]
  3295.     set selector "set[cap [$this roleName]]:at:"
  3296.     set set [$this getModifyImplementation $selector]
  3297.     if { $set == "" } {
  3298.             return
  3299.     }
  3300.  
  3301.     set parName [$set getNewUniqueArgumentName [$this parameterName]]
  3302.     set qualPar [$set getNewUniqueArgumentName [$this qualifierParameter]]
  3303.  
  3304.     # if it is mandatory generate a nil check and an inequality check
  3305.     if [[$this assocAttr] isMandatory] {
  3306.     $this generateNilCheck $set $parName
  3307.     }
  3308.  
  3309.     if { [$this opposite] != "" } {
  3310.     if [[$this assocAttr] isMandatory] {
  3311.         set compare "($name ~~ $parName | ($qualName ~= $qualPar))"
  3312.         set set [$set addExpression "$compare ifTrue:"]
  3313.     }
  3314.     # remove old links
  3315.     [$this opposite] generateRemoveMessage $set $parName $qualPar
  3316.     set removeBlock $set
  3317.     if { ![[$this assocAttr] isMandatory]} {
  3318.         set removeBlock [$set addExpression "$name isNil ifFalse:"]
  3319.     }
  3320.     [$this opposite] generateRemoveRefMessage $removeBlock $name self $qualName
  3321.     # set new link
  3322.     [$this opposite] generateSetRefMessage $set $parName self $qualPar
  3323.     }
  3324.  
  3325.     $set addExpression "$name := $parName"   
  3326.     $set addExpression "$qualName := $qualPar"   
  3327. }
  3328.  
  3329.  
  3330. # Generates the set method to remove the association.
  3331. #
  3332. method STGOneOppQual::generateRemove {this} {
  3333.     set selector "remove[cap [$this roleName]]"
  3334.     set remove [$this getRemoveImplementation $selector]
  3335.     if  { $remove != "" } {
  3336.     $this generateRemoveCode $remove [$this opposite] [$this qualifierName]
  3337.     }
  3338. }
  3339.  
  3340.  
  3341. # Generates the additions to initialize, if it exists.
  3342. #
  3343. method STGOneOppQual::generateInitialize {this} {
  3344.     set initialize [[$this classImplementation] initialize]
  3345.     if { $initialize == "" } {
  3346.     return
  3347.     }
  3348.  
  3349.     if { [[$this assocAttr] hasInitializer] == 1 } {
  3350.     set qualPar [$initialize getUniqueArgumentName \
  3351.         [$this oppositeQualifierName] [$this qualifierParameter] ]
  3352.     $this generateInitializeCode $initialize $qualPar
  3353.     $initialize addExpression "[$this qualifierName] := $qualPar"
  3354.     } else {
  3355.     $this generateInitializeCode $initialize 
  3356.     $initialize addExpression "[$this qualifierName] := nil"
  3357.     }
  3358.  
  3359. }
  3360.  
  3361.  
  3362. # Generates the additions to release in block.
  3363. #
  3364. method STGOneOppQual::generateReleaseCode {this block} {
  3365.     $this generateRemoveCode $block [$this opposite] [$this qualifierName]
  3366. }
  3367.  
  3368.  
  3369. # Generates expressions in block to send setRef
  3370. # messages to object for <parameter> and for <qualifier>.
  3371. #
  3372. method STGOneOppQual::generateSetRefMessage {this block object parameter qualifier} {
  3373.     $this STGAssocOne::generateSetRefMessage $block $object $parameter
  3374.     set qualName [[$this assocAttr] getPropertyValue qualifierName]
  3375.     if { $qualName == "" } {
  3376.     set qualName [$this qualifierName]
  3377.     }
  3378.     set setQualRefName "set[cap $qualName]Ref:"
  3379.     $block addExpression "$object $setQualRefName $qualifier"
  3380. }
  3381.  
  3382.  
  3383. # Generates expressions in block to send a SetRef
  3384. # message to object with parameter nil.
  3385. #
  3386. method STGOneOppQual::generateRemoveRefMessage {this block object parameter qualifier} {
  3387.     $this STGAssocOne::generateSetRefMessage $block $object nil
  3388. }
  3389.  
  3390.  
  3391. # Generates an expression in block to send a remove
  3392. # message to object.
  3393. #
  3394. method STGOneOppQual::generateRemoveMessage {this block object qualifier} {
  3395.     $this STGAssocOne::generateRemoveMessage $block $object
  3396. }
  3397.  
  3398.  
  3399. # Generates the special method to set a qualifier and 
  3400. # update the association if necessary.
  3401. #
  3402. method STGOneOppQual::generateQualifierSet {this} {
  3403.     set selector "[$this qualifierName]:"
  3404.     set setQual [$this getModifyImplementation $selector]
  3405.     if { $setQual == "" } {
  3406.     return
  3407.     }
  3408.  
  3409.     set name [$this variableName]
  3410.     set qualName [$this qualifierName]
  3411.     set qualPar [$this qualifierParameter]
  3412.     $setQual addArgument $qualPar
  3413.  
  3414.     # if it's empty generate the set
  3415.     if [$setQual isEmpty] {
  3416.     $setQual addExpression "$qualName := $qualPar"
  3417.     }
  3418.  
  3419.     # generate check if update is needed
  3420.     set checkExpr "($name notNil & ($qualName ~= $qualPar)) ifTrue:"
  3421.     set block [$setQual insertExpression $checkExpr]
  3422.     set opposite [$this opposite]
  3423.  
  3424.     # remove and set on other side
  3425.     $opposite generateRemoveRefMessage $block $name self $qualName
  3426.     $opposite generateRemoveMessage $block $name $qualPar  
  3427.     $opposite generateSetRefMessage $block $name self $qualPar    
  3428. }
  3429.  
  3430.  
  3431. # Generates the method to get the qualifier.
  3432. #
  3433. method STGOneOppQual::generateQualifierGet {this} {
  3434.     set selector "[$this qualifierName]"
  3435.     set getQual [$this getAccessImplementation $selector]
  3436.     if { $getQual == "" } {
  3437.     set getQual [$this getPrivateImplementation $selector]
  3438.     }
  3439.  
  3440.     # if it's empty generate the get
  3441.     if [$getQual isEmpty] {
  3442.     $getQual addExpression "\^[$this qualifierName]"
  3443.     }
  3444. }
  3445.  
  3446.  
  3447. # Generates the implementation method to set the
  3448. # qualifier instance variable.
  3449. #
  3450. method STGOneOppQual::generateQualifierSetRef {this} {
  3451.     set selector "set[cap [$this qualifierName]]Ref:"
  3452.     set setQualRef [$this getPrivateImplementation $selector]
  3453.     $setQualRef addArgument [$this qualifierParameter]
  3454.     set assign "[$this qualifierName] := [$this qualifierParameter]"
  3455.     $setQualRef addExpression $assign
  3456. }
  3457.  
  3458.  
  3459. # Generates in the printVars method to print the qualifier instance variable.
  3460. #
  3461. method STGOneOppQual::generateQualifierPrint {this} {
  3462.     set printVars [[$this classImplementation] printVars]
  3463.     set qualName [$this qualifierName]
  3464.     if { $printVars != "" } {
  3465.     $printVars addExpression "aStream cr; tab: anInteger; nextPutAll: \'$qualName: \' displayString"
  3466.     $printVars addExpression "$qualName printOn: aStream"
  3467.     }
  3468. }
  3469.  
  3470. # Do not delete this line -- regeneration end marker
  3471.  
  3472.  
  3473. #      File:           @(#)stgassocat.tcl    /main/1
  3474.  
  3475.  
  3476. # Generator class for normal association attributes.
  3477.  
  3478. Class STGAssocAttr : {STGGenAssocAttr OPAssocAttr} {
  3479.     constructor
  3480.     method destructor
  3481.     method setGenerator
  3482. }
  3483.  
  3484. constructor STGAssocAttr {class this name} {
  3485.     set this [STGGenAssocAttr::constructor $class $this $name]
  3486.     # Start constructor user section
  3487.     # End constructor user section
  3488.     return $this
  3489. }
  3490.  
  3491. method STGAssocAttr::destructor {this} {
  3492.     # Start destructor user section
  3493.     # End destructor user section
  3494. }
  3495.  
  3496.  
  3497. # Set generator to assocOne or assocMany
  3498. # exceptions:  
  3499. # * opposite of a qualified attribute with multiplicity one,
  3500. # where a oneoppqual generator is used.
  3501. # * opposite of a qualified attribute with multiplicity many, where a qualMany
  3502. # is used.
  3503. # In these two special cases set up the
  3504. # qualifierName and qualifierParameter 
  3505. # attributes in the generator.
  3506. #
  3507. method STGAssocAttr::setGenerator {this} {
  3508.     set opposite [$this opposite]
  3509.     if { $opposite != "" } {
  3510.     if [$opposite isQualified] {
  3511.         if { [$this getMultiplicity] == "one" } {
  3512.         $this generator [STGOneOppQual new $this]
  3513.         } else {
  3514.         $this generator [STGManyQual new $this]
  3515.         }
  3516.         set qualifier [$opposite qualifier]
  3517.         [$this generator] qualifierName [$qualifier getSTName]
  3518.         [$this generator] qualifierParameter [$qualifier getArgumentName]
  3519.         return
  3520.     }
  3521.     }
  3522.     
  3523.     if { [$this getMultiplicity] == "one" } {
  3524.     $this generator [STGAssocOne new $this]
  3525.     } else {
  3526.     $this generator [STGAssocMany new $this]
  3527.     }
  3528. }
  3529.  
  3530. # Do not delete this line -- regeneration end marker
  3531.  
  3532. selfPromoter OPAssocAttr {this} {
  3533.     STGAssocAttr promote $this
  3534. }
  3535.  
  3536. #      File:           @(#)stglinkatt.tcl    /main/1
  3537.  
  3538.  
  3539. # Generates for link attributes.
  3540.  
  3541. Class STGLinkAttr : {STGGenAssocAttr OPLinkAttr} {
  3542.     constructor
  3543.     method destructor
  3544.     method setGenerator
  3545.     method setNames
  3546.     method argumentName
  3547. }
  3548.  
  3549. constructor STGLinkAttr {class this name} {
  3550.     set this [STGGenAssocAttr::constructor $class $this $name]
  3551.     # Start constructor user section
  3552.     # End constructor user section
  3553.     return $this
  3554. }
  3555.  
  3556. method STGLinkAttr::destructor {this} {
  3557.     # Start destructor user section
  3558.     # End destructor user section
  3559. }
  3560.  
  3561.  
  3562. # Initializes generator for link attribute: 
  3563. # * multiplicity one: uses assocOne
  3564. # * multiplicity many: uses assocMany
  3565. #
  3566. method STGLinkAttr::setGenerator {this} {
  3567.     if { [$this getMultiplicity] == "one" } {
  3568.     $this generator [STGAssocOne new $this]
  3569.     } else {
  3570.     $this generator [STGAssocMany new $this]
  3571.     }
  3572. }
  3573.  
  3574.  
  3575. # Set the roleName in the generator to <linkclass_name>Of<role_name> and parameterName accordingly.
  3576. #
  3577. method STGLinkAttr::setNames {this} {
  3578.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  3579.     set name "${linkClassName}Of[cap [$this getSTName]]"
  3580.     [$this generator] roleName $name
  3581.     [$this generator] parameterName [$this asArgument $name]
  3582. }
  3583.  
  3584.  
  3585. # Return name for this link when used as parameter.
  3586. #
  3587. method STGLinkAttr::argumentName {this} {
  3588.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  3589.     set name "${linkClassName}Of[cap [$this getSTName]]"
  3590.     return [$this asArgument $name]
  3591. }
  3592.  
  3593. # Do not delete this line -- regeneration end marker
  3594.  
  3595. selfPromoter OPLinkAttr {this} {
  3596.     STGLinkAttr promote $this
  3597. }
  3598.  
  3599. #      File:           @(#)stgqualass.tcl    /main/1
  3600.  
  3601.  
  3602. # Generator for qualified associations.
  3603.  
  3604. Class STGQualAssocAttr : {STGGenAssocAttr OPQualAssocAttr} {
  3605.     constructor
  3606.     method destructor
  3607.     method setGenerator
  3608. }
  3609.  
  3610. constructor STGQualAssocAttr {class this name} {
  3611.     set this [STGGenAssocAttr::constructor $class $this $name]
  3612.     # Start constructor user section
  3613.     # End constructor user section
  3614.     return $this
  3615. }
  3616.  
  3617. method STGQualAssocAttr::destructor {this} {
  3618.     # Start destructor user section
  3619.     # End destructor user section
  3620. }
  3621.  
  3622.  
  3623. # Sets generator: oneQualified or manyQualified.
  3624. #
  3625. method STGQualAssocAttr::setGenerator {this} {
  3626.     if { [$this getMultiplicity] == "one" } {
  3627.     $this generator [STGOneQual new $this]
  3628.     } else {
  3629.     $this generator [STGManyQual new $this]
  3630.     }
  3631.     [$this generator] qualifierName [[$this qualifier] getSTName]
  3632.     [$this generator] qualifierParameter [[$this qualifier] getArgumentName]
  3633. }
  3634.  
  3635. # Do not delete this line -- regeneration end marker
  3636.  
  3637. selfPromoter OPQualAssocAttr {this} {
  3638.     STGQualAssocAttr promote $this
  3639. }
  3640.  
  3641. #      File:           @(#)stgquallin.tcl    /main/1
  3642.  
  3643.  
  3644. # Generator class for qualified link attributes.
  3645.  
  3646. Class STGQualLinkAttr : {STGGenAssocAttr OPQualLinkAttr} {
  3647.     constructor
  3648.     method destructor
  3649.     method setGenerator
  3650.     method setNames
  3651.     method argumentName
  3652. }
  3653.  
  3654. constructor STGQualLinkAttr {class this name} {
  3655.     set this [STGGenAssocAttr::constructor $class $this $name]
  3656.     # Start constructor user section
  3657.     # End constructor user section
  3658.     return $this
  3659. }
  3660.  
  3661. method STGQualLinkAttr::destructor {this} {
  3662.     # Start destructor user section
  3663.     # End destructor user section
  3664. }
  3665.  
  3666.  
  3667. # Set the generator: use the generators for normal qualified associations.
  3668. #
  3669. method STGQualLinkAttr::setGenerator {this} {
  3670.     if { [$this getMultiplicity] == "one" } {
  3671.     $this generator [STGOneQual new $this]
  3672.     } else {
  3673.     $this generator [STGManyQual new $this]    
  3674.     }
  3675.     [$this generator] qualifierName [[$this qualifier] getSTName]
  3676.     [$this generator] qualifierParameter [[$this qualifier] getArgumentName]
  3677. }
  3678.  
  3679.  
  3680. # Set role name to <link_name>Of<role_name> style and parameterName accordingly.
  3681. #
  3682. method STGQualLinkAttr::setNames {this} {
  3683.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  3684.     set name "${linkClassName}Of[cap [$this getSTName]]"
  3685.     [$this generator] roleName $name
  3686.     [$this generator] parameterName [$this asArgument $name]
  3687. }
  3688.  
  3689.  
  3690. # Return name for this attribute when used as parameter.
  3691. #
  3692. method STGQualLinkAttr::argumentName {this} {
  3693.     set linkClassName [$this asSTName [[$this ooplType] getName]]
  3694.     set name "${linkClassName}Of[cap [$this getSTName]]"
  3695.     return [$this asArgument $name]
  3696. }
  3697.  
  3698. # Do not delete this line -- regeneration end marker
  3699.  
  3700. selfPromoter OPQualLinkAttr {this} {
  3701.     STGQualLinkAttr promote $this
  3702. }
  3703.  
  3704. #      File:           @(#)stgreverse.tcl    /main/1
  3705.  
  3706.  
  3707. # Generator class for reverse link attributes.
  3708.  
  3709. Class STGReverseLinkAttr : {STGGenAssocAttr OPReverseLinkAttr} {
  3710.     constructor
  3711.     method destructor
  3712.     method setGenerator
  3713. }
  3714.  
  3715. constructor STGReverseLinkAttr {class this name} {
  3716.     set this [STGGenAssocAttr::constructor $class $this $name]
  3717.     # Start constructor user section
  3718.     # End constructor user section
  3719.     return $this
  3720. }
  3721.  
  3722. method STGReverseLinkAttr::destructor {this} {
  3723.     # Start destructor user section
  3724.     # End destructor user section
  3725. }
  3726.  
  3727.  
  3728. # Sets the generator: an assocOne for a reverse link in a normal link association or a 
  3729. # oneOppQual for the opposite of a qualified  association.
  3730. #
  3731. method STGReverseLinkAttr::setGenerator {this} {
  3732.     set opposite [$this opposite]
  3733.     set qualifier ""
  3734.     if { $opposite != "" } {
  3735.     if [$opposite isQualified] {
  3736.         set qualifier [$opposite qualifier]
  3737.     }
  3738.     }
  3739.     if { $qualifier != "" } {
  3740.     $this generator [STGOneOppQual new $this]
  3741.     [$this generator] qualifierName [$qualifier getSTName]
  3742.     [$this generator] qualifierParameter [$qualifier getArgumentName]
  3743.     } else {
  3744.     $this generator [STGAssocOne new $this] 
  3745.     }
  3746. }
  3747.  
  3748. # Do not delete this line -- regeneration end marker
  3749.  
  3750. selfPromoter OPReverseLinkAttr {this} {
  3751.     STGReverseLinkAttr promote $this
  3752. }
  3753.