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

  1. #---------------------------------------------------------------------------
  2. #
  3. # Copyright (c) 1997 by Cayenne Software, Inc.
  4. #
  5. # This software is furnished under a license and may be used only in
  6. # accordance with the terms of such license and with the inclusion of
  7. # the above copyright notice. This software or any other copies thereof
  8. # may not be provided or otherwise made available to any other person.
  9. # No title to and ownership of the software is hereby transferred.
  10. #
  11. # The information in this software is subject to change without notice
  12. # and should not be construed as a commitment by Cayenne Software, Inc.
  13. #
  14. #---------------------------------------------------------------------------
  15. #
  16. #       File            : stgentor.tcl
  17. #       Author          : 
  18. #       Original date   : November 1997
  19. #       Description     : Classes for code generation
  20. #
  21. #---------------------------------------------------------------------------
  22.  
  23. #---------------------------------------------------------------------------
  24. #      File:           @(#)stfilehand.tcl    /main/titanic/2
  25. #---------------------------------------------------------------------------
  26.  
  27. # Start user added include file section
  28. # End user added include file section
  29.  
  30. require "filehandle.tcl"
  31.  
  32.  
  33. Class STFileHandler : {FileHandler} {
  34.     constructor
  35.     method destructor
  36.     method getSpecialFiles
  37.     method getFileTypes
  38.     method getImportFileName
  39.     method getExportFileName
  40.     method sourceTclFiles
  41.  
  42.     # The Smalltalk file type. All methods using
  43.     # the Smalltalk file type query this attribute.
  44.     #
  45.     attribute stType
  46. }
  47.  
  48. constructor STFileHandler {class this} {
  49.     set this [FileHandler::constructor $class $this]
  50.     # Start constructor user section
  51.     $this stType "st"
  52.     # End constructor user section
  53.     return $this
  54. }
  55.  
  56. method STFileHandler::destructor {this} {
  57.     # Start destructor user section
  58.     # End destructor user section
  59.     $this FileHandler::destructor
  60. }
  61.  
  62.  
  63. # Returns a list with special file names for Smalltalk: the import
  64. # and the export file.
  65. #
  66. method STFileHandler::getSpecialFiles {this} {
  67.     set list [List new]
  68.     $list append [$this getImportFileName]
  69.     $list append [$this getExportFileName]
  70.     return $list
  71. }
  72.  
  73.  
  74. # Returns a list with Smalltalk file types: stType.
  75. #
  76. method STFileHandler::getFileTypes {this} {
  77.     set list [List new]
  78.     $list append [$this stType]
  79.     return $list
  80. }
  81.  
  82.  
  83. # Returns the file name for the file with the import script.
  84. #
  85. method STFileHandler::getImportFileName {this} {
  86.     return "vwimport.[$this stType]"
  87.  
  88. }
  89.  
  90.  
  91. # Returns the file name for the file with the export script.
  92. #
  93. method STFileHandler::getExportFileName {this} {
  94.     return "vwexport.[$this stType]"
  95. }
  96.  
  97.  
  98. # Source u_genst.tcl if it exists.
  99. # Call FileHandler::sourceTclFiles.
  100. #
  101. method STFileHandler::sourceTclFiles {this} {
  102.     set cc [ClientContext::global]
  103.  
  104.     if {[$cc customFileExists u_genst tcl "" 0]} {
  105.         require u_genst.tcl
  106.     }
  107.  
  108.     $this FileHandler::sourceTclFiles
  109. }
  110.  
  111. # Do not delete this line -- regeneration end marker
  112.  
  113. #---------------------------------------------------------------------------
  114. #      File:           @(#)stregenera.tcl    /main/titanic/6
  115. #---------------------------------------------------------------------------
  116.  
  117. # Start user added include file section
  118. # End user added include file section
  119.  
  120. require "regenerato.tcl"
  121.  
  122.  
  123. Class STRegenerator : {Regenerator} {
  124.     constructor
  125.     method destructor
  126.     method regenerate
  127.     method countExclamationMarks
  128.     method isCategoryHeader
  129.     method processCategoryHeader
  130.     method processMethod
  131.     method getLine
  132.     method isCommentLine
  133.     method parseInitialize
  134.     method parseFile
  135.  
  136.     # Current parsing state, one of initial, inCategory, 
  137.     # inMethod, inMethodBody, skippingGeneratedMethod.
  138.     #
  139.     attribute state
  140.  
  141.     # Indicates whether the last line that was read
  142.     # started in a single quote delimited string.
  143.     #
  144.     attribute startInSingleQuote
  145.  
  146.     # Indicates whether the last line that was read 
  147.     # ended in a single quote delimited string.
  148.     #
  149.     attribute endInSingleQuote
  150.  
  151.     # Indicates whether the last line that was read
  152.     # started in a double quote delimited string.
  153.     #
  154.     attribute startInDoubleQuote
  155.  
  156.     # Indicates whether the last line that was read
  157.     # ended in a double quote delimited string.
  158.     #
  159.     attribute endInDoubleQuote
  160.  
  161.     # Name of the class currently in regeneration.
  162.     #
  163.     attribute currentClassName
  164.  
  165.     # Name of the class implementation
  166.     # currently in regeneration.
  167.     #
  168.     attribute currentClassImplementation
  169.  
  170.     # Category Type currently in regeneration:
  171.     # Class or Instance.
  172.     #
  173.     attribute currentCategoryType
  174.  
  175.     # parsed comment of current method
  176.     #
  177.     attribute methodComment
  178. }
  179.  
  180. constructor STRegenerator {class this} {
  181.     set this [Regenerator::constructor $class $this]
  182.     # Start constructor user section
  183.     # End constructor user section
  184.     return $this
  185. }
  186.  
  187. method STRegenerator::destructor {this} {
  188.     # Start destructor user section
  189.     # End destructor user section
  190.     $this Regenerator::destructor
  191. }
  192.  
  193.  
  194. # Regeneration entry point.
  195. #
  196. method STRegenerator::regenerate {this class fileObject} {
  197.     set fileHandler [STFileHandler new]
  198.     $this fileObject $fileObject
  199.     $this fileDesc [$fileHandler openFile $class [$fileHandler stType]]
  200.     if { [$this fileDesc] != "" } {
  201.         $this parseFile
  202.         $fileHandler closeFile [$this fileDesc]
  203.     }
  204. }
  205.  
  206.  
  207. # Count the exclamation marks in <line>, from right to left.
  208. # Returns 0 when the line ends in a string.
  209. # Stops counting when a character other than <space> or
  210. # ! is encountered. Returns the count and
  211. # strips the found exclamation marks
  212. # from <line>.
  213. #
  214. method STRegenerator::countExclamationMarks {this line} {
  215.     upvar $line l
  216.     if { (![regexp {!} $l]) || [$this endInDoubleQuote] || \
  217.              [$this endInSingleQuote] } {
  218.         return 0
  219.     }
  220.     set l [string trimright $l]
  221.     set index [expr [string length $l]-1]
  222.     set count 0
  223.     while { ($index >= 0) && ([regexp {[! ]} [string index $l $index] ch]) } {
  224.         set index [expr $index-1]
  225.         if { $ch == "!" } {
  226.             set count [expr $count+1]
  227.         }
  228.     }
  229.     set l [string range $l 0 $index]
  230.     return $count
  231. }
  232.  
  233.  
  234. # Returns whether <line> contains a category header.
  235. #
  236. method STRegenerator::isCategoryHeader {this line} {
  237.     if { [string first methodsFor $line] != -1 } {
  238.         return 1
  239.     } 
  240.     if { [string first publicMethodsFor $line] != -1 } {
  241.         return 1
  242.     } 
  243.     if { [string first privateMethodsFor $line] != -1 } {
  244.         return 1
  245.     } 
  246.     if { [string first protectedMethodsFor $line] != -1 } {
  247.         return 1
  248.     } 
  249.     return 0
  250. }
  251.  
  252.  
  253. # Processes <line> (which is a category header).
  254. # Sets currentClassName, currentCategoryType
  255. # and currentClassImplementation.
  256. #
  257. method STRegenerator::processCategoryHeader {this line} {
  258.     regsub -all "!" $line "" tokenList
  259.     if { [llength $tokenList] < 3 } { 
  260.         m4_error $EST_BADCATHEAD [$this currentClassName]
  261.     return
  262.     }
  263.     $this currentClassName [lindex $tokenList 0]
  264.     
  265.     if { [lindex $tokenList 1] == "class" } {
  266.         $this currentCategoryType "Class"
  267.     } else {
  268.         $this currentCategoryType "Instance"
  269.     }
  270.     $this currentClassImplementation [[$this fileObject] getImplementation \
  271.                                           [$this currentClassName]]
  272.     # if this class implemenentation has no super class then it is generated
  273.     if {[[$this currentClassImplementation] super] == "" } {
  274.         m4_warning $WST_OBSOLMETHOD [$this currentClassName]
  275.         [$this currentClassImplementation] super \
  276.             "ObsoleteClass[cap [$this currentClassName]]"        
  277.     }
  278. }
  279.  
  280.  
  281. # Processes the method found with
  282. # header <header>, temporaries <temporaries> and
  283. # body <expression>:
  284. # Determines selector and arguments, gets a
  285. # method implementation, warns if the method
  286. # is obsolete.
  287. # Adds temporaries, removes code before
  288. # user code marker if it exists and the marker itself.
  289. # Adds the user added code as one expression.
  290. #
  291. method STRegenerator::processMethod {this header temporaries expression} {
  292.     set obsolete 0
  293.     set selector ""
  294.     set isArgument 0
  295.     set arguments [List new]
  296.     foreach part $header {
  297.         if { !$isArgument } {
  298.             set selector "$selector$part"
  299.             set isArgument 1
  300.         } else {
  301.             $arguments append $part
  302.             set isArgument 0
  303.         }
  304.     }
  305.  
  306.     # do workaround for - as method name: - as parameter is not allowed in tcl
  307.     if { $selector == "-" } {
  308.         set selector "operator-"
  309.     }
  310.  
  311.     set impl [[$this currentClassImplementation] \
  312.                   get[$this currentCategoryType]MethodImplementation \
  313.                   $selector ""]
  314.  
  315.     if { $impl == "" } {
  316.         m4_warning $WST_OBSOLMETHODCLASS $selector [$this currentClassName]
  317.         set impl [[$this currentClassImplementation] \
  318.                       get[$this currentCategoryType]MethodImplementation \
  319.                       $selector obsolete]
  320.         # for obsolete methods we need to insert the argument names
  321.         $arguments foreach argument {
  322.             $impl addArgument $argument
  323.         }
  324.         if {[$impl comment] == "" } {
  325.             if {$expression == "" } {
  326.                 set expression [$this methodComment]
  327.             } else {
  328.                 regsub -all {["']} [$this methodComment] "" cmline
  329.                 #"]]
  330.                 $impl comment $cmline
  331.             }
  332.         }
  333.         $impl hasUserCodePart 1
  334.     }
  335.     $this methodComment ""
  336.     
  337.     # do temporaries
  338.     if { $temporaries != "" } {
  339.         regsub -all {\|} [string trim $temporaries] "" tempList
  340.         foreach temporary $tempList {
  341.             $impl addTemporary $temporary
  342.         }
  343.     }
  344.  
  345.     # delete code before user code marker from expression
  346.     set userMarkerIndex [string first [$globals startUserCodeMarker] $expression]
  347.     if { $userMarkerIndex != -1 } {
  348.         set restIndex [expr $userMarkerIndex+\
  349.                            [string length [$globals startUserCodeMarker]]+1]
  350.         set expression [string range $expression $restIndex end]
  351.     }
  352.     if {$obsolete} {
  353.         set expresion "obsolete code:\n$expresion"
  354.     }
  355.     if { $expression != "" } {
  356.         $impl addExpression $expression
  357.         $impl hasUserCode 1
  358.     }
  359. }
  360.  
  361.  
  362. # Reads <line> from file with descriptor fileDesc,
  363. # returns 0 if end of file.
  364. # Updates the start/end in single/double quote
  365. # attributes based on the contents of
  366. # <line>.
  367. #
  368. method STRegenerator::getLine {this line} {
  369.     upvar $line l
  370.     set l [gets [$this fileDesc]]
  371.     if [eof [$this fileDesc]] {
  372.         return 0
  373.     }
  374.  
  375.     # update count stuff
  376.     $this startInSingleQuote [$this endInDoubleQuote]
  377.     $this startInDoubleQuote [$this endInDoubleQuote]
  378.     # get only the 's and "'s
  379.     regsub -all {[^"']} $l "" newLine         
  380.     #"
  381.     
  382.     foreach char [split $newLine {}] {
  383.         if { $char == "\"" } {
  384.             if { ![$this endInSingleQuote] } {
  385.                 $this endInDoubleQuote [expr 1-[$this endInDoubleQuote]]
  386.             }
  387.         } else {
  388.             if { ![$this endInDoubleQuote] } {
  389.                 $this endInSingleQuote [expr 1-[$this endInSingleQuote]]
  390.             }
  391.         }
  392.     }
  393.     return 1
  394. }
  395.  
  396.  
  397. # Returns whether <line> is a comment line.
  398. #
  399. method STRegenerator::isCommentLine {this line} {
  400.     if { [$this startInDoubleQuote] || [$this endInDoubleQuote] } {
  401.         return 1
  402.     }
  403.     if { [string index [string trim $line] 0] == "\"" } {
  404.         return 1
  405.     }
  406.     return 0
  407. }
  408.  
  409.  
  410. # Initializes the parse variables.
  411. #
  412. method STRegenerator::parseInitialize {this} {
  413.     $this startInSingleQuote 0
  414.     $this endInSingleQuote 0
  415.     $this startInDoubleQuote 0
  416.     $this endInDoubleQuote 0
  417.     $this state initial
  418.     $this methodComment ""
  419. }
  420.  
  421.  
  422. # This method is the parser. Parses the file
  423. # and adds regenerated method bodies.
  424. #
  425. method STRegenerator::parseFile {this} {
  426.     $this parseInitialize 
  427.  
  428.     set line ""
  429.     while { [$this getLine line] } {
  430.         case [$this state] in {
  431.             {initial} {
  432.                 if [$this isCategoryHeader $line] {
  433.                     $this processCategoryHeader $line
  434.                     $this state inCategory
  435.                     $this methodComment ""
  436.                 }
  437.             }
  438.             {inCategory} {
  439.                 if { ([string trim $line] != "" ) && \
  440.                          (![$this isCommentLine $line]) } {
  441.                     set count [$this countExclamationMarks line]
  442.                     if $count {
  443.                         $this state initial
  444.                     } else {
  445.                         $this state inMethod
  446.                         set methodHeader $line
  447.                         set expression ""
  448.                         set temporaries ""
  449.                         $this methodComment ""
  450.                     }
  451.                 }
  452.             }
  453.             {inMethod} {
  454.                 set count [$this countExclamationMarks line]
  455.                 if { [string trim $line] == "\"Generated\"" } {
  456.                     $this state skippingGeneratedMethod
  457.                     $this methodComment ""
  458.                     continue
  459.                 }
  460.                 if { ([string trim $line] != "" ) && \
  461.                          (![$this isCommentLine $line]) } {
  462.                     if { [string index [string trim $line] 0] == "|" } {
  463.                         set temporaries [string trim $line]
  464.                     } else {
  465.                         set expression $line
  466.                     }
  467.                     
  468.                     $this state inMethodBody
  469.                 }
  470.                 if $count {
  471.                     $this processMethod $methodHeader $temporaries $expression
  472.                     $this methodComment ""
  473.                     if { $count == 1 } {
  474.                         $this state inCategory
  475.                     } else {
  476.                         $this state initial
  477.                     }
  478.                 }
  479.                 if {[$this isCommentLine $line]} {
  480.                     set cmline $line
  481.                     set cmline [string trim $cmline]
  482.                     if {$cmline != ""} {
  483.                         if {[$this methodComment] != ""} {
  484.                             $this methodComment "[$this methodComment]\n$cmline"
  485.                         } else {
  486.                             $this methodComment "$cmline"
  487.                         }
  488.                     }
  489.                 }
  490.             }
  491.             {inMethodBody} {
  492.                 set count [$this countExclamationMarks line]
  493.                 if { $expression != "" } {
  494.                     set expression "$expression\n$line"
  495.                 } else {
  496.                     set expression $line
  497.                 }
  498.                 if $count {
  499.                     $this processMethod $methodHeader $temporaries $expression
  500.                     $this methodComment ""
  501.                     if { $count == 1 } {
  502.                         $this state inCategory
  503.                     } else {
  504.                         $this state initial
  505.                     }
  506.                 }
  507.             }
  508.             {skippingGeneratedMethod} {
  509.                 set count [$this countExclamationMarks line]
  510.                 if $count {
  511.                     if { $count == 1 } {
  512.                         $this state inCategory
  513.                     } else {
  514.                         $this state initial
  515.                     }
  516.                 }
  517.             }
  518.         }
  519.     }    
  520. }
  521.  
  522. # Do not delete this line -- regeneration end marker
  523.  
  524. #---------------------------------------------------------------------------
  525. #      File:           @(#)stgglobal.tcl    /main/titanic/10
  526. #---------------------------------------------------------------------------
  527.  
  528. # Start user added include file section
  529. global globals
  530. # End user added include file section
  531.  
  532.  
  533.  
  534. Class STGGlobal : {GCObject} {
  535.     method destructor
  536.     constructor
  537.     method setGeneratePrint
  538.     method setDefaultCategory
  539.     method setUserCodeMarker
  540.     method setErrorDictionary
  541.     method setGeneratedMethodMarker
  542.  
  543.     # Maps the error codes to error messages.
  544.     #
  545.     attribute errorDictionary
  546.  
  547.     # Indicates whether print methods must be generated.
  548.     #
  549.     attribute generatePrint
  550.  
  551.     # Default category naming: based on system or diagram names.
  552.     #
  553.     attribute defaultCategory
  554.  
  555.     # The marker for user added code.
  556.     #
  557.     attribute startUserCodeMarker
  558.  
  559.     # The marker for generated methods.
  560.     #
  561.     attribute generatedMethodMarker
  562. }
  563.  
  564. method STGGlobal::destructor {this} {
  565.     # Start destructor user section
  566.     # End destructor user section
  567. }
  568.  
  569.  
  570. # Set all the instance variables by calling their set methods.
  571. #
  572. constructor STGGlobal {class this} {
  573.     set this [GCObject::constructor $class $this]
  574.     $this setGeneratePrint
  575.     $this setDefaultCategory    
  576.     $this setUserCodeMarker
  577.     $this errorDictionary [Dictionary new]
  578.     $this setErrorDictionary
  579.     return $this
  580. }
  581.  
  582. proc STGGlobal::getGeneratePrint {} {
  583.     set cc [ClientContext::global]
  584.     set cs [$cc currentSystem]
  585.     if {$cs == ""} {
  586.         return 0
  587.     }
  588.     set generatePrint [$cs getPropertyValue st_generate_print]
  589.     if { [string tolower $generatePrint] == "on" } {
  590.         set generatePrint 1
  591.     } elseif { [string tolower $generatePrint] == "off" } {
  592.         set generatePrint 0
  593.     } elseif { $generatePrint == "0" } {
  594.         set generatePrint 0
  595.     } elseif { $generatePrint == "1" } {
  596.         set generatePrint 1
  597.     } else {
  598.         set generatePrint 0
  599.     }
  600.     return $generatePrint
  601. }
  602.  
  603. proc STGGlobal::setGeneratePrintProp {value} {
  604.     # this can also be done using the property box
  605.     # of the systemVersion.
  606.     if { $value == "0" } {
  607.         set generatePrint 0
  608.     } else {
  609.         set generatePrint 1
  610.     }
  611.     set cc [ClientContext::global]
  612.     set cs [$cc currentSystem]
  613.     if {$cs == ""} {
  614.         return
  615.     }
  616.     $cs setProperty st_generate_print $generatePrint
  617. }
  618.  
  619. # Sets generatePrint according to M4_st_generate_print.
  620. # Default is 0.
  621. #
  622. method STGGlobal::setGeneratePrint {this} {
  623.     $this generatePrint [STGGlobal::getGeneratePrint]
  624. }
  625.  
  626. proc STGGlobal::getDefaultCategory {} {
  627.     set cc [ClientContext::global]
  628.     set cs [$cc currentSystem]
  629.     if {$cs == ""} {
  630.         return "System"
  631.     }
  632.     set defaultCategory [$cs getPropertyValue st_default_category]
  633.     if { [regexp -nocase "diagram" value] } {
  634.         set defaultCategory "Diagram"
  635.     } else {
  636.         set defaultCategory "System"
  637.     }
  638.     return $defaultCategory
  639. }
  640.  
  641. proc STGGlobal::setDefaultCategoryProp {value} {
  642.     # this can also be done using the property box
  643.     # of the systemVersion.
  644.     if { [regexp -nocase "system" $value] } {
  645.         set defcat "SystemName"
  646.     } else {
  647.         set defcat "DiagramName"
  648.     }
  649.     set cc [ClientContext::global]
  650.     set cs [$cc currentSystem]
  651.     if {$cs == ""} {
  652.         return
  653.     }
  654.     $cs setProperty st_default_category $defcat
  655. }
  656.  
  657. # Sets defaultCategory according to M4_st_default_category.
  658. # Default is System.
  659. #
  660. method STGGlobal::setDefaultCategory {this} {
  661.     $this defaultCategory [STGGlobal::getDefaultCategory]
  662. }
  663.  
  664.  
  665. # Sets startUserCodeMarker.
  666. #
  667. method STGGlobal::setUserCodeMarker {this} {
  668.     $this startUserCodeMarker "\"Start user added code\""
  669. }
  670.  
  671.  
  672. # Sets errorDictionary with error codes as keys
  673. # and error messages as values.
  674. #
  675. method STGGlobal::setErrorDictionary {this} {
  676.     [$this errorDictionary] set PARAMETER_NIL "Parameter nil for mandatory association"
  677.     [$this errorDictionary] set ASSOC_OBJ_NOT_FOUND "Associated object not found"
  678.     [$this errorDictionary] set QUAL_NOT_FOUND "Qualifier not found"
  679.     [$this errorDictionary] set CONSTRAINT "Constraint violation"
  680.     [$this errorDictionary] set CANNOT_RELEASE "Cannot release"
  681. }
  682.  
  683.  
  684. # Sets generatedMethodMarker.
  685. #
  686. method STGGlobal::setGeneratedMethodMarker {this} {
  687.     $this generatedMethodMarker "\"Generated\""
  688. }
  689.  
  690. # Do not delete this line -- regeneration end marker
  691.  
  692. #---------------------------------------------------------------------------
  693. #      File:           @(#)stgenerato.tcl    /main/titanic/4
  694. #---------------------------------------------------------------------------
  695.  
  696. # Start user added include file section
  697.  
  698.  
  699. set globals [STGGlobal new]
  700.  
  701. # End user added include file section
  702.  
  703. require "generator.tcl"
  704.  
  705.  
  706. Class STGenerator : {Generator} {
  707.     constructor
  708.     method destructor
  709.     method generate
  710.     method check
  711.     method generateSpecialFiles
  712.     method sortClasses
  713.     method generateImport
  714.     method generateExport
  715.  
  716.     # The file handler for this generator.
  717.     #
  718.     attribute fileHandler
  719. }
  720.  
  721. constructor STGenerator {class this} {
  722.     set this [Generator::constructor $class $this]
  723.     # Start constructor user section
  724.     $this fileHandler [STFileHandler new]
  725.     # End constructor user section
  726.     return $this
  727. }
  728.  
  729. method STGenerator::destructor {this} {
  730.     # Start destructor user section
  731.     # End destructor user section
  732.     $this Generator::destructor
  733. }
  734.  
  735.  
  736. # Generates for <classList>, see description in class Generator.
  737. #
  738. method STGenerator::generate {this classList} {
  739.     # set header variables
  740.     set cc [ClientContext::global]
  741.     set proj [$cc currentProject]
  742.     set configV [$cc currentConfig]
  743.     set phaseV [$cc currentPhase]
  744.     set systemV [$cc currentSystem]
  745.     if {![$proj isNil] } {
  746.         set projName [$proj name]
  747.     }
  748.     if {![$configV isNil] } {
  749.         set configName [[$configV config] name]
  750.     }
  751.     if {![$phaseV isNil] } {
  752.         set phaseName [[$phaseV phase] name]
  753.     }
  754.     if {![$systemV isNil] } {
  755.         set systemName [[$systemV system] name]
  756.     }
  757.     
  758.     # initialize file handler, type and result variables
  759.     set type [[$this fileHandler] stType]
  760.     set typeToClassDictionary [Dictionary new]
  761.     set classToSection [Dictionary new]
  762.     $typeToClassDictionary set [[$this fileHandler] stType] $classToSection
  763.     set regenerator [STRegenerator new]
  764.     
  765.     # start generation
  766.     $classList foreach class {
  767.         set tmpErrors 0
  768.         set tmpErrors [$class check]
  769.         if {$tmpErrors == 0} {
  770.             # errorfree so generate
  771.             set fileObject [STFile new]
  772.             set implementation [$fileObject getImplementation \
  773.                                     [$class getSTName]]
  774.             $class generate $implementation
  775.         
  776.             # do regeneration
  777.             $regenerator regenerate $class $fileObject
  778.             
  779.             set text [TextSection new]
  780.         
  781.             # do header 
  782.             set fileName [[$this fileHandler] getFileName $class $type]
  783.             expandHeaderIntoSection $fileName $type $text
  784.             
  785.             
  786.             $fileObject generate $text
  787.         
  788.             $classToSection set $class $text
  789.         } else {
  790.             # puts "not generating due to errors ($tmpErrors)"
  791.         }
  792.     }
  793.     return $typeToClassDictionary
  794. }
  795.  
  796. method STGenerator::check {this classList} {
  797.     set errornr 0
  798.     # set header variables
  799.     set cc [ClientContext::global]
  800.     set proj [$cc currentProject]
  801.     set configV [$cc currentConfig]
  802.     set phaseV [$cc currentPhase]
  803.     set systemV [$cc currentSystem]
  804.     if {![$proj isNil] } {
  805.         set projName [$proj name]
  806.     }
  807.     if {![$configV isNil] } {
  808.         set configName [[$configV config] name]
  809.     }
  810.     if {![$phaseV isNil] } {
  811.         set phaseName [[$phaseV phase] name]
  812.     }
  813.     if {![$systemV isNil] } {
  814.         set systemName [[$systemV system] name]
  815.     }
  816.     # start checking
  817.     $classList foreach class {
  818.         # puts " Language dependence checking for class: [$class getName]"
  819.         if {![$class isExternal]} {
  820.             set tmpError [$class check]
  821.         } else {
  822.             m4_message $MST_NOCHKEXTCLS [$class getName]
  823.         }
  824.         incr errornr $tmpError
  825.         # puts " number of returned errors: $tmpError"
  826.     }
  827.     return $errornr
  828. }
  829.  
  830.  
  831. # Generates special files: the import and/or
  832. # the export file.
  833. # Makes a mapping from class to fileName
  834. # and from class to super class and
  835. # generates the file specified in <fileList>.
  836. #
  837. method STGenerator::generateSpecialFiles {this ooplModel fileList} {
  838.     set classList [List new]
  839.     set classToSuper [Dictionary new]
  840.     set classToFile [Dictionary new]
  841.     
  842.     foreach class [$ooplModel ooplClassSet] {
  843.         if [$class isExternal] {
  844.             continue
  845.         }
  846.         set className [$class getSTName]
  847.         $classList append $className
  848.         
  849.         # get superclass
  850.         set gnodeSet [$class genNodeSet]
  851.         
  852.         if { [llength $gnodeSet] == 0 } {
  853.             $classToSuper set $className "Object"
  854.         } else {
  855.             $classToSuper set $className [[[lindex $gnodeSet 0] superClass] getSTName]
  856.         }
  857.         
  858.         $classToFile set $className [[$this fileHandler] getFileName $class [[$this fileHandler] stType]]
  859.     }
  860.     
  861.     $fileList foreach specialFile {
  862.         if { [[$this fileHandler] getImportFileName] == $specialFile } {
  863.             m4_message $MST_GENIMPSCRPTS
  864.             $this generateImport $classList $classToSuper $classToFile
  865.         }
  866.         if { [[$this fileHandler] getExportFileName] == $specialFile } {
  867.             m4_message $MST_GENEXPSCRPTS
  868.             $this generateExport $classList $classToFile
  869.         }
  870.     }
  871. }
  872.  
  873.  
  874. # Sorts the classes in <classList> in 
  875. # prefix order. <classToSuper> maps classes to
  876. # their super classes and <classToFile> maps
  877. # classes to file names, these are used during
  878. # the sort process. 
  879. #
  880. method STGenerator::sortClasses {this classList classToSuper classToFile} {
  881.     upvar $classList selectedClasses
  882.     # make class to subs and root classes
  883.     set rootClasses [List new]
  884.     set classToSubs [Dictionary new]
  885.     $classToSuper foreach className superName {
  886.         if { ![$classToSubs exists $superName] } {
  887.             $classToSubs set $superName [List new]
  888.         }
  889.         if { [[$classToSubs set $superName] search $className] == -1 } {
  890.             # if super does not have a file it must be external and thus a root class
  891.             if { ![$classToFile exists $superName] } {
  892.                 # now get the subclass of the external root class
  893.                 if { [$rootClasses search $className] == -1 } {
  894.                     $rootClasses append $className
  895.                 }
  896.             }
  897.             [$classToSubs set $superName] append $className
  898.         }
  899.     } 
  900.     # little hack: when an class <Object> was present, 
  901.     # an empty import-file was created. This is corrected
  902.     # by setting rootClasses:
  903.     if { [$rootClasses empty] } {
  904.         $rootClasses append "Object"
  905.     }
  906.     # walk the inheritance tree till the leaves and append every selected class visited
  907.     # yielding the classes in prefix order in newSelectedClasses
  908.     set newSelectedClasses [List new]
  909.     while { ![$rootClasses empty] } {
  910.         set currentClass [$rootClasses index 0]
  911.         if { [$selectedClasses search $currentClass] != -1 } { 
  912.             $newSelectedClasses append $currentClass
  913.         }
  914.         if [$classToSubs exists $currentClass] {
  915.             [$classToSubs set $currentClass] foreach subClass {
  916.                 if { [$rootClasses search $subClass] == -1 } {
  917.                     $rootClasses append $subClass
  918.                 }
  919.             }
  920.         }
  921.         $rootClasses removeValue $currentClass
  922.     }
  923.     set selectedClasses $newSelectedClasses
  924. }
  925.  
  926.  
  927. # Generates the import file: sorts the
  928. # classes in <classList> , creates a section with 
  929. # Smalltalk expression to file in these
  930. # classes and writes the import file.
  931. #
  932. method STGenerator::generateImport {this classList classToSuper classToFile} {
  933.     set importSection [TextSection new]
  934.     set clientContext [ClientContext::global]
  935.     set pathName [[$clientContext currentSystem] path]
  936.     
  937.     $this sortClasses classList $classToSuper $classToFile
  938.     $classList foreach className {
  939.         set fileName [path_name concat $pathName [$classToFile set $className]]
  940.         $importSection append "(Filename named: \'$fileName\') fileIn!\n"
  941.     }
  942.     set fileName [[$this fileHandler] getImportFileName]
  943.     [$this fileHandler] writeSectionToNamedFile $importSection $fileName
  944. }
  945.  
  946.  
  947. # Generates the export file: creates a section
  948. # with Smalltalk expressions to file out
  949. # the classes in <classList> and writes
  950. # the export file.
  951. #
  952. method STGenerator::generateExport {this classList classToFile} {
  953.     set exportSection [TextSection new]
  954.     set clientContext [ClientContext::global]
  955.     set pathName [[$clientContext currentSystem] path]
  956.     
  957.     $classList foreach className {
  958.         set fileName [path_name concat $pathName [$classToFile set $className]]
  959.         $exportSection append "(Filename named: \'$fileName\') fileOutChangesFor: $className!\n"
  960.     }
  961.     set fileName [[$this fileHandler] getExportFileName]
  962.     [$this fileHandler] writeSectionToNamedFile $exportSection $fileName
  963. }
  964.  
  965. # Do not delete this line -- regeneration end marker
  966.  
  967.