!=========================================================================
! Copyright (C) VMware, Inc. 1986-2011.  All Rights Reserved.
!
! $Id: obssymboldict.gs,v 1.7 2008-01-09 22:50:13 stever Exp $
!
! Superclass Hierarchy:
!   ObsoleteSymbolDictionary, ObsoleteDictionary, IdentitySet, 
!   IdentityBag, UnorderedCollection, Collection, Object.
!
!=========================================================================

removeallmethods ObsoleteSymbolDictionary
removeallclassmethods ObsoleteSymbolDictionary

category: 'For Documentation Installation only'
classmethod: ObsoleteSymbolDictionary
installDocumentation

| doc txt |

doc := GsClassDocumentation _newForObsoleteGsClass: self asOfGsVersion: '5.0'.

txt := (GsDocText new) details:
'Existing instances should be migrated to SymbolDictionary or otherwise
 processed as required, and then should be removed.' .
doc documentClassWith: txt.

self description: doc.
%

category: 'Accessing'
method: ObsoleteSymbolDictionary
at: aKey ifAbsent: aBlock

"Returns the value of the Association with key aKey.  If no such 
 Association exists, returns the result of evaluating the zero-argument
 block aBlock."

| assoc |
assoc := self associationAt: aKey otherwise: nil .
assoc == nil ifTrue:[ 
  aBlock == nil ifTrue:[ ^ nil ].
  ^ aBlock value
  ].
^ assoc value
%

category: 'Accessing'
method: ObsoleteSymbolDictionary
at: aKey

"Returns the value of the SymbolAssociation with key aKey.  Generates an error
 if no such SymbolAssociation exists."

| anAssoc |
anAssoc := self associationAt: aKey
                ifAbsent: nil "avoid creating a ComplexBlock" .
anAssoc == nil ifTrue:[ anAssoc := self _errorKeyNotFound: aKey ].
^ anAssoc value
%

category: 'Accessing'
method: ObsoleteSymbolDictionary
associationAt: aKey ifAbsent: aBlock

"Returns the SymbolAssociation with key aKey.  If no such SymbolAssociation
 exists, returns the result of evaluating the zero-argument block aBlock."

<primitive: 48>
| aSym |
aKey _isSymbol ifFalse:[
  aSym := Symbol _existingWithAll: aKey .
  aSym ~~ nil ifTrue:[ 
    ^ self associationAt: aSym ifAbsent: aBlock .
    ].
  ].
aBlock == nil ifTrue:[ ^ nil ] .
^ aBlock value
%

category: 'Accessing'
method: ObsoleteSymbolDictionary
name

"Returns the key of an Association whose value is the receiver.  If the
 receiver contains no such Association, returns nil."

^ (self detectAssociations:{:i| i.value == self } ifNone:[^ nil ] ) key .
%

category: 'Updating'
method: ObsoleteSymbolDictionary
at: aKey put: aValue

"Creates a new SymbolAssociation with the given key and
 value and adds it to the receiver.  If the receiver already contains an
 Association with the given key, this makes aValue the value of that
 Association.  Returns aValue."

<primitive: 304>
aKey _isSymbol ifFalse:[
  ^ self at: (aKey asSymbol) put: aValue
  ].
^ self _primitiveFailed: #at:put:
%

category: 'Searching'
method: ObsoleteSymbolDictionary
includesKey: aKey

"Returns true if the receiver contains a SymbolAssociation whose key is equal
 to aKey.  Returns false otherwise."

self at: aKey ifAbsent:[ ^ false ].
^ true
%

! at: aKey otherwise: aValue   - inherited

category: 'Accessing'
method: ObsoleteSymbolDictionary
keys

"Reimplemented.  Returns a SymbolSet containing the receiver's keys."

| result |
result := SymbolSet new.
1 to: self size do:
  [ :i | result _addSymbol: (self _at: i) key ].
^result
%

category: 'Accessing'
method: ObsoleteSymbolDictionary
_behaviorKeys

"Returns a SymbolSet containing keys in the receiver whose values are
 Behaviors."

"This is used as an optimization by the GemBuilder for Smalltalk browser."

| result |
result := SymbolSet new.
1 to: self size do:
  [ :i |
    (self _at: i) value isBehavior
      ifTrue: [ result _addSymbol: (self _at: i) key ].
  ].
^result
%

category: 'Browser Methods'
method: ObsoleteSymbolDictionary
_classAndVersionStrings

