Class.st
changeset 5801 3ae2f700ed6e
parent 5800 a4386f928cf0
child 5849 4cc89ecfbbda
equal deleted inserted replaced
5800:a4386f928cf0 5801:3ae2f700ed6e
     1 "
     1 "
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     2  COPYRIGHT (c) 1989 by Claus Gittinger
     3 	       All Rights Reserved
     3                All Rights Reserved
     4 
     4 
     5  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
    11 "
    11 "
    12 
    12 
    13 "{ Package: 'stx:libbasic' }"
    13 "{ Package: 'stx:libbasic' }"
    14 
    14 
    15 ClassDescription subclass:#Class
    15 ClassDescription subclass:#Class
    16 	instanceVariableNames:'name category classvars comment subclasses classFilename package
    16         instanceVariableNames:'name category classvars comment subclasses classFilename package
    17 		revision primitiveSpec environment signature hook'
    17                 revision primitiveSpec environment signature hook'
    18 	classVariableNames:''
    18         classVariableNames:''
    19 	poolDictionaries:''
    19         poolDictionaries:''
    20 	category:'Kernel-Classes'
    20         category:'Kernel-Classes'
    21 !
    21 !
    22 
    22 
    23 !Class class methodsFor:'documentation'!
    23 !Class class methodsFor:'documentation'!
    24 
    24 
    25 copyright
    25 copyright
    26 "
    26 "
    27  COPYRIGHT (c) 1989 by Claus Gittinger
    27  COPYRIGHT (c) 1989 by Claus Gittinger
    28 	       All Rights Reserved
    28                All Rights Reserved
    29 
    29 
    30  This software is furnished under a license and may be used
    30  This software is furnished under a license and may be used
    31  only in accordance with the terms of that license and with the
    31  only in accordance with the terms of that license and with the
    32  inclusion of the above copyright notice.   This software may not
    32  inclusion of the above copyright notice.   This software may not
    33  be provided or otherwise made available to, or used by, any
    33  be provided or otherwise made available to, or used by, any
   142 
   142 
   143     "/
   143     "/
   144     "/ mhmh - ask the default manager
   144     "/ mhmh - ask the default manager
   145     "/
   145     "/
   146     (mgr := Smalltalk at:#SourceCodeManager) notNil ifTrue:[
   146     (mgr := Smalltalk at:#SourceCodeManager) notNil ifTrue:[
   147 	info := mgr revisionInfoFromString:aString.
   147         info := mgr revisionInfoFromString:aString.
   148 	info notNil ifTrue:[
   148         info notNil ifTrue:[
   149 	    ^ info
   149             ^ info
   150 	]
   150         ]
   151     ].
   151     ].
   152 
   152 
   153     "/
   153     "/
   154     "/ fallBack - handles some RCS headers only
   154     "/ fallBack - handles some RCS headers only
   155     "/ is this really needed ?
   155     "/ is this really needed ?
   156     "/
   156     "/
   157     info := IdentityDictionary new.
   157     info := IdentityDictionary new.
   158     words := aString asCollectionOfWords.
   158     words := aString asCollectionOfWords.
   159 
   159 
   160     words notEmpty ifTrue:[
   160     words notEmpty ifTrue:[
   161 	"/
   161         "/
   162 	"/ supported formats:
   162         "/ supported formats:
   163 	"/
   163         "/
   164 	"/ $-Header: pathName rev date time user state $
   164         "/ $-Header: pathName rev date time user state $
   165 	"/ $-Revision: rev $
   165         "/ $-Revision: rev $
   166 	"/ $-Id: fileName rev date time user state $
   166         "/ $-Id: fileName rev date time user state $
   167 	"/
   167         "/
   168 
   168 
   169 	((words at:1) = '$Header:') ifTrue:[
   169         ((words at:1) = '$Header:') ifTrue:[
   170 	    nm := words at:2.
   170             nm := words at:2.
   171 	    info at:#repositoryPathName put:nm.
   171             info at:#repositoryPathName put:nm.
   172 	    (nm endsWith:',v') ifTrue:[
   172             (nm endsWith:',v') ifTrue:[
   173 		nm := nm copyWithoutLast:2
   173                 nm := nm copyWithoutLast:2
   174 	    ].
   174             ].
   175 	    info at:#fileName put:nm asFilename baseName.
   175             info at:#fileName put:nm asFilename baseName.
   176 	    words size > 2 ifTrue:[
   176             words size > 2 ifTrue:[
   177 		(words at:3) = '$' ifFalse:[
   177                 (words at:3) = '$' ifFalse:[
   178 		    info at:#revision put:(words at:3).
   178                     info at:#revision put:(words at:3).
   179 		    (words at:4) = '$' ifFalse:[
   179                     (words at:4) = '$' ifFalse:[
   180 			info at:#date put:(words at:4).
   180                         info at:#date put:(words at:4).
   181 			info at:#time put:(words at:5).
   181                         info at:#time put:(words at:5).
   182 			info at:#user put:(words at:6).
   182                         info at:#user put:(words at:6).
   183 			info at:#state put:(words at:7).
   183                         info at:#state put:(words at:7).
   184 		    ]
   184                     ]
   185 		].
   185                 ].
   186 	    ].
   186             ].
   187 	    ^ info
   187             ^ info
   188 	].
   188         ].
   189 	((words at:1) = '$Revision:') ifTrue:[
   189         ((words at:1) = '$Revision:') ifTrue:[
   190 	    info at:#revision put:(words at:2).
   190             info at:#revision put:(words at:2).
   191 	    ^ info
   191             ^ info
   192 	].
   192         ].
   193 	((words at:1) = '$Id:') ifTrue:[
   193         ((words at:1) = '$Id:') ifTrue:[
   194 	    info at:#fileName put:(words at:2).
   194             info at:#fileName put:(words at:2).
   195 	    info at:#revision put:(words at:3).
   195             info at:#revision put:(words at:3).
   196 	    info at:#date put:(words at:4).
   196             info at:#date put:(words at:4).
   197 	    info at:#time put:(words at:5).
   197             info at:#time put:(words at:5).
   198 	    info at:#user put:(words at:6).
   198             info at:#user put:(words at:6).
   199 	    info at:#state put:(words at:7).
   199             info at:#state put:(words at:7).
   200 	    ^ info
   200             ^ info
   201 	].
   201         ].
   202     ].
   202     ].
   203 
   203 
   204     ^ nil
   204     ^ nil
   205 
   205 
   206     "Created: 15.11.1995 / 14:58:35 / cg"
   206     "Created: 15.11.1995 / 14:58:35 / cg"
   214 
   214 
   215     |lines line|
   215     |lines line|
   216 
   216 
   217     lines := aMethodSourceString asCollectionOfLines.
   217     lines := aMethodSourceString asCollectionOfLines.
   218     lines do:[:l |
   218     lines do:[:l |
   219 	|i|
   219         |i|
   220 
   220 
   221 	i := l indexOfSubCollection:'$Header: '.
   221         i := l indexOfSubCollection:'$Header: '.
   222 	i ~~ 0 ifTrue:[
   222         i ~~ 0 ifTrue:[
   223 	    line := l copyFrom:i.
   223             line := l copyFrom:i.
   224 	    i := line lastIndexOf:$$.
   224             i := line lastIndexOf:$$.
   225 	    i > 1 ifTrue:[
   225             i > 1 ifTrue:[
   226 		line := line copyTo:i.
   226                 line := line copyTo:i.
   227 	    ].
   227             ].
   228 	    ^ line
   228             ^ line
   229 	]
   229         ]
   230     ].
   230     ].
   231     ^ nil
   231     ^ nil
   232 
   232 
   233     "Created: 15.10.1996 / 18:57:57 / cg"
   233     "Created: 15.10.1996 / 18:57:57 / cg"
   234     "Modified: 16.10.1996 / 16:54:40 / cg"
   234     "Modified: 16.10.1996 / 16:54:40 / cg"
   257     ^ self == Class class or:[self == Class]
   257     ^ self == Class class or:[self == Class]
   258 
   258 
   259     "Created: 15.4.1996 / 17:17:13 / cg"
   259     "Created: 15.4.1996 / 17:17:13 / cg"
   260     "Modified: 23.4.1996 / 15:56:58 / cg"
   260     "Modified: 23.4.1996 / 15:56:58 / cg"
   261 ! !
   261 ! !
   262 
       
   263 
   262 
   264 !Class methodsFor:'Compatibility - ST80'!
   263 !Class methodsFor:'Compatibility - ST80'!
   265 
   264 
   266 fileOutSourceOn:aStream
   265 fileOutSourceOn:aStream
   267     self fileOutOn:aStream withTimeStamp:false
   266     self fileOutOn:aStream withTimeStamp:false
   580 
   579 
   581     "the comment is either a string, or an integer specifying the
   580     "the comment is either a string, or an integer specifying the
   582      position within the classes sourcefile ...
   581      position within the classes sourcefile ...
   583     "
   582     "
   584     comment isNumber ifTrue:[
   583     comment isNumber ifTrue:[
   585 	classFilename notNil ifTrue:[
   584         classFilename notNil ifTrue:[
   586 	    stream := self sourceStream. 
   585             stream := self sourceStream. 
   587 	    stream notNil ifTrue:[
   586             stream notNil ifTrue:[
   588 		stream position:comment.
   587                 stream position:comment.
   589 		string := String readFrom:stream onError:''.
   588                 string := String readFrom:stream onError:''.
   590 		stream close.
   589                 stream close.
   591 		^ string
   590                 ^ string
   592 	    ].
   591             ].
   593 	    ^ nil
   592             ^ nil
   594 	]
   593         ]
   595     ].
   594     ].
   596     ^ comment
   595     ^ comment
   597 
   596 
   598     "
   597     "
   599      Object comment 
   598      Object comment 
   650     "/ due to the implementation, extract this from my name
   649     "/ due to the implementation, extract this from my name
   651     "/ (physically, all classes are found in Smalltalk)
   650     "/ (physically, all classes are found in Smalltalk)
   652 
   651 
   653     idx := name lastIndexOf:$:.
   652     idx := name lastIndexOf:$:.
   654     idx ~~ 0 ifTrue:[
   653     idx ~~ 0 ifTrue:[
   655 	(name at:idx-1) == $: ifTrue:[
   654         (name at:idx-1) == $: ifTrue:[
   656 	    nsName := name copyTo:(idx - 2).
   655             nsName := name copyTo:(idx - 2).
   657 	    environment := Smalltalk at:nsName asSymbol.
   656             environment := Smalltalk at:nsName asSymbol.
   658 	]
   657         ]
   659     ].
   658     ].
   660     ^ environment
   659     ^ environment
   661 
   660 
   662     "Modified: / 20.7.1998 / 14:21:36 / cg"
   661     "Modified: / 20.7.1998 / 14:21:36 / cg"
   663 !
   662 !
   832 
   831 
   833     |nmSym|
   832     |nmSym|
   834 
   833 
   835     nmSym := (self name , '::' , aClassNameStringOrSymbol) asSymbolIfInterned.
   834     nmSym := (self name , '::' , aClassNameStringOrSymbol) asSymbolIfInterned.
   836     nmSym isNil ifTrue:[
   835     nmSym isNil ifTrue:[
   837 	"/ no such symbol - there cannot be a corresponding private class
   836         "/ no such symbol - there cannot be a corresponding private class
   838 	^ nil
   837         ^ nil
   839     ].
   838     ].
   840 
   839 
   841     ^ Smalltalk at:nmSym.
   840     ^ Smalltalk at:nmSym.
   842 
   841 
   843     "Modified: 26.6.1997 / 11:44:04 / cg"
   842     "Modified: 26.6.1997 / 11:44:04 / cg"
  1002 
  1001 
  1003     |cat|
  1002     |cat|
  1004 
  1003 
  1005     comment := com.
  1004     comment := com.
  1006     categoryStringOrSymbol isNil ifTrue:[
  1005     categoryStringOrSymbol isNil ifTrue:[
  1007 	cat := ''
  1006         cat := ''
  1008     ] ifFalse:[
  1007     ] ifFalse:[
  1009 	cat := categoryStringOrSymbol
  1008         cat := categoryStringOrSymbol
  1010     ].
  1009     ].
  1011     category := cat asSymbol
  1010     category := cat asSymbol
  1012 !
  1011 !
  1013 
  1012 
  1014 setEnvironment:aNamespace
  1013 setEnvironment:aNamespace
  1057     aStream := WriteStream on:code.
  1056     aStream := WriteStream on:code.
  1058     self fileOutOn:aStream
  1057     self fileOutOn:aStream
  1059 "
  1058 "
  1060     aStream := FileStream newFileNamed:'__temp'.
  1059     aStream := FileStream newFileNamed:'__temp'.
  1061     aStream isNil ifTrue:[
  1060     aStream isNil ifTrue:[
  1062 	self notify:'cannot create temporary file.'.
  1061         self notify:'cannot create temporary file.'.
  1063 	^ nil
  1062         ^ nil
  1064     ].
  1063     ].
  1065     FileOutErrorSignal handle:[:ex |
  1064     FileOutErrorSignal handle:[:ex |
  1066 	aStream nextPutAll:'"no source available"'.
  1065         aStream nextPutAll:'"no source available"'.
  1067     ] do:[
  1066     ] do:[
  1068 	self fileOutOn:aStream.
  1067         self fileOutOn:aStream.
  1069     ].
  1068     ].
  1070     aStream close.
  1069     aStream close.
  1071     aStream := FileStream oldFileNamed:'__temp'.
  1070     aStream := FileStream oldFileNamed:'__temp'.
  1072     aStream isNil ifTrue:[
  1071     aStream isNil ifTrue:[
  1073 	self notify:'oops - cannot reopen temp file'.
  1072         self notify:'oops - cannot reopen temp file'.
  1074 	^ nil
  1073         ^ nil
  1075     ].
  1074     ].
  1076     code := aStream contents.
  1075     code := aStream contents.
  1077     aStream close.
  1076     aStream close.
  1078     OperatingSystem removeFile:'__temp'.
  1077     OperatingSystem removeFile:'__temp'.
  1079     ^ code
  1078     ^ code
  1176 !Class methodsFor:'binary storage'!
  1175 !Class methodsFor:'binary storage'!
  1177 
  1176 
  1178 addGlobalsForBinaryStorageTo:globalDictionary
  1177 addGlobalsForBinaryStorageTo:globalDictionary
  1179 "
  1178 "
  1180     classPool == nil ifFalse: [
  1179     classPool == nil ifFalse: [
  1181 	classPool associationsDo: [:assoc|
  1180         classPool associationsDo: [:assoc|
  1182 	    globalDictionary at: assoc put: self
  1181             globalDictionary at: assoc put: self
  1183 	]
  1182         ]
  1184     ]
  1183     ]
  1185 "
  1184 "
  1186 
  1185 
  1187     "Created: 21.3.1997 / 15:40:45 / cg"
  1186     "Created: 21.3.1997 / 15:40:45 / cg"
  1188 !
  1187 !
  1527      output the instance variable name string
  1526      output the instance variable name string
  1528     "
  1527     "
  1529     varnames := self allInstVarNames.
  1528     varnames := self allInstVarNames.
  1530     n := varnames size.
  1529     n := varnames size.
  1531     n == 0 ifTrue:[
  1530     n == 0 ifTrue:[
  1532 	sz := 0
  1531         sz := 0
  1533     ] ifFalse:[
  1532     ] ifFalse:[
  1534 	sz := varnames inject:0 into:[:sum :nm | sum + nm size].
  1533         sz := varnames inject:0 into:[:sum :nm | sum + nm size].
  1535 	sz := sz + n - 1.
  1534         sz := sz + n - 1.
  1536     ].
  1535     ].
  1537     stream nextNumber:2 put:sz.
  1536     stream nextNumber:2 put:sz.
  1538     varnames keysAndValuesDo:[:i :nm |
  1537     varnames keysAndValuesDo:[:i :nm |
  1539 	stream nextPutBytes:(nm size) from:nm startingAt:1.
  1538         stream nextPutBytes:(nm size) from:nm startingAt:1.
  1540 "/        nm do:[:c |
  1539 "/        nm do:[:c |
  1541 "/            stream nextPut:c asciiValue
  1540 "/            stream nextPut:c asciiValue
  1542 "/        ].
  1541 "/        ].
  1543 	i ~~ n ifTrue:[stream nextPut:(Character space asciiValue)]
  1542         i ~~ n ifTrue:[stream nextPut:(Character space asciiValue)]
  1544     ].
  1543     ].
  1545 
  1544 
  1546     "
  1545     "
  1547      output my name
  1546      output my name
  1548     "
  1547     "
  2027     "a helper for fileOutDefinition"
  2026     "a helper for fileOutDefinition"
  2028 
  2027 
  2029     |isVar s|
  2028     |isVar s|
  2030 
  2029 
  2031     superclass isNil ifTrue:[
  2030     superclass isNil ifTrue:[
  2032 	isVar := self isVariable
  2031         isVar := self isVariable
  2033     ] ifFalse:[
  2032     ] ifFalse:[
  2034 	"I cant remember what this is for ?"
  2033         "I cant remember what this is for ?"
  2035 	isVar := (self isVariable and:[superclass isVariable not])
  2034         isVar := (self isVariable and:[superclass isVariable not])
  2036     ].
  2035     ].
  2037 
  2036 
  2038     aStream nextPutAll:(self firstDefinitionSelectorPart).
  2037     aStream nextPutAll:(self firstDefinitionSelectorPart).
  2039 
  2038 
  2040     "Created: 11.10.1996 / 18:57:29 / cg"
  2039     "Created: 11.10.1996 / 18:57:29 / cg"
  2056 
  2055 
  2057     "
  2056     "
  2058      this test allows a smalltalk to be built without Projects/ChangeSets
  2057      this test allows a smalltalk to be built without Projects/ChangeSets
  2059     "
  2058     "
  2060     Project notNil ifTrue:[
  2059     Project notNil ifTrue:[
  2061 	dirName := Project currentProjectDirectory
  2060         dirName := Project currentProjectDirectory
  2062     ] ifFalse:[
  2061     ] ifFalse:[
  2063 	dirName := Filename currentDirectory
  2062         dirName := Filename currentDirectory
  2064     ].
  2063     ].
  2065     fileName := (dirName asFilename construct:nm).
  2064     fileName := (dirName asFilename construct:nm).
  2066     fileName makeLegalFilename.
  2065     fileName makeLegalFilename.
  2067 
  2066 
  2068     self fileOutAs:fileName name.
  2067     self fileOutAs:fileName name.
  2353     |comment s|
  2352     |comment s|
  2354 
  2353 
  2355     self printClassNameOn:aStream.
  2354     self printClassNameOn:aStream.
  2356     aStream nextPutAll:' comment:'.
  2355     aStream nextPutAll:' comment:'.
  2357     (comment := self comment) isNil ifTrue:[
  2356     (comment := self comment) isNil ifTrue:[
  2358 	s := ''''''
  2357         s := ''''''
  2359     ] ifFalse:[
  2358     ] ifFalse:[
  2360 	s := comment storeString
  2359         s := comment storeString
  2361     ].
  2360     ].
  2362     aStream nextPutAllAsChunk:s.
  2361     aStream nextPutAllAsChunk:s.
  2363     aStream nextPutChunkSeparator.
  2362     aStream nextPutChunkSeparator.
  2364     aStream cr
  2363     aStream cr
  2365 
  2364 
  2383     |aStream fileName|
  2382     |aStream fileName|
  2384 
  2383 
  2385     fileName := (Smalltalk fileNameForClass:self name), '.st'.
  2384     fileName := (Smalltalk fileNameForClass:self name), '.st'.
  2386     aStream := (aDirectoryName asFilename construct:fileName) writeStream.
  2385     aStream := (aDirectoryName asFilename construct:fileName) writeStream.
  2387     aStream isNil ifTrue:[
  2386     aStream isNil ifTrue:[
  2388 	^ FileOutErrorSignal 
  2387         ^ FileOutErrorSignal 
  2389 		raiseRequestWith:fileName
  2388                 raiseRequestWith:fileName
  2390 		errorString:('cannot create file:', fileName)
  2389                 errorString:('cannot create file:', fileName)
  2391     ].
  2390     ].
  2392     self fileOutOn:aStream.
  2391     self fileOutOn:aStream.
  2393     aStream close
  2392     aStream close
  2394 
  2393 
  2395     "
  2394     "
  2396 	self fileOutIn:'/tmp'
  2395         self fileOutIn:'/tmp'
  2397 	self fileOutIn:'/tmp' asFilename
  2396         self fileOutIn:'/tmp' asFilename
  2398     "
  2397     "
  2399 
  2398 
  2400     "Modified: 19.9.1997 / 00:03:53 / stefan"
  2399     "Modified: 19.9.1997 / 00:03:53 / stefan"
  2401 !
  2400 !
  2402 
  2401 
  2609 
  2608 
  2610     "
  2609     "
  2611      primitive definitions - if any
  2610      primitive definitions - if any
  2612     "
  2611     "
  2613     (s := self primitiveDefinitionsString) notNil ifTrue:[
  2612     (s := self primitiveDefinitionsString) notNil ifTrue:[
  2614 	aStream nextPutChunkSeparator.
  2613         aStream nextPutChunkSeparator.
  2615 	self printClassNameOn:aStream.
  2614         self printClassNameOn:aStream.
  2616 	aStream nextPutAll:' primitiveDefinitions';
  2615         aStream nextPutAll:' primitiveDefinitions';
  2617 		nextPutChunkSeparator;
  2616                 nextPutChunkSeparator;
  2618 		cr.
  2617                 cr.
  2619 	aStream nextPutAll:s.
  2618         aStream nextPutAll:s.
  2620 	aStream nextPutChunkSeparator; space; nextPutChunkSeparator; cr; cr
  2619         aStream nextPutChunkSeparator; space; nextPutChunkSeparator; cr; cr
  2621     ].
  2620     ].
  2622     (s := self primitiveVariablesString) notNil ifTrue:[
  2621     (s := self primitiveVariablesString) notNil ifTrue:[
  2623 	aStream nextPutChunkSeparator.
  2622         aStream nextPutChunkSeparator.
  2624 	self printClassNameOn:aStream.
  2623         self printClassNameOn:aStream.
  2625 	aStream nextPutAll:' primitiveVariables';
  2624         aStream nextPutAll:' primitiveVariables';
  2626 		nextPutChunkSeparator;
  2625                 nextPutChunkSeparator;
  2627 		cr.
  2626                 cr.
  2628 	aStream nextPutAll:s.
  2627         aStream nextPutAll:s.
  2629 	aStream nextPutChunkSeparator; space; nextPutChunkSeparator; cr; cr
  2628         aStream nextPutChunkSeparator; space; nextPutChunkSeparator; cr; cr
  2630     ].
  2629     ].
  2631 
  2630 
  2632     "Modified: 8.1.1997 / 17:45:40 / cg"
  2631     "Modified: 8.1.1997 / 17:45:40 / cg"
  2633 !
  2632 !
  2634 
  2633 
  2643     self fileOutPrimitiveDefinitionsOn:aStream.
  2642     self fileOutPrimitiveDefinitionsOn:aStream.
  2644     "
  2643     "
  2645      primitive functions - if any
  2644      primitive functions - if any
  2646     "
  2645     "
  2647     (s := self primitiveFunctionsString) notNil ifTrue:[
  2646     (s := self primitiveFunctionsString) notNil ifTrue:[
  2648 	aStream nextPutChunkSeparator.
  2647         aStream nextPutChunkSeparator.
  2649 	self printClassNameOn:aStream.
  2648         self printClassNameOn:aStream.
  2650 	aStream nextPutAll:' primitiveFunctions';
  2649         aStream nextPutAll:' primitiveFunctions';
  2651 		nextPutChunkSeparator;
  2650                 nextPutChunkSeparator;
  2652 		cr.
  2651                 cr.
  2653 	aStream nextPutAll:s.
  2652         aStream nextPutAll:s.
  2654 	aStream nextPutChunkSeparator; space; nextPutChunkSeparator; cr; cr
  2653         aStream nextPutChunkSeparator; space; nextPutChunkSeparator; cr; cr
  2655     ].
  2654     ].
  2656 
  2655 
  2657     "Modified: 8.1.1997 / 17:45:51 / cg"
  2656     "Modified: 8.1.1997 / 17:45:51 / cg"
  2658 ! !
  2657 ! !
  2659 
  2658 
  2680 
  2679 
  2681 binaryFileOutOn:aStream sourceMode:sourceMode
  2680 binaryFileOutOn:aStream sourceMode:sourceMode
  2682     "append a binary representation of myself to aStream in
  2681     "append a binary representation of myself to aStream in
  2683      a portable binary format. 
  2682      a portable binary format. 
  2684      The argument controls how sources are to be saved:
  2683      The argument controls how sources are to be saved:
  2685 	#keep - include the source
  2684         #keep - include the source
  2686 	#reference - include a reference to the sourceFile
  2685         #reference - include a reference to the sourceFile
  2687 	#discard - dont save sources.
  2686         #discard - dont save sources.
  2688 
  2687 
  2689      With #reference, the sourceFile needs to be present after reload 
  2688      With #reference, the sourceFile needs to be present after reload 
  2690      in order to be browsable."
  2689      in order to be browsable."
  2691 
  2690 
  2692     |bos|
  2691     |bos|
  3131     aStream spaces:indent; bold; nextPutAll:nm; normal; nextPutAll:' ('.
  3130     aStream spaces:indent; bold; nextPutAll:nm; normal; nextPutAll:' ('.
  3132     self printInstVarNamesOn:aStream indent:(indent + nm size + 2).
  3131     self printInstVarNamesOn:aStream indent:(indent + nm size + 2).
  3133     aStream nextPutLine:')'.
  3132     aStream nextPutLine:')'.
  3134 
  3133 
  3135     (self subclasses sort:[:a :b | a name < b name]) do:[:aSubclass |
  3134     (self subclasses sort:[:a :b | a name < b name]) do:[:aSubclass |
  3136 	aSubclass printFullHierarchyOn:aStream indent:(indent + 2)
  3135         aSubclass printFullHierarchyOn:aStream indent:(indent + 2)
  3137     ]
  3136     ]
  3138 
  3137 
  3139     "|printStream|
  3138     "|printStream|
  3140      printStream := Printer new.
  3139      printStream := Printer new.
  3141      Object printFullHierarchyOn:printStream indent:0.
  3140      Object printFullHierarchyOn:printStream indent:0.
  3150     |comment s|
  3149     |comment s|
  3151 
  3150 
  3152     aPrintStream nextPutAll:'class                '; bold; nextPutLine:self name; normal. 
  3151     aPrintStream nextPutAll:'class                '; bold; nextPutLine:self name; normal. 
  3153     aPrintStream nextPutAll:'superclass           '.
  3152     aPrintStream nextPutAll:'superclass           '.
  3154     superclass isNil ifTrue:[
  3153     superclass isNil ifTrue:[
  3155 	s := 'Object'
  3154         s := 'Object'
  3156     ] ifFalse:[
  3155     ] ifFalse:[
  3157 	s := superclass name
  3156         s := superclass name
  3158     ].
  3157     ].
  3159     aPrintStream nextPutLine:s.
  3158     aPrintStream nextPutLine:s.
  3160 
  3159 
  3161     aPrintStream nextPutAll:'instance Variables   '.
  3160     aPrintStream nextPutAll:'instance Variables   '.
  3162     self printInstVarNamesOn:aPrintStream indent:21.
  3161     self printInstVarNamesOn:aPrintStream indent:21.
  3165     aPrintStream nextPutAll:'class Variables      '.
  3164     aPrintStream nextPutAll:'class Variables      '.
  3166     self printClassVarNamesOn:aPrintStream indent:21.
  3165     self printClassVarNamesOn:aPrintStream indent:21.
  3167     aPrintStream cr.
  3166     aPrintStream cr.
  3168 
  3167 
  3169     category notNil ifTrue:[
  3168     category notNil ifTrue:[
  3170 	aPrintStream nextPutAll:'category             '; 
  3169         aPrintStream nextPutAll:'category             '; 
  3171 		     nextPutLine:(category printString).
  3170                      nextPutLine:(category printString).
  3172     ].
  3171     ].
  3173 
  3172 
  3174     (comment := self comment) notNil ifTrue:[
  3173     (comment := self comment) notNil ifTrue:[
  3175 	aPrintStream cr; nextPutLine:'comment:'; italic; nextPutLine:comment; normal
  3174         aPrintStream cr; nextPutLine:'comment:'; italic; nextPutLine:comment; normal
  3176     ]
  3175     ]
  3177 
  3176 
  3178     "Created: 10.12.1995 / 16:30:47 / cg"
  3177     "Created: 10.12.1995 / 16:30:47 / cg"
  3179     "Modified: 9.11.1996 / 00:13:37 / cg"
  3178     "Modified: 9.11.1996 / 00:13:37 / cg"
  3180     "Modified: 1.4.1997 / 16:01:26 / stefan"
  3179     "Modified: 1.4.1997 / 16:01:26 / stefan"
  3218     aStream nextPutAll:(' category:' , category storeString).
  3217     aStream nextPutAll:(' category:' , category storeString).
  3219     aStream nextPutChunkSeparator.
  3218     aStream nextPutChunkSeparator.
  3220 
  3219 
  3221     "this test allows a smalltalk without Projects/ChangeSets"
  3220     "this test allows a smalltalk without Projects/ChangeSets"
  3222     Project notNil ifTrue:[
  3221     Project notNil ifTrue:[
  3223 	Project addClassDefinitionChangeFor:self
  3222         Project addClassDefinitionChangeFor:self
  3224     ]
  3223     ]
  3225 
  3224 
  3226     "Created: 3.12.1995 / 13:43:33 / cg"
  3225     "Created: 3.12.1995 / 13:43:33 / cg"
  3227     "Modified: 3.12.1995 / 14:10:34 / cg"
  3226     "Modified: 3.12.1995 / 14:10:34 / cg"
  3228 !
  3227 !
  3231     "{ Pragma: +optSpace }"
  3230     "{ Pragma: +optSpace }"
  3232 
  3231 
  3233     "append a class-definition-record to aStream"
  3232     "append a class-definition-record to aStream"
  3234 
  3233 
  3235     aClass isLoaded ifTrue:[
  3234     aClass isLoaded ifTrue:[
  3236 	aClass fileOutDefinitionOn:aStream.
  3235         aClass fileOutDefinitionOn:aStream.
  3237 	aStream nextPutChunkSeparator.
  3236         aStream nextPutChunkSeparator.
  3238 	Project notNil ifTrue:[
  3237         Project notNil ifTrue:[
  3239 	    Project addClassDefinitionChangeFor:aClass 
  3238             Project addClassDefinitionChangeFor:aClass 
  3240 	]
  3239         ]
  3241     ]
  3240     ]
  3242 
  3241 
  3243     "Created: 3.12.1995 / 13:57:44 / cg"
  3242     "Created: 3.12.1995 / 13:57:44 / cg"
  3244     "Modified: 3.12.1995 / 14:11:26 / cg"
  3243     "Modified: 3.12.1995 / 14:11:26 / cg"
  3245 !
  3244 !
  3294     "{ Pragma: +optSpace }"
  3293     "{ Pragma: +optSpace }"
  3295 
  3294 
  3296     "append a primitiveDefinitions-record to aStream"
  3295     "append a primitiveDefinitions-record to aStream"
  3297 
  3296 
  3298     aStream nextPutAll:aClass name; nextPutLine:' primitiveDefinitions:'''; 
  3297     aStream nextPutAll:aClass name; nextPutLine:' primitiveDefinitions:'''; 
  3299 	    nextPutAll:(aClass primitiveDefinitionsString storeString copyFrom:2).
  3298             nextPutAll:(aClass primitiveDefinitionsString storeString copyFrom:2).
  3300     aStream nextPutChunkSeparator.
  3299     aStream nextPutChunkSeparator.
  3301 
  3300 
  3302     "Modified: 9.11.1996 / 00:09:54 / cg"
  3301     "Modified: 9.11.1996 / 00:09:54 / cg"
  3303 !
  3302 !
  3304 
  3303 
  3306     "{ Pragma: +optSpace }"
  3305     "{ Pragma: +optSpace }"
  3307 
  3306 
  3308     "append a primitiveFunctions-record to aStream"
  3307     "append a primitiveFunctions-record to aStream"
  3309 
  3308 
  3310     aStream nextPutAll:aClass name; nextPutLine:' primitiveFunctions:'''; 
  3309     aStream nextPutAll:aClass name; nextPutLine:' primitiveFunctions:'''; 
  3311 	    nextPutAll:(aClass primitiveFunctionsString storeString copyFrom:2).
  3310             nextPutAll:(aClass primitiveFunctionsString storeString copyFrom:2).
  3312     aStream nextPutChunkSeparator.
  3311     aStream nextPutChunkSeparator.
  3313 
  3312 
  3314     "Modified: 9.11.1996 / 00:10:02 / cg"
  3313     "Modified: 9.11.1996 / 00:10:02 / cg"
  3315 !
  3314 !
  3316 
  3315 
  3318     "{ Pragma: +optSpace }"
  3317     "{ Pragma: +optSpace }"
  3319 
  3318 
  3320     "append a primitiveVariables-record to aStream"
  3319     "append a primitiveVariables-record to aStream"
  3321 
  3320 
  3322     aStream nextPutAll:aClass name; nextPutLine:' primitiveVariables:'''; 
  3321     aStream nextPutAll:aClass name; nextPutLine:' primitiveVariables:'''; 
  3323 	    nextPutAll:(aClass primitiveVariablesString storeString copyFrom:2).
  3322             nextPutAll:(aClass primitiveVariablesString storeString copyFrom:2).
  3324     aStream nextPutChunkSeparator.
  3323     aStream nextPutChunkSeparator.
  3325 
  3324 
  3326     "Modified: 9.11.1996 / 00:10:10 / cg"
  3325     "Modified: 9.11.1996 / 00:10:10 / cg"
  3327 ! !
  3326 ! !
  3328 
  3327 
  3343 
  3342 
  3344     "the primitiveSpec is either a string, or an integer specifying the
  3343     "the primitiveSpec is either a string, or an integer specifying the
  3345      position within the classes sourcefile ...
  3344      position within the classes sourcefile ...
  3346     "
  3345     "
  3347     pos isNumber ifTrue:[
  3346     pos isNumber ifTrue:[
  3348 	classFilename notNil ifTrue:[
  3347         classFilename notNil ifTrue:[
  3349 	    stream := self sourceStream. 
  3348             stream := self sourceStream. 
  3350 	    stream notNil ifTrue:[
  3349             stream notNil ifTrue:[
  3351 		stream position:pos+1.
  3350                 stream position:pos+1.
  3352 		string := stream nextChunk.
  3351                 string := stream nextChunk.
  3353 		stream close.
  3352                 stream close.
  3354 		^ string
  3353                 ^ string
  3355 	    ]
  3354             ]
  3356 	].
  3355         ].
  3357 	^ nil
  3356         ^ nil
  3358     ].
  3357     ].
  3359     ^ pos
  3358     ^ pos
  3360 
  3359 
  3361     "Modified: 15.1.1997 / 15:29:30 / stefan"
  3360     "Modified: 15.1.1997 / 15:29:30 / stefan"
  3362 !
  3361 !
  3365     "{ Pragma: +optSpace }"
  3364     "{ Pragma: +optSpace }"
  3366 
  3365 
  3367     "set a primitiveSpecification component to aString"
  3366     "set a primitiveSpecification component to aString"
  3368 
  3367 
  3369     primitiveSpec isNil ifTrue:[
  3368     primitiveSpec isNil ifTrue:[
  3370 	primitiveSpec := Array new:3
  3369         primitiveSpec := Array new:3
  3371     ].
  3370     ].
  3372     primitiveSpec at:index put:aString
  3371     primitiveSpec at:index put:aString
  3373 ! !
  3372 ! !
  3374 
  3373 
  3375 !Class methodsFor:'protocol printOut'!
  3374 !Class methodsFor:'protocol printOut'!
  3493 
  3492 
  3494     |cls|
  3493     |cls|
  3495 
  3494 
  3496     cls := self.
  3495     cls := self.
  3497     [cls notNil] whileTrue:[
  3496     [cls notNil] whileTrue:[
  3498 	(cls classVarNames includes:aVariableName) ifTrue:[ ^ cls].
  3497         (cls classVarNames includes:aVariableName) ifTrue:[ ^ cls].
  3499 	cls := cls superclass
  3498         cls := cls superclass
  3500     ].
  3499     ].
  3501     ^ nil
  3500     ^ nil
  3502 
  3501 
  3503     "
  3502     "
  3504      StandardSystemView whichClassDefinesClassVar:'ErrorSignal'
  3503      StandardSystemView whichClassDefinesClassVar:'ErrorSignal'
  3701     value := (value bitShift:3) + ((self class instSize - Class instSize) bitAnd:7).
  3700     value := (value bitShift:3) + ((self class instSize - Class instSize) bitAnd:7).
  3702     value := (value bitShift:7) + (self instSize bitAnd:16r7F).
  3701     value := (value bitShift:7) + (self instSize bitAnd:16r7F).
  3703 
  3702 
  3704     nameKey := 0.
  3703     nameKey := 0.
  3705     self allInstVarNames do:[:name |
  3704     self allInstVarNames do:[:name |
  3706 	nameKey := nameKey bitShift:1.
  3705         nameKey := nameKey bitShift:1.
  3707 	(nameKey bitAnd:16r10000) ~~ 0 ifTrue:[
  3706         (nameKey bitAnd:16r10000) ~~ 0 ifTrue:[
  3708 	    nameKey := nameKey bitXor:1.
  3707             nameKey := nameKey bitXor:1.
  3709 	    nameKey := nameKey bitAnd:16rFFFF.
  3708             nameKey := nameKey bitAnd:16rFFFF.
  3710 	].
  3709         ].
  3711 	nameKey := (nameKey + (name at:1) asciiValue) bitAnd:16rFFFF.
  3710         nameKey := (nameKey + (name at:1) asciiValue) bitAnd:16rFFFF.
  3712     ].
  3711     ].
  3713     value := value + (nameKey bitShift:14).
  3712     value := value + (nameKey bitShift:14).
  3714     signature := value.
  3713     signature := value.
  3715     ^ value
  3714     ^ value
  3716 
  3715 
  3733 
  3732 
  3734     |owner info c|
  3733     |owner info c|
  3735 
  3734 
  3736     (owner := self owningClass) notNil ifTrue:[^ owner binaryRevision].
  3735     (owner := self owningClass) notNil ifTrue:[^ owner binaryRevision].
  3737     revision notNil ifTrue:[
  3736     revision notNil ifTrue:[
  3738 	c := revision first.
  3737         c := revision first.
  3739 	c == $$ ifTrue:[
  3738         c == $$ ifTrue:[
  3740 	    info := Class revisionInfoFromString:revision.
  3739             info := Class revisionInfoFromString:revision.
  3741 	    info isNil ifTrue:[^ '0'].
  3740             info isNil ifTrue:[^ '0'].
  3742 	    ^ info at:#revision ifAbsent:'0'.
  3741             ^ info at:#revision ifAbsent:'0'.
  3743 	].
  3742         ].
  3744 	c isDigit ifFalse:[
  3743         c isDigit ifFalse:[
  3745 	    ^ '0'
  3744             ^ '0'
  3746 	].
  3745         ].
  3747     ].
  3746     ].
  3748 
  3747 
  3749     ^ revision
  3748     ^ revision
  3750 
  3749 
  3751     "
  3750     "
  3757      to find all classes which are not up-to-date:
  3756      to find all classes which are not up-to-date:
  3758 
  3757 
  3759      |classes|
  3758      |classes|
  3760 
  3759 
  3761      classes := Smalltalk allClasses 
  3760      classes := Smalltalk allClasses 
  3762 		    select:[:cls | cls binaryRevision notNil and:[cls binaryRevision ~= cls revision]].
  3761                     select:[:cls | cls binaryRevision notNil and:[cls binaryRevision ~= cls revision]].
  3763      SystemBrowser browseClasses:classes title:'classes which are not up-to-date'
  3762      SystemBrowser browseClasses:classes title:'classes which are not up-to-date'
  3764     "
  3763     "
  3765 
  3764 
  3766     "Created: 7.12.1995 / 10:58:47 / cg"
  3765     "Created: 7.12.1995 / 10:58:47 / cg"
  3767     "Modified: 1.4.1997 / 23:33:01 / stefan"
  3766     "Modified: 1.4.1997 / 23:33:01 / stefan"
  4071 
  4070 
  4072     |info|
  4071     |info|
  4073 
  4072 
  4074     info := self revisionInfo.
  4073     info := self revisionInfo.
  4075     info notNil ifTrue:[
  4074     info notNil ifTrue:[
  4076 	^ info at:#revision ifAbsent:nil
  4075         ^ info at:#revision ifAbsent:nil
  4077     ].
  4076     ].
  4078     ^ self binaryRevision
  4077     ^ self binaryRevision
  4079 
  4078 
  4080     "
  4079     "
  4081      Object revision 
  4080      Object revision 
  4092 
  4091 
  4093     |info|
  4092     |info|
  4094 
  4093 
  4095     info := self revisionInfo.
  4094     info := self revisionInfo.
  4096     info notNil ifTrue:[
  4095     info notNil ifTrue:[
  4097 	^ info at:#date ifAbsent:'??/??/??'
  4096         ^ info at:#date ifAbsent:'??/??/??'
  4098     ].
  4097     ].
  4099     ^ '??/??/??'
  4098     ^ '??/??/??'
  4100 
  4099 
  4101     "
  4100     "
  4102      Object revisionDateString 
  4101      Object revisionDateString 
  4107 
  4106 
  4108 revisionInfo
  4107 revisionInfo
  4109     "return a dictionary filled with revision info.
  4108     "return a dictionary filled with revision info.
  4110      This extracts the relevant info from the revisionString.
  4109      This extracts the relevant info from the revisionString.
  4111      The revisionInfo contains all or a subset of:
  4110      The revisionInfo contains all or a subset of:
  4112 	#binaryRevision - the revision upon which the binary of this class is based
  4111         #binaryRevision - the revision upon which the binary of this class is based
  4113 	#revision       - the revision upon which the class is based logically
  4112         #revision       - the revision upon which the class is based logically
  4114 			  (different, if a changed class was checked in, but not yet recompiled)
  4113                           (different, if a changed class was checked in, but not yet recompiled)
  4115 	#user           - the user who checked in the logical revision
  4114         #user           - the user who checked in the logical revision
  4116 	#date           - the date when the logical revision was checked in
  4115         #date           - the date when the logical revision was checked in
  4117 	#time           - the time when the logical revision was checked in
  4116         #time           - the time when the logical revision was checked in
  4118 	#fileName       - the classes source file name
  4117         #fileName       - the classes source file name
  4119 	#repositoryPath - the classes source container
  4118         #repositoryPath - the classes source container
  4120     "
  4119     "
  4121 
  4120 
  4122     |vsnString info mgr|
  4121     |vsnString info mgr|
  4123 
  4122 
  4124     vsnString := self revisionString.
  4123     vsnString := self revisionString.
  4125     vsnString notNil ifTrue:[
  4124     vsnString notNil ifTrue:[
  4126 	mgr := self sourceCodeManager.
  4125         mgr := self sourceCodeManager.
  4127 	mgr notNil ifTrue:[
  4126         mgr notNil ifTrue:[
  4128 	    info := mgr revisionInfoFromString:vsnString
  4127             info := mgr revisionInfoFromString:vsnString
  4129 	] ifFalse:[
  4128         ] ifFalse:[
  4130 	    info := Class revisionInfoFromString:vsnString.
  4129             info := Class revisionInfoFromString:vsnString.
  4131 	].
  4130         ].
  4132 	info notNil ifTrue:[
  4131         info notNil ifTrue:[
  4133 	    info at:#binaryRevision put:self binaryRevision.
  4132             info at:#binaryRevision put:self binaryRevision.
  4134 	]
  4133         ]
  4135     ].
  4134     ].
  4136     ^ info
  4135     ^ info
  4137 
  4136 
  4138     "
  4137     "
  4139      Object revisionString 
  4138      Object revisionString 
  4160     (owner := self owningClass) notNil ifTrue:[^ owner revisionString].
  4159     (owner := self owningClass) notNil ifTrue:[^ owner revisionString].
  4161 
  4160 
  4162     thisContext isRecursive ifTrue:[^ nil ].
  4161     thisContext isRecursive ifTrue:[^ nil ].
  4163 
  4162 
  4164     self isMeta ifTrue:[
  4163     self isMeta ifTrue:[
  4165 	meta := self. cls := self soleInstance
  4164         meta := self. cls := self soleInstance
  4166     ] ifFalse:[
  4165     ] ifFalse:[
  4167 	cls := self. meta := self class
  4166         cls := self. meta := self class
  4168     ].
  4167     ].
  4169 
  4168 
  4170     m := meta compiledMethodAt:#version.
  4169     m := meta compiledMethodAt:#version.
  4171     m isNil ifTrue:[
  4170     m isNil ifTrue:[
  4172 	m := cls compiledMethodAt:#version.
  4171         "/ no - do NEVER care for a version method on the instance side
  4173 	m isNil ifTrue:[^ nil].
  4172         "/ m := cls compiledMethodAt:#version.
       
  4173         m isNil ifTrue:[^ nil].
  4174     ].
  4174     ].
  4175 
  4175 
  4176     m isExecutable ifTrue:[
  4176     m isExecutable ifTrue:[
  4177 	"/
  4177         "/
  4178 	"/ if its a method returning the string,
  4178         "/ if its a method returning the string,
  4179 	"/ thats the returned value
  4179         "/ thats the returned value
  4180 	"/
  4180         "/
  4181 	val := cls version.
  4181         val := cls version.
  4182 	val isString ifTrue:[^ val].
  4182         val isString ifTrue:[^ val].
  4183     ].
  4183     ].
  4184 
  4184 
  4185     "/
  4185     "/
  4186     "/ if its a method consisting of a comment only
  4186     "/ if its a method consisting of a comment only
  4187     "/ extract it - this may lead to a recursive call
  4187     "/ extract it - this may lead to a recursive call
  4193     src isNil ifTrue:[^ nil].
  4193     src isNil ifTrue:[^ nil].
  4194     ^ Class revisionStringFromSource:src 
  4194     ^ Class revisionStringFromSource:src 
  4195 
  4195 
  4196     "
  4196     "
  4197      Smalltalk allClassesDo:[:cls |
  4197      Smalltalk allClassesDo:[:cls |
  4198 	Transcript showCR:cls revisionString
  4198         Transcript showCR:cls revisionString
  4199      ].
  4199      ].
  4200 
  4200 
  4201      Number revisionString  
  4201      Number revisionString  
  4202      FileDirectory revisionString
  4202      FileDirectory revisionString
  4203      Metaclass revisionString
  4203      Metaclass revisionString
  4204     "
  4204     "
  4205 
  4205 
  4206     "Created: 29.10.1995 / 19:28:03 / cg"
  4206     "Created: / 29.10.1995 / 19:28:03 / cg"
  4207     "Modified: 23.10.1996 / 18:23:56 / cg"
  4207     "Modified: / 23.10.1996 / 18:23:56 / cg"
  4208     "Modified: 1.4.1997 / 23:37:25 / stefan"
  4208     "Modified: / 1.4.1997 / 23:37:25 / stefan"
       
  4209     "Modified: / 7.2.2001 / 18:03:39 / ps"
  4209 !
  4210 !
  4210 
  4211 
  4211 setBinaryRevision:aString
  4212 setBinaryRevision:aString
  4212     "set the revision-ID.
  4213     "set the revision-ID.
  4213      This should normally not be done in the running system, as the source-manager
  4214      This should normally not be done in the running system, as the source-manager
  4286     |owner source|
  4287     |owner source|
  4287 
  4288 
  4288     (owner := self owningClass) notNil ifTrue:[^ owner sourceStream].
  4289     (owner := self owningClass) notNil ifTrue:[^ owner sourceStream].
  4289 
  4290 
  4290     classFilename notNil ifTrue:[
  4291     classFilename notNil ifTrue:[
  4291 	source := classFilename
  4292         source := classFilename
  4292     ] ifFalse:[
  4293     ] ifFalse:[
  4293 	source := (Smalltalk fileNameForClass:self) , '.st'
  4294         source := (Smalltalk fileNameForClass:self) , '.st'
  4294     ].
  4295     ].
  4295     ^ self sourceStreamFor:source
  4296     ^ self sourceStreamFor:source
  4296 
  4297 
  4297     "Modified: 15.10.1996 / 18:59:40 / cg"
  4298     "Modified: 15.10.1996 / 18:59:40 / cg"
  4298     "Modified: 1.4.1997 / 14:33:12 / stefan"
  4299     "Modified: 1.4.1997 / 14:33:12 / stefan"
  4583 ! !
  4584 ! !
  4584 
  4585 
  4585 !Class class methodsFor:'documentation'!
  4586 !Class class methodsFor:'documentation'!
  4586 
  4587 
  4587 version
  4588 version
  4588     ^ '$Header: /cvs/stx/stx/libbasic/Class.st,v 1.393 2001-02-06 14:54:13 cg Exp $'
  4589     ^ '$Header: /cvs/stx/stx/libbasic/Class.st,v 1.394 2001-02-07 17:23:29 ps Exp $'
  4589 ! !
  4590 ! !