"Create a foreign environment importing all from Smalltalk globals"
foreign := Environment withName: #Foreign.
foreign exportSelf.
foreign import: Smalltalk globals.
"Bind a new global"
fooKey := #ClassVarScopeFoo.
fooValue := Smalltalk globals at: fooKey put: Object basicNew.
fooBinding := Smalltalk globals bindingOf: fooKey.
self assert: (foreign bindingOf: fooKey) == fooBinding.
"Unbind the global: it is moved to, and shared by both undeclared"
Smalltalk globals removeKey: fooKey.
self assert: (Smalltalk globals undeclared associationAt: fooKey) ==
fooBinding.
self assert: (foreign undeclared associationAt: fooKey) == fooBinding.
"Create a class var: the undeclared binding is moved to classPool.
This is questionable, it was a global with potentially larger/different
scope."
parent := Object
subclass: #ClassVarScopeParent
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Dummy-Tests-Class'.
child := parent
subclass: #ClassVarScopeChild
instanceVariableNames: ''
classVariableNames: 'ClassVarScopeFoo'
poolDictionaries: ''
category: 'Dummy-Tests-Class'.
self assert: (child classPool associationAt: fooKey) == fooBinding.
"The global is no more in Smalltalk globals undeclared"
self assert: (Smalltalk globals undeclared includesKey: fooKey) not.
"But it is still in foreign undeclared"
self assert: (foreign undeclared associationAt: fooKey) == fooBinding.
"Rebind a new global"
fooValue := Smalltalk globals at: fooKey put: Object basicNew.
globalFooBinding := Smalltalk globals bindingOf: fooKey.
"The binding has been removed from foreign undeclared"
self assert: (foreign undeclared includesKey: fooKey) not.
self assert: (foreign bindingOf: fooKey) == globalFooBinding.
"But because #showBinding: did use a becomeForward: the class pool and
global bindings are now surprisingly fused.
That explains that a foreign environment importing Smalltalk globals is
enough to make ClassVarScopeTest fail"
self assert: globalFooBinding == fooBinding.
self assert: (child classPool associationAt: fooKey) ==
globalFooBinding.
"save our souls"
classes := { child. parent }.
child := parent := nil.
classes do: [ :each |
each
removeFromChanges;
removeFromSystemUnlogged ].
classes := nil.
Smalltalk globals removeKey: fooKey.
foreign destroy.