"For all Behaviors in the receiver, returns an OrderedCollection of Strings
 showing the class name and version.  This method is used as an optimization by
 the GemBuilder for Smalltalk browser."

| result |
result := OrderedCollection new .
self do: [ :anAssoc | | each |
  each := anAssoc value.
  each isBehavior
  ifTrue: [ result add: 
              ( each classHistory size = 1
                 ifTrue: [ each name asString ]
                 ifFalse: [ each name + ' [ ' +  
                      ( each classHistory indexOf: each ) printString + ' ]' ]
               )
    ] 
  ].
^result
%
category: 'Adding'
method: ObsoleteSymbolDictionary
addAll: aCollection

"Adds all of the elements of aCollection to the receiver and returns the
 receiver.  If aCollection is a kind of KeyValueDictionary, then adds new
 Associations that reference the key/value pairs found in aCollection."

(self == aCollection) ifTrue: [ ^ self addAll: (aCollection copy) ].
aCollection do: [:each | self add: each ].
^ self
%

category: 'Repository Conversion'
method: ObsoleteSymbolDictionary
convertTo5

"Returns an instance of SymbolDictionary containing the converted contents
 of the receiver."

<primitive: 901> "enter protected mode"
| newSymDict tempArray |

(self _class == ObsoleteSymbolDictionary) ifFalse: [ 
  System _disableProtectedMode.
  ^ self 
].
"User defined subclasses cannot be converted here."

newSymDict := SymbolDictionary new.
tempArray := Array new.

self doAssociations: [ :anObsSymAssoc |
  tempArray add: (anObsSymAssoc convertTo5)
  ].

newSymDict assignToSegment: self segment .
self _primitiveBecome: newSymDict .

tempArray do: [ :anAssoc |
  self addAssociation: anAssoc
  ].

System _disableProtectedMode.
^ self
%

category: 'Repository Conversion'
method: ObsoleteSymbolDictionary
asGsMethodDictionary

"Convert an instance of ObsoleteSymbolDictionary to an instance of
 GsMethodDictionary."

| newGsDict |

newGsDict := GsMethodDictionary new.
self keysAndValuesDo: [ :aKey :aValue |
  newGsDict at: (aKey convertTo5) put: aValue.
  ].
newGsDict assignToSegment: self segment .
^ newGsDict.
%

category: 'Repository Conversion'
method: ObsoleteSymbolDictionary
convertToCategories

"Convert an instance of ObsoleteSymbolDictionary to an instance of
 GsMethodDictionary."

| newGsDict |

newGsDict := GsMethodDictionary new.
self keysAndValuesDo: [ :aKey :aValue |
  newGsDict at: (aKey asSymbol) put: (aValue convertToSymbolSet).
  ].
newGsDict assignToSegment: self segment .
^ newGsDict.
%

category: 'Storing and Loading'
classmethod: ObsoleteSymbolDictionary
loadFrom: passiveObj

"Reads from passiveObj the passive form of an object with named instance
 variable format.  Converts the object to its active form by loading the
 information into a new instance of the receiver.  Returns the new instance."

^ self loadFrom: passiveObj mappingToClass: SymbolDictionary
%

category: 'Repository Conversion'
method: ObsoleteSymbolDictionary
rehashForConversion

"Private. Converts the receiver to an instance of Dictionary. Only done if
 the receiver is an instance of ObsoleteDictionary. Instances of subclasses
 of ObsoleteDictionary are not converted. Returns the receiver."

<primitive: 901> "enter protected mode"
| newDict anArray onlySymbols |

self _class == ObsoleteSymbolDictionary ifFalse: [ 
  System _disableProtectedMode.
  ^ self 
].

anArray := Array new.
onlySymbols := true.
self doAssociations: [ :anAssoc |
  (anAssoc _class == SymbolAssociation) ifFalse: [ onlySymbols := false ].
  anArray add: anAssoc.
  ].

(onlySymbols)
  ifTrue: [ newDict := SymbolDictionary new: (self size) ]
  ifFalse: [ newDict := Dictionary new: (self size) ].

newDict assignToSegment: self segment.
newDict _primitiveBecome: self.

anArray do: [ :anAssoc | self add: anAssoc.  ].

System _disableProtectedMode.
^ self.
%

category: 'Repository Conversion'
classmethod: ObsoleteSymbolDictionary
_correspondingNewClass

"The class all instances of receiver are converted to during conversion."

(self == ObsoleteSymbolDictionary)
  ifTrue: [ ^ SymbolDictionary ].

^ self.
%